Erzwingen Sie lokalen IP-Verkehr zu einer externen Schnittstelle


30

Ich habe eine Maschine mit mehreren Schnittstellen, die ich nach Belieben konfigurieren kann, zum Beispiel:

  • eth1: 192.168.1.1
  • eth2: 192.168.2.2

Ich möchte den gesamten Datenverkehr, der über die andere Schnittstelle an eine dieser lokalen Adressen gesendet wird, weiterleiten. Beispielsweise sollten alle Anforderungen an einen iperf-, ftp-, http-Server unter 192.168.1.1 nicht nur intern weitergeleitet, sondern über eth2 weitergeleitet werden (und das externe Netzwerk übernimmt die Weiterleitung des Pakets an eth1).

Ich habe versucht, verschiedene Befehle wie iptables, ip route usw. zu lesen, aber nichts hat funktioniert.

Das Verhalten, das ich am ehesten erreichen konnte, war:

ip route change to 192.168.1.1/24 dev eth2

die alle 192.168.1.x auf eth2 senden, außer 192.168.1.1, die noch intern geroutet wird. Könnte ich dann NAT-Weiterleitungen für den gesamten Datenverkehr durchführen, der an gefälschte 192.168.1.2 auf eth1 gerichtet ist und intern auf 192.168.1.1 umgeleitet wurde? Ich kämpfe eigentlich mit Iptables, aber es ist zu hart für mich.

Ziel dieses Setups ist das Testen von Schnittstellentreibern ohne Verwendung von zwei PCs.

Ich benutze Linux, aber wenn Sie wissen, wie man das mit Windows macht, kaufe ich es!

Bearbeiten:

Das externe Netzwerk ist nur ein Crossover-Kabel zwischen eth1 und eth2. Angenommen, ich habe einen http-Server auf meinem Computer. Jetzt möchte ich vom selben Computer auf diesen Server zugreifen, aber ich möchte den TCP / IP-Verkehr zwingen, über dieses eth1 / eth2-Kabel zu gehen. Wie muss ich meine Schnittstellen dafür konfigurieren?


Wollen Sie damit sagen, dass der gesamte Datenverkehr über die Schnittstellen 1 und 2 gespiegelt und nur von einem anderen Router an die Schnittstelle 2 zurückgesendet werden soll? Könnte das nicht ein paar komische Sachen im Netzwerk machen? Wäre es besser, gespiegelten Datenverkehr von Schnittstelle 2 auf ein anderes System zu leiten, auf dem der Datenverkehr gerade unterbrochen wurde, und ihn dann zu überwachen, oder Virtualisierungssoftware zu verwenden, um den Datenverkehr zu erfassen? Vielleicht fehlt mir etwas in der Beschreibung.
Bart Silverstrim

Es hört sich so an, als ob er ein Paket für beispielsweise 192.168.1.1 generieren möchte, das die IP von eth1 ist. Aber anstatt dass der Linux-Stack dieses Paket vollständig intern empfängt, möchte er, dass das Paket eth2 (das von außen zurück in eth1 und dann in den Linux-Stack geliefert wird) herausgedrückt wird. Ich bin mir nicht sicher, ob dies möglich ist. Sobald die Netzwerkschicht erkennt, dass es sich bei der Adresse um eine interne Schnittstelle handelt, hat sie wenig Grund, Routingtabellen zu prüfen. Jemand anderes weiß es vielleicht besser.
PP.

Antworten:


14

Ich habe Caladonas Antwort erweitert, da ich keine Antwortpakete sehen konnte. Für dieses Beispiel:

  1. Auf meinem lokalen PC habe ich Netzwerkkarten in verschiedenen Subnetzen, 192.168.1 / 24 , 192.168.2 / 24
  2. Es gibt einen externen Router / PC, der Zugriff auf beide Subnetze hat.
  3. Ich möchte bidirektionalen Datenverkehr über die Netzwerkkarten auf dem lokalen PC senden.
  4. Die Konfiguration erfordert zwei nicht verwendete IP-Adressen für jedes Subnetz.

Lokale iptable-PC-Routen werden auf SNAT- und DNAT-ausgehenden Datenverkehr zur gefälschten IP-Adresse eingestellt.

iptables -t nat -A POSTROUTING -d 192.168.1.100 -s 192.168.2.0/24 -j SNAT --to-source      192.168.2.100
iptables -t nat -A PREROUTING  -d 192.168.1.100 -i eth0           -j DNAT --to-destination 192.168.1.1
iptables -t nat -A POSTROUTING -d 192.168.2.100 -s 192.168.1.0/24 -j SNAT --to-source      192.168.1.100
iptables -t nat -A PREROUTING  -d 192.168.2.100 -i eth1           -j DNAT --to-destination 192.168.2.1

Die Regeln machen Folgendes:

  1. Schreiben Sie die Quelle 192.168.2.1 bei ausgehenden Paketen auf 192.168.2.100 um
  2. Schreiben Sie das Ziel 192.168.1.100 bei eingehenden Paketen auf 192.168.1.1 um
  3. Schreiben Sie die Quelle 192.168.1.1 bei ausgehenden Paketen auf 192.168.1.100 um
  4. Schreiben Sie das Ziel 192.168.2.100 bei eingehenden Paketen auf 192.168.2.1 um

Zusammenfassend kann das lokale System jetzt mit einer 'virtuellen' Maschine mit den Adressen 192.168.1.100 und 192.168.2.100 kommunizieren.

Als nächstes müssen Sie Ihren lokalen PC zwingen, den externen Router zu verwenden, um Ihre gefälschte IP zu erreichen. Dazu erstellen Sie eine direkte Route zu den IPs über den Router. Sie möchten sicherstellen, dass Sie die Pakete auf das Gegenteil des Zielsubnetzes zwingen.

ip route 192.168.1.100 via $ROUTER_2_SUBNET_IP 
ip route 192.168.2.100 via $ROUTER_1_SUBNET_IP

Damit dies alles funktioniert, muss der externe Router wissen, wie er die gefälschten IP-Adressen auf Ihrem lokalen PC erreicht. Sie können dies tun, indem Sie Proxy-ARPs für Ihr System aktivieren.

echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/proxy_arp
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Mit diesem Setup können Sie die gefälschten IP-Adressen nun wie ein echtes System auf Ihrem lokalen PC behandeln. Durch das Senden von Daten an das Subnetz .1 werden Pakete aus der Schnittstelle .2 herausgefordert. Durch das Senden von Daten an das Subnetz .2 werden Pakete aus der Schnittstelle .1 herausgefordert.

ping 192.168.1.100
ping 192.168.2.100

Viel besser dein Weg! Beachten Sie, dass ich auch eine ip_forward benötige, damit ARP funktioniert: echo 1> / proc / sys / net / ipv4 / ip_forward
calandoa

28

Ich habe das Folgende unter Linux erfolgreich verwendet, um den Durchsatz einer neuen 10-Gbit / s-Dual-Port-Karte im "Loopback" -Modus zu testen, d. H. Einen Port direkt in den anderen gesteckt. Dies ist alles nur ein bisschen Voodoo, nur um Pakete aus der Leitung zu zwingen, aber wenn Sie dies nicht tun, wird Linux den Verkehr durch den Kernel kurzschließen (daher die Frage des OP). Bei der obigen Antwort von Casey bin ich mir nicht sicher, ob es wirklich notwendig war, einen externen Router zu haben, oder nicht, aber das Folgende ist völlig eigenständig. Die beiden Schnittstellen sind eth2 und eth3.

Geben Sie den Schnittstellen IPs und ordnen Sie sie in separaten Netzwerken zu:

ifconfig eth2 10.50.0.1/24
ifconfig eth3 10.50.1.1/24

Als nächstes richten wir ein doppeltes NAT-Szenario ein: zwei neue gefälschte Netzwerke, mit denen das andere erreicht wird. Versorgen Sie unterwegs Ihr falsches Netzwerk mit NAT. Bestimmen Sie auf dem Weg dorthin das Ziel. Und umgekehrt für das andere Netzwerk:

# nat source IP 10.50.0.1 -> 10.60.0.1 when going to 10.60.1.1
iptables -t nat -A POSTROUTING -s 10.50.0.1 -d 10.60.1.1 -j SNAT --to-source 10.60.0.1

# nat inbound 10.60.0.1 -> 10.50.0.1
iptables -t nat -A PREROUTING -d 10.60.0.1 -j DNAT --to-destination 10.50.0.1

