Frage: Wie starte ich ein Programm und stelle dabei sicher, dass der Netzwerkzugriff über eine bestimmte Netzwerkschnittstelle erfolgt?
Fall: Ich möchte auf zwei verschiedene Computer mit derselben IP-Adresse (192.168.1.1) zugreifen, die jedoch über zwei verschiedene Netzwerkschnittstellen (eth1 und eth2) erreichbar sind.
Beispiel:
net-bind -D eth1 -exec {Program 192.168.1.1}
net-bind -D eth2 -exec {Program 192.168.1.1}
Das Obige ist eine Annäherung an das, was ich gerne hätte, inspiriert von der Hardware-Bindung, die über primusrun und optirun durchgeführt wurde .
Herausforderung: Wie in einem verwandten Thread vorgeschlagen , werden die verwendeten Schnittstellen nicht vom Programm, sondern vom Kernel ausgewählt (daher die Präbindungssyntax im obigen Beispiel).
Ich habe einige verwandte Lösungen gefunden, die unbefriedigend sind. Sie basieren auf der Bindung von Netzwerkschnittstellen über benutzerspezifisches Netzwerk-Blacklisting. dh Ausführen des Prozesses als Benutzer, der nur auf eine bestimmte Netzwerkschnittstelle zugreifen kann.
quelle
Antworten:
Für Linux wurde dies bereits unter Superuser beantwortet - Wie werden verschiedene Netzwerkschnittstellen für verschiedene Prozesse verwendet? .
In der gängigsten Antwort wird ein
LD_PRELOAD
Trick verwendet, um die Netzwerkbindung für ein Programm zu ändern. Moderne Kernel unterstützen jedoch eine wesentlich flexiblere Funktion namens "Netzwerknamespaces", die über dasip
Programm verfügbar gemacht werden. Diese Antwort zeigt, wie man das benutzt. Aus meinen eigenen Experimenten habe ich folgendes gemacht (als root):Es ist auch möglich, Netzwerk-Namespaces in gewissem Umfang mit den Befehlen
unshare
und zu verwaltennsenter
. Auf diese Weise können Sie auch separate Bereiche für PIDs, Benutzer und Einhängepunkte erstellen. Weitere Informationen finden Sie unter:quelle
wvdial
zum Beispiel scheint es überhaupt nicht einzurichten ... also muss es im Namespace selbst definiert werdenip netns remove test_ns
wieder normal werden? Oder müssen Sie etwas Besonderes tun?Ich akzeptiere Graemes Antwort. Dies ist nur eine Nachverfolgung, um die Änderungen zu erklären, die ich an seinem Vorschlag zur Lösung meines Problems vorgenommen habe.
Anstatt die physische Schnittstelle im Namespace zu binden, habe ich ein virtuelles Netzwerkschnittstellenpaar mit einem Ende im Netzwerknamespace und einem Ende im Stamm erstellt. Pakete werden dann über dieses virtuelle Netzwerk vom Namespace zum Root-Namespace und dann zur physischen Schnittstelle weitergeleitet. - Als solche kann ich alle meine gewöhnlichen Datenübertragungen ausführen und außerdem Prozesse starten, die nur auf eine bestimmte Schnittstelle zugreifen können.
Nachdem die Schnittstellen für eth0 und eth1 mit ihren jeweiligen Namespaces eth0_ns und eth1_ns eingerichtet wurden, können Programme auf der angegebenen Schnittstelle über ausgeführt werden.
quelle
dhclient <bridge>
per here ausgab .Lösung I: Vorabladen einer bestimmten Bibliothek
App-Route-Jail : Verwenden Sie ld_preload, um die Verwendung des Schnittstellen-Gateways zu erzwingen (gute Idee, aber Root- oder Markierungsfähigkeiten erforderlich)
Proxybound : Verwenden Sie ld_preload, um einen Proxy für eine bestimmte Anwendung zu erzwingen (dies verwendet einen Proxy anstelle einer Schnittstelle).
Force-Bind : viele Funktionen, aber das Binden leckt (nicht zuverlässig)
Bind-Interface-IP : zu einfache und undichte Verbindungen (nicht zuverlässig)
Bind-IP : viel zu einfache und undichte Verbindungen (nicht zuverlässig)
Lösung II: Linux Userspace
Klassischer Linux-User-Space IP-Netns : Tolle Lösung, aber Root und Interface müssen vorhanden sein
Firejail : Firejail kann eine Anwendung zur Verwendung eines bestimmten Netzwerks zwingen, die Kompatibilität ist jedoch begrenzt (z. B. nicht kompatibel mit Tun-Schnittstellen). firejail benötigt kein root
firejail --dns=8.8.8.8 --noprofile --net=eth0 --ip=192.168.1.1 app-command
Firejail mit netns : Firejail kann eine Anwendung zwingen, einen bestimmten Benutzerbereich zu verwenden, der separat erstellt wurde. Auf diese Weise können Sie Bereiche ohne root benennen
firejail --dns=8.8.8.8 --noprofile --netns=nameOfyourNS app-command
Firejail mit Maskerade und Brücke : Firejail eine Anwendung zwingen kann , eine verwenden spezifische Schnittstelle mit iptables Maskerade , ist dieser große und erfordert keine root aber dies erfordert ip_forward und Auswirkungen Sicherheit bedeuten könnte
firejail --net=br0 firefox
Lösung III: Linux Iptables
Iptables können für diesen Zweck verwendet werden , erfordern jedoch ip_forward und können Auswirkungen auf die Sicherheit haben, wenn sie nicht richtig konfiguriert sind ( Beispiel 1 , Beispiel 2 , Beispiel 3 , Beispiel 4)
Lösungshinweise (I, II & III):
Wireguard
Wenn Sie ein VPN (insbesondere Wireguard) verwenden und diese Lösung auf eine Wireguard-Schnittstelle ( Wireguard mit Benutzerbereich ) anwenden möchten, können Sie den verknüpften Anweisungen folgen, um einen Benutzerbereich mit einer WG-Schnittstelle (und damit auf eine VPN-Schnittstelle beschränkt) zu erstellen ) kann auch mit kombiniert
firejail --netns=container
werden, um den Benutzerraum ohne root nutzen zu können.So finden Sie das Schnittstellen-Gateway
Es gibt viele Lösungen, um das Gateway zu finden. Hier sind einige Befehle, die es erlauben, das verwendete Gateway zu finden
Wie benutzt man App-Route-Jail?
192.168.1.1
als erzwungenes Gateway verwendet. Diese Routenregel wirkt sich nicht auf andere Anwendungen aus. Diese Manipulation muss beispielsweise nur einmal beim Systemstart durchgeführt werden, wenn Sie dies möchten Verwenden Sie diese Lösung täglichquelle