it-swarm.com.de

Binden Sie das Unix-Programm an eine bestimmte Netzwerkschnittstelle

Frage: Wie starte ich ein Programm und stelle gleichzeitig sicher, dass sein Netzwerkzugriff über eine bestimmte Netzwerkschnittstelle gebunden ist?

Fall: Ich möchte auf zwei verschiedene Computer mit derselben IP (192.168.1.1) zugreifen, die jedoch über zwei verschiedene Netzwerkschnittstellen (eth1 und eth2) zugänglich 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 möchte, inspiriert von der Hardwarebindung, die über primusrun und optirun erfolgt.

Herausforderung: Wie in einem verwandten Thread vorgeschlagen, werden die verwendeten Schnittstellen nicht vom Programm, sondern vom Kernel ausgewählt ( Daher die Vorbindungssyntax im obigen Beispiel.

Ich habe einige verwandte Lösungen gefunden, die unbefriedigend sind. Sie basieren auf der Bindung von Netzwerkschnittstellen über benutzerspezifische Netzwerk-Blacklisting. Ausführen des Prozesses als Benutzer, der nur auf eine einzelne spezifische Netzwerkschnittstelle zugreifen kann.

42
Skeen

Für Linux wurde dies bereits im Superuser beantwortet - Wie werden unterschiedliche Netzwerkschnittstellen für unterschiedliche Prozesse verwendet? .

Die beliebteste Antwort verwendet ein LD_PRELOAD Trick, um die Netzwerkbindung für ein Programm zu ändern, aber moderne Kernel unterstützen eine viel flexiblere Funktion namens 'Netzwerk-Namespaces', die über das Programm ip verfügbar gemacht wird. Diese Antwort zeigt, wie man das benutzt. Aus meinen eigenen Experimenten habe ich Folgendes gemacht (als Wurzel):

# Add a new namespace called test_ns
ip netns add test_ns

# Set test to use eth0, after this point eth0 is not usable by programs
# outside the namespace
ip link set eth0 netns test_ns

# Bring up eth0 inside test_ns
ip netns exec test_ns ip link set eth0 up

# Use dhcp to get an ipv4 address for eth0
ip netns exec test_ns dhclient eth0

# Ping google from inside the namespace
ip netns exec test_ns ping www.google.co.uk

Es ist auch möglich, Netzwerk-Namespaces in gewissem Umfang mit den Befehlen unshare und nsenter zu verwalten. Auf diese Weise können Sie auch separate Bereiche für PIDs, Benutzer und Einhängepunkte erstellen. Weitere Informationen finden Sie unter:

38
Graeme

Ich akzeptiere Graemes Antwort. Dies ist lediglich eine Folge, um die Änderungen zu erklären, die ich an seinem Vorschlag zur Lösung meines Problems vorgenommen habe.

Anstatt die physische Schnittstelle innerhalb des Namespace zu binden, habe ich ein virtuelles Netzwerkschnittstellenpaar mit einem Ende im Netzwerk-Namespace und einem Ende im Stammverzeichnis erstellt. Pakete werden dann über dieses virtuelle Netzwerk vom Namespace zum Root-Namespace und dann zur physischen Schnittstelle weitergeleitet. - Als solches kann ich alle meine normalen Datenübertragungen ausführen und außerdem Prozesse starten, die nur auf eine bestimmte Schnittstelle zugreifen können.

# Create the eth0 network namespace
ip netns add eth0_ns

# Create the virtual network pair
ip link add v_eth0a type veth peer name v_eth0b

# Move v_eth0a to the eth0_ns namespace, the virtual pair is now split
# between two network namespaces.
ip link set v_eth0a netns eth0_ns

# Configure the ends of the virtual network pairs
ip netns exec eth0_ns ifconfig v_eth0a up {{NAMESPACE_IP}} netmask {{NAMESPACE_NETMASK}}
ifconfig v_eth0b up {{ROOT_NS_IP}} netmask {{ROOT_NS_NETMASK}}

# Setup routing from namespace to root
ip netns exec eth0_ns route add default gw {{ROOT_NS_IP}} dev v_eth0a

# Setup IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s {{ROUTE_SOURCE}}/24 -o {{NETWORK_INTERFACE}} -j SNAT --to-source {{ROUTE_TARGET}}

Sobald 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.

ip netns exec eth0_ns fish
ip netns exec eth1_ns fish
18
Skeen

Lösung I: Vorladen einer bestimmten Bibliothek

  • App-Route-Jail: Verwenden Sie ld_preload, um das Schnittstellen-Gateway zu erzwingen (großartige Idee, aber Root- oder Markierungsfunktionen erforderlich). Die Verwendung ist in den nachstehenden Anmerkungen aufgeführt

  • Proxybound: Verwenden Sie ld_preload, um einen Proxy für eine bestimmte Anwendung zu erzwingen (dies verwendet Proxy anstelle von Schnittstelle).

  • Force-Bind: Viele Funktionen haben, aber die Bindung 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-Benutzerbereich

  • Klassischer Linux-Benutzerbereich ip-netns : Tolle Lösung, aber Root und Schnittstelle können nur auf einem einzigen Benutzerbereich vorhanden sein

  • Firejail : Firejail kann eine Anwendung zwingen, ein bestimmtes Netzwerk zu verwenden, aber die Kompatibilität ist eingeschränkt (Beispiel: Es ist nicht mit Tun-Schnittstellen kompatibel). firejail benötigt kein root firejail --dns=8.8.8.8 --noprofile --net=eth0 --ip=192.168.1.1 app-command

  • Firejail with netns : Firejail kann eine Anwendung zwingen, einen bestimmten Benutzerbereich zu verwenden, der separat erstellt wurde. Dadurch können wir Bereiche ohne root benennen firejail --dns=8.8.8.8 --noprofile --netns=nameOfyourNS app-command

  • Firejail mit Maskerade und Brücke : Firejail kann eine Anwendung zwingen, eine spezifische Schnittstelle mit iptables masquerade zu verwenden , dies ist großartig und erfordert kein root aber dies erfordert ip_forward und könnte Auswirkungen auf die Sicherheit haben firejail --net=br0 firefox

Lösung III: Linux iptables

Iptables könnten für diesen Zweck verwendet werden , aber dies erfordert ip_forward und könnte Auswirkungen auf die Sicherheit haben, wenn es nicht richtig konfiguriert ist, 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 anwenden möchten ( Wireguard mit Benutzerbereich ), können Sie den Anweisungen zum Erstellen eines Benutzerbereichs mit einer wg folgen Schnittstelle (und damit auf eine VPN-Schnittstelle beschränkt) kann auch mit firejail --netns=container kombiniert werden, um den User Space 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, mit denen das verwendete Gateway gefunden werden kann

$ route
$ route -n
$ ip rule list
$ ip route show
$ netstat -rn
$ cat /etc/network/interfaces
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
$ traceroute www.google.com
$ ip route show 0.0.0.0/0 dev eth0

Verwendung von App-Route-Jail

  • App-Route-Gefängnis erstellen
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • Fügen Sie in diesem Beispiel eine Route für die zukünftig markierten Pakete (für die inhaftierte Anwendung) hinzu. 192.168.1.1 Wird als erzwungenes Gateway verwendet. Diese Routenregel wirkt sich nicht auf andere Anwendungen aus. Diese Manipulation muss nur einmal beim Systemstart durchgeführt werden Zum Beispiel, wenn Sie diese Lösung täglich verwenden möchten
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • Starten Sie die Anwendung, die Sie ins Gefängnis bringen möchten
MARK=10 LD_PRELOAD=./mark.so firefox
  • Testen der fahlen IP-Adresse
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me
7
intika

Kann nicht kommentieren, also hoffe ich, dass jemand dies zu Kommentaren verschiebt. Derzeit (März 2020) ist diese Lösung mit Firejail und Wifi nicht möglich, siehe https://github.com/netblue30/firejail/issues/30

0
Hannes