# nat source IP 10.50.1.1 -> 10.60.1.1 when going to 10.60.0.1
iptables -t nat -A POSTROUTING -s 10.50.1.1 -d 10.60.0.1 -j SNAT --to-source 10.60.1.1

# nat inbound 10.60.1.1 -> 10.50.1.1
iptables -t nat -A PREROUTING -d 10.60.1.1 -j DNAT --to-destination 10.50.1.1

Sagen Sie dem System nun, wie es zu den gefälschten Netzwerken kommt, und füllen Sie die Arp-Einträge vorab aus (stellen Sie sicher, dass Sie Ihre MAC-Adressen ersetzen, verwenden Sie meine nicht):

ip route add 10.60.1.1 dev eth2
arp -i eth2 -s 10.60.1.1 00:1B:21:C1:F6:0F # eth3's mac address

ip route add 10.60.0.1 dev eth3 
arp -i eth3 -s 10.60.0.1 00:1B:21:C1:F6:0E # eth2's mac address

Dies täuscht Linux genug, um tatsächlich Pakete auf den Draht zu legen. Beispielsweise:

ping 10.60.1.1

eth2 erlischt, die Quell-IP 10.50.0.1 wird auf 10.60.0.1 NATted und bei eth3 wird das Ziel 10.60.1.1 auf 10.50.1.1 NATted. Und die Antwort nimmt eine ähnliche Reise.

Verwenden Sie nun iperf, um den Durchsatz zu testen. Binden Sie an die richtigen IPs und stellen Sie sicher, welche IP Sie kontaktieren (die falsche Adresse des anderen Endes):

# server
./iperf -B 10.50.1.1 -s

# client: your destination is the other end's fake address
./iperf -B 10.50.0.1 -c 10.60.1.1 -t 60 -i 10

Vergewissern Sie sich, dass der Datenverkehr wirklich zum Kabel fließt:

tcpdump -nn -i eth2 -c 500

Sie können auch / proc / interrupts ansehen, um sicherzugehen, dass die Karte verwendet wird:

while true ; do egrep 'eth2|eth3' /proc/interrupts ; sleep 1 ; done

Wie auch immer, ich fand diesen Beitrag auf der Suche nach einer Lösung, danke für die Fragen und Antworten und hoffe, dass dies jemand anderem hilft, diesen Beitrag in Zukunft zu finden.


+1 Tolle Lösung - dazu muss nicht einmal die IP-Weiterleitung aktiviert werden! Dies ist genau das, was ich gerade brauchte (für 10 GB-Tests über Loopback).
Nils

16

Wie immer - ich bin ein bisschen spät dran -, aber heutzutage könnte man Netzwerk-Namespaces verwenden, um die Schnittstellen zu isolieren und lokale Weiterleitungen zu verhindern (und mit iptables zu fummeln :)).

Erstellen Sie Namespaces (alle mit den erforderlichen Berechtigungen, zB als root):

ip netns add ns_server
ip netns add ns_client

Beachten Sie, dass auf die Schnittstellen status / config jetzt im Kontext des zugewiesenen Namespaces zugegriffen werden muss. Sie werden also nicht angezeigt , wenn Sie einen nackten IP-Link ausführen, da dieser im Kontext des Standardnamespaces ausgeführt wird. Das Ausführen eines Befehls in einem Namespace kann mit ausgeführt werden

ip netns exec <namespace-name> <command>

als Präfix.

Weisen Sie jetzt den Schnittstellen Namespaces zu, wenden Sie config an und richten Sie die Schnittstellen ein:

ip link set eth1 netns ns_server
ip netns exec ns_server ip addr add dev eth1 192.168.1.1/24
ip netns exec ns_server ip link set dev eth1 up
ip link set eth2 netns ns_client
ip netns exec ns_client ip addr add dev eth2 192.168.1.2/24
ip netns exec ns_client ip link set dev eth2 up

Jetzt können Sie die Anwendungen im Namespace ausführen - für den iperf-Serverlauf

ip netns exec ns_server iperf -s -B 192.168.1.1

und der Kunde:

ip netns exec ns_client iperf -c 192.168.1.1 -B 192.168.1.2

Der Datenverkehr wird nun über die physischen Schnittstellen gesendet, da der gesamte Netzwerkstack, die Schnittstelle, das Routing ... durch die Namespaces isoliert ist und der Kernel nicht in der Lage ist, die im Datenverkehr verwendeten Adressen mit lokalen (verfügbaren) Schnittstellen abzugleichen.

