Lösung 1:
Ich habe das Folgende unter Linux erfolgreich verwendet, um den Durchsatz auf einer neuen Dual-Port-10-Gbit/s-Karte im „Loopback“-Modus zu testen, d. h. ein Port ist direkt an den anderen angeschlossen. Das ist alles nur ein bisschen Voodoo, nur um Pakete aus der Leitung zu zwingen, aber wenn Sie dies nicht tun, wird Linux den Datenverkehr durch den Kernel kurzschließen (daher die Frage des OP). In Caseys Antwort oben bin ich mir nicht sicher, ob es wirklich notwendig war, einen externen Router zu haben oder nicht, aber das Folgende ist völlig in sich abgeschlossen. Die beiden Schnittstellen sind eth2 und eth3.
Geben Sie den Schnittstellen IPs und legen Sie sie in separaten Netzwerken ab:
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, die verwendet werden, um das andere zu erreichen. Geben Sie auf dem Weg nach draußen NAT in Ihr gefälschtes Netzwerk ein. Legen Sie auf dem Hinweg das Ziel fest. 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
Teilen Sie dem System nun mit, wie es zu jedem gefälschten Netzwerk gelangen kann, und füllen Sie die arp-Einträge vorab aus (stellen Sie sicher, dass Sie Ihre MAC-Adressen ersetzen, verwenden Sie nicht meine):
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 die Leitung zu bringen. Zum Beispiel:
ping 10.60.1.1
geht eth2 aus, wird die Quell-IP 10.50.0.1 auf 10.60.0.1 NATted, und wenn sie in eth3 eingeht, wird das Ziel 10.60.1.1 auf 10.50.1.1 NATted. Und die Antwort nimmt einen ähnlichen Weg.
Verwenden Sie jetzt iperf, um den Durchsatz zu testen. Binden Sie sich an die richtigen IPs und stellen Sie sicher, welche IP Sie kontaktieren (die gefälschte 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
Stellen Sie sicher, dass der Datenverkehr wirklich an die Leitung geht:
tcpdump -nn -i eth2 -c 500
Sie können auch /proc/interrupts beobachten, um absolut sicherzugehen, dass die Karte verwendet wird:
while true ; do egrep 'eth2|eth3' /proc/interrupts ; sleep 1 ; done
Wie auch immer, ich habe diesen Beitrag gefunden, als ich gesucht habe, wie das geht, danke für die Q&A-Leute und hoffe, dass dies anderen hilft, diesen Beitrag in Zukunft zu finden.
Lösung 2:
Wie immer - ich bin etwas spät dran - aber heutzutage könnte man Netzwerk-Namespaces verwenden, um die Schnittstellen zu isolieren und jegliche lokale Weiterleitung zu verhindern (und mit iptables herumzuspielen :)).
Namespaces erstellen (alles mit den erforderlichen Berechtigungen, z. B. als root):
ip netns add ns_server
ip netns add ns_client
Beachten Sie, dass auf den Status/die Konfiguration der Schnittstellen jetzt im Kontext des zugewiesenen Namensraums zugegriffen werden muss – sie werden also nicht angezeigt, wenn Sie einen nackten IP-Link ausführen da dies im Kontext des Standard-Namensraums ausgeführt wird. Das Ausführen eines Befehls innerhalb eines Namensraums kann mit
erfolgenip netns exec <namespace-name> <command>
als Präfix.
Weisen Sie nun den Schnittstellen Namensräume zu, wenden Sie die Konfiguration 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 innerhalb des Namensraums ausführen - für den iperf-Server ausführen
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 Netzwerkstapel, die Schnittstelle, das Routing ... durch die Namensräume isoliert ist, sodass der Kernel die im Datenverkehr verwendeten Adressen nicht mit lokalen (verfügbaren) Schnittstellen abgleichen kann.
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 innerhalb des Namespace vorgenommenen Konfigurationen verschwinden (z. B. müssen zugewiesene IP-Adressen nicht gelöscht werden).
Lösung 3:
Ich habe Caladonas Antwort erweitert, da ich keine Antwortpakete sehen konnte. Für dieses Beispiel:
- Auf meinem lokalen PC habe ich NICs in verschiedenen Subnetzen, 192.168.1/24 , 192.168.2/24
- Es gibt einen externen Router/PC, der Zugriff auf beide Subnetze hat.
- Ich möchte bidirektionalen Datenverkehr über die NICs auf dem lokalen PC senden.
- Die Konfiguration erfordert zwei unbenutzte IP-Adressen für jedes Subnetz.
Lokale PC-iptable-Routen werden auf ausgehenden SNAT- und DNAT-Verkehr an die „falsche“ IP gesetzt.
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:
- Schreiben Sie die Quelle 192.168.2.1 bei ausgehenden Paketen auf 192.168.2.100 um
- Schreiben Sie das Ziel 192.168.1.100 bei eingehenden Paketen in 192.168.1.1 um
- Schreiben Sie die Quelle 192.168.1.1 bei ausgehenden Paketen auf 192.168.1.100 um
- Schreiben Sie das Ziel 192.168.2.100 bei eingehenden Paketen in 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. Sie tun dies, indem Sie über den Router eine direkte Route zu den IPs erstellen. Sie sollten sicherstellen, dass Sie die Pakete auf das Gegenteil des Ziel-Subnetzes zwingen.
ip route 192.168.1.100 via $ROUTER_2_SUBNET_IP
ip route 192.168.2.100 via $ROUTER_1_SUBNET_IP
Damit das alles funktioniert, muss der externe Router schließlich wissen, wie er die gefälschten IPs auf Ihrem lokalen PC erreichen kann. 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 IPs jetzt wie ein echtes System auf Ihrem lokalen PC behandeln. Das Senden von Daten an das .1-Subnetz zwingt Pakete aus der .2-Schnittstelle. Das Senden von Daten an das .2-Subnetz erzwingt Pakete aus der .1-Schnittstelle.
ping 192.168.1.100
ping 192.168.2.100
Lösung 4:
Ok, ich habe es endlich geschafft, 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 echten Adresse 2 mit NAT/iptables zu übersetzen.
Meine Einrichtung besteht tatsächlich aus einem Router, den ich zwischen IF1 (Schnittstelle 1) und IF2 telnet kann
In meinem Setup 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, erneut an IF2 weitergeleitet, dann wird FAKE_IP durch IF2_ADDR ersetzt. Das Paket wird vom Server verarbeitet, das Ergebnis wird an IF1_ADDR zurückgesendet, von IF2_ADDR, das durch FAKE_ADDR ersetzt wird.
Vielleicht ist es möglich, eine einfachere Konfiguration mit nur einem Crossover-Kabel zu verwenden, aber da ich es nicht versucht habe, ziehe ich es vor, meine funktionierende Lösung zu geben.