Wenn Sie mit Ihren Experimenten fertig sind, löschen Sie einfach die Namespaces:

ip netns del <namespace-name>

Die Schnittstellen werden dem Standard-Namespace neu zugewiesen und alle im Namespace vorgenommenen Konfigurationen verschwinden (z. B. müssen zugewiesene IP-Adressen nicht gelöscht werden).


Dies ist weitaus einfacher als die vorgeschlagene Double-Nat-Magie und erfordert keine Koordination durch andere Computer im Netzwerk und keine physikalische Topologie. Meine einzige Bitte wäre, dass Sie Befehle hinzufügen, um Routen hinzuzufügen.
Huckle

2

Ok, es ist mir endlich gelungen, meine Konfiguration einzurichten.

Die Idee ist, eine andere gefälschte Adresse zu verwenden, um die Route dieser gefälschten Adresse zur Schnittstelle 2 zu erzwingen und dann die gefälschte Adresse mit der realen Adresse 2 mit NAT / iptables zu übersetzen.

Meine Einrichtung besteht eigentlich aus einem Router, den ich zwischen IF1 (Schnittstelle 1) und IF2 telnet kann

In meiner Konfiguration befinden sich FAKE_ADDR und IF1_ADDR im selben Subnetz.

ifconfig $IF1 $IF1_ADDR netmask 255.255.255.0
ifconfig $IF2 $IF2_ADDR netmask 255.255.255.0

iptables -t nat -A PREROUTING -d $FAKE_ADDR -i $IF2 -j DNAT --to-destination $IF2_ADDR
iptables -t nat -A POSTROUTING -s $IF2_ADDR -d $IF1_ADDR/24 -j SNAT --to-source $FAKE_ADDR

route add $FAKE_ADDR gw $ROUTER_ADDR

Und auf dem Router:

route add $FAKE_ADDR gw $IF2_ADDR

Wenn ich etwas an FAKE_ADDR sende, wird pkt über IF1 an den Router weitergeleitet und erneut an IF2. Dann wird FAKE_IP durch IF2_ADDR ersetzt. Das Paket wird vom Server verarbeitet, das Ergebnis wird von IF2_ADDR, das durch FAKE_ADDR ersetzt wird, an IF1_ADDR zurückgesendet.

Möglicherweise ist es möglich, eine einfachere Konfiguration mit nur einem Crossover-Kabel zu verwenden, aber da ich nicht versucht habe, habe ich es vorgezogen, meine funktionierende Lösung anzugeben.


Wenn der Router $ FAKE_ADDR an $ IF2_ADDR sendet, muss Ihre DNAT-Regel nicht "-i $ IF2" anstelle von "-i $ IF1" sein?
cmcginty

Sie haben recht, Casey, die Korrektur ist erledigt.
Calandoa

1

Die Antwort von Thomas Tannhäuser war genau richtig!

Ich hatte eine ähnliche Situation: eine einzelne Maschine mit zwei enet-Schnittstellen. Mein Plan war, eine Schnittstelle als Server (Empfänger) und die andere als Client (Absender) zu verwenden. Jede Schnittstelle wäre mit dem Router verbunden und iperf würde den Datenverkehr durch den Router leiten, um den Durchsatz, die PPS, die Verzögerung usw. zu messen.

Leider war der Ansatz von iptables nicht intuitiv und mit Problemen behaftet. Nach ein paar frustrierenden Stunden gab ich diesen Angriffsplan auf. Inspiriert von Thomas Vorschlag, machte ich ein paar Hausaufgaben zu Linux IP Namespaces und begann die Einfachheit und Eleganz dieser Lösung zu schätzen.

Nachfolgend finden Sie eine Liste der genauen Befehle, mit denen ich den Fedora FC26 für diese Funktion konfiguriert habe. Die beiden Schnittstellen sind enp1s0 und enp3s0. Der Router verfügt über zwei Schnittstellen mit den Adressen 192.168.2.112 und 172.16.16.2. Jeder FC26 ENET-Anschluss ist direkt mit der entsprechenden Router-Schnittstelle verbunden.

# How to configure the IP Namespaces
ip netns add iperf-server
ip netns add iperf-client
ip link set enp1s0 netns iperf-server
ip link set enp3s0 netns iperf-client
ip netns exec iperf-server ip addr add dev enp1s0 192.168.2.139/20
ip netns exec iperf-client ip addr add dev enp3s0 172.16.16.2/24
ip netns exec iperf-client ip link set dev enp3s0 up
ip netns exec iperf-server ip link set dev enp1s0 up
ip netns exec iperf-server route add default gw 192.168.2.112
ip netns exec iperf-client route add default gw 172.16.16.1

# Test the interfaces and network using ping
ip netns exec iperf-client ping -c1 172.16.16.1
ip netns exec iperf-server ping -c1 192.168.2.112
ip netns exec iperf-server ping -c1 172.16.16.2
ip netns exec iperf-client ping -c1 192.168.2.139

# Start Iperf Server for UDP test
ip netns exec iperf-server iperf -u -s
# Run Client against Iperf server for UDP test
ip netns exec iperf-client iperf -u -c 192.168.2.139

0

Es hört sich so an, als ob Sie Ihre Linux-Box in eine Router / Bridge / Gateway / Firewall-Box verwandeln möchten. Die folgenden Ressourcen könnten das sein, wonach Sie suchen:

Das Linux-Router-Projekt

Liste der Router- oder Firewall-Distributionen

Linux LiveCD Router

Linux Journal - Der Linux Router

Update basierend auf weiteren Informationen:

Ich glaube nicht, dass Sie tun können, was Sie wollen. Das Betriebssystem wird immer auf seine interne Routingtabelle schauen und beide IP-Adressen lokal "sehen". Es wird dann den Verkehr innerhalb des Betriebssystems leiten und niemals auf die Leitung legen. Sie benötigen eine zweite Maschine oder zwei virtuelle Maschinen (siehe Xen ).


0

Eine Menge Dinge, die hier zu erledigen sind, daher kann ich meine Genauigkeit nicht vollständig garantieren, aber die ursprüngliche Frage scheint nach einer Technik zu suchen, die als "an sich selbst senden" bekannt ist . Die verknüpfte Suche zeigt, was meiner Meinung nach der am besten gepflegte Kernel-Patch ist, wie Top-Link + Diskussionen und Patches mit anderen Ansätzen auf verschiedenen Mailinglisten, insbesondere. LKML.

Ich denke, man sollte sich auch die Netzwerk-Namespaces ansehen , die mit iproute2s "ip netns" erstellt wurden . Dies erfordert auch etwas zusätzliche Schnittstellen- und Routing-Magie und ist daher möglicherweise nicht weniger komplex als der massive Iptables-Hoopla in den anderen Antworten.

Kommentare sind auf jeden Fall willkommen, wenn jemand etwas Nützliches dabei findet - das Wie, das Was, das Wo Ihrer Implementierung.



-1

Hier ist, wie ich es für IPV6 zum Laufen gebracht habe

zugewiesene statische IPS

/sbin/ifconfig eth1 inet6 add 2001:db8::1/127 
/sbin/ifconfig eth3 inet6 add 2001:db8::2/127 

Richten Sie nur Host-Routen zu "FAKE" -Adressen ein

ip -6 route add 2001:db8::2/128 dev eth1 metric 1
ip -6 route add 2001:db8::1/128 dev eth3 metric 1

bevölkerte die Nachbar-Tabelle ... wie die Arp

ip -6 neighbor add 2001:db8::1 lladdr 90:e2:ba:0d:75:e8 dev eth3 # eth1's mac address
ip -6 neighbor add 2001:db8::2 lladdr 90:e2:ba:0d:75:e9 dev eth1 # eth3's mac address

hat die ip6tables-Einträge hinzugefügt

ip6tables -t nat -A POSTROUTING -s 2001:db8::1 -d 2013::2 -j SNAT --to-source 2001:db8::1
ip6tables -t nat -A PREROUTING -d 2001:db8::1 -j DNAT --to-destination 2001:db8::1
ip6tables -t nat -A POSTROUTING -s 2001:db8::2 -d 2013::1 -j SNAT --to-source 2001:db8::2
ip6tables -t nat -A PREROUTING -d 2001:db8::2 -j DNAT --to-destination 2001:db8::2

Welche Distribution benutzt du? Bei der letzten Überprüfung hat der Kernel keine NAT-Tabelle für IPv6.
fukawi2
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.