2 Netzwerkkarten: Hardware Loopback

Squicky

Lt. Commander
Registriert
Sep. 2002
Beiträge
1.405
Hallo

Es soll etwas programmiert werden und für Tests ist folgend ungewöhnliche Eigenschaft gewünscht: Hardware Loopback

Es wird Linux Mint 17 Qiana Xfce x86 mit zwei Netzwerkkarten (eth0 & eth1). Jede Netzwerkkarte hat eine feste IP (z.B.: eth0: 192.168.2.100/24 und eth1: 192.168.2.200/24)

Ein selber programmiertes Programm (C++) soll nur Daten über eine Netzwerkkarte senden und empfangen. Dies ist möglich. (int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);)

Nun werden die zwei Netzwerkkarten mit einem Kabel direkt miteinander verbunden: Hardware Loopback


Leider werden die Daten aber nicht über den Hardware Loopback gesendet. Linux erkennt beim Senden, dass die Ziel-IP eine eigene IP ist sendet die Daten nicht an die Netzwerkkarte, sondern übergibt die Daten direkt an die interne Ziel-IP.


Wie kann man Linux nun einstellen dass für die zwei IPs die Daten über den Hardware Loopback gesendet/empfangen werden. (Wenn nötig, können die IPs geändert werden.)
Habe zum Teil gelesen, dass die nicht möglich ist. Habe aber auch gelesen, dass dies mit manuellen Routing Einträgen erreicht werden könnte.

Hat jemand Tipps oder Hilfe für mich?

Danke
 
Eine VM und die Netzwerkkarte der VM zuweisen. Dann sind es 2 Betriebssysteme wo nix direkt erkannt werden kann.
 
HominiLupus schrieb:
Eine VM und die Netzwerkkarte der VM zuweisen. Dann sind es 2 Betriebssysteme wo nix direkt erkannt werden kann.

Eine Vm ist nicht möglich. Das Linux Mint 17 Qiana Xfce x86 läuft direkt auf der Hardware, nicht in einer VM.
 
Ich würde beide Adapter in 2 verschiedene Subnetze stecken.


Wie sieht dein "route" config aus?
 
habe etwas geändert:

eth0: 192.168.100.100 / 24
eth1: 192.168.200.200 / 24

route:
Kernel-IP-Routentabelle
Ziel Router Genmask Flags Metric Ref Use Iface
default 192.168.100.1 0.0.0.0 UG 0 0 0 eth0
192.168.100.0 * 255.255.255.0 U 1 0 0 eth0
192.168.200.0 * 255.255.255.0 U 1 0 0 eth1

Nun soll die Daten mit Ziel-IP 192.168.100.100 über eth1 und Daten mit Ziel-IP 192.168.200.200 über eth0 gesendet werden: (Bin nicht sicher, die Richtigkeit der Befehle)

route add -net 192.168.100.100 netmask 255.255.255.255 dev eth1
route add -net 192.168.200.200 netmask 255.255.255.255 dev eth0

route:
Kernel-IP-Routentabelle
Ziel Router Genmask Flags Metric Ref Use Iface
default 192.168.100.1 0.0.0.0 UG 0 0 0 eth0
192.168.100.0 * 255.255.255.0 U 1 0 0 eth0
192.168.100.100 * 255.255.255.255 UH 0 0 0 eth1
192.168.200.0 * 255.255.255.0 U 1 0 0 eth1
192.168.200.200 * 255.255.255.255 UH 0 0 0 eth0

Leider wird immernoch der Hardware Loopback nicht genutzt.
(Datenrate ist zu groß. LED an den Netzwerkkarten blinken nicht.)
Wie es aussieht, wird zuerst geprüft, ob die Ziel-IP einge eigenen IP ist. Wenn es eine eigene IP ist, dann wird garnicht geroutet, sondern direkt an die Ziel-IP die Daten übergeben. (Oder?)

Was kann man noch versuchen? Wie geht es richtig?
 
Zuletzt bearbeitet:
Das mit den Subnetzen wird nicht funktionieren, denn das Protokoll ermöglicht keine Kommunikation zwischen verschiedenen Netzen, es sei denn du hast einen Router, welcher in beiden ist.
Das Problem ist hier eigentlich der IP-Stack an sich und das der Host sich selbst als Besitzer der Adresse erkennt. Das musst du auf Systemebene ändern... Ich habe dazu aber leider keine Anleitung parat...

Darf man denn fragen, was genau du vorhast? Mir fällt dafür kein sinnvolles Szenario ein, außer einem Kabeltest und da gibt es bessere Wege. :)
 
Folgendes geht auch nicht:
eth0: 192.168.100.100 / 24
eth1: 192.168.100.200 / 24

route add -net 192.168.100.100 netmask 255.255.255.255 dev eth1
route add -net 192.168.100.200 netmask 255.255.255.255 dev eth0



Also "IP-Stack": Wie kann man das "Ding" konfigurieren?
 
Kurz: gar nicht... :)
Das ist schlicht das Paket, welches weiß wie man mit IP-Daten umgeht und dazu gehört eben den schnellsten Weg zu finden, das bekommst du so nicht raus. Genau genommen kann es keine hilfreiche Lösung geben, denn alles was du machen kannst ist an der Verarbeitung von Localhost zu arbeiten und das fehlt in den seltensten Fällen unter "gute Idee"... Deswegen wäre auch wichtig zu wissen, was du eigentlich erreichen willst.
 
Eventuell könnte man die mit iptables Lösung??? :confused_alt:

Idee:
eth0: 192.168.100.100 / 24
eth1: 192.168.200.200 / 24

eth0 glaub mit 192.168.100.101 zu reden. Und eth1 glaub mit 192.168.200.201 zu reden.
Aber diese IPs gibt es nicht wirklich. Durch diese IPs soll der IP Stack dazu gebracht werden die Daten durch die netzwerkkarte zu senden. Und beim Empfangen werden dann die IP angepasst.


iptables -t nat -A PREROUTING -i eth0 -d 192.168.200.201 -s 192.168.200.200 -j DNAT --to-destination 192.168.100.100 SNAT --to-source 192.168.100.101

iptables -t nat -A PREROUTING -i eth1 -d 192.168.100.101 -s 192.168.100.100 -j DNAT --to-destination 192.168.200.200 SNAT --to-source 192.168.200.201



Aber wie lautet der richtige Befehl?

pc user # iptables -t nat -A PREROUTING -i eth0 -d 192.168.200.201 -s 192.168.200.200 -j DNAT --to-destination 192.168.100.100 SNAT --to-source 192.168.100.101
Bad argument `SNAT'
Try `iptables -h' or 'iptables --help' for more information.

pc user # iptables -t nat -A PREROUTING -i eth0 -d 192.168.200.201 -s 192.168.200.200 -j SNAT --to-source 192.168.100.101
iptables: Invalid argument. Run `dmesg' for more information.
pc user #

Was ist an diesen iptables Befehlen falsch?


Mein Vorhaben ist ein Hardware Loopback (siehe 1. Beitrag): Zwei Programm laufen auf einem Rechner und reden über IP miteinander. Die Daten dieser zwei programme sollen aber über die Netzwerkkarten (inkl. Kabel) laufen und nicht über den internen Software Loopback.
 
Ich meine eine VM in deinem Mint installieren und dieser VM, die gerne auch Mint laufen haben kann, den NIC zuweisen.
 
HominiLupus schrieb:
Ich meine eine VM in deinem Mint installieren und dieser VM, die gerne auch Mint laufen haben kann, den NIC zuweisen.

Eine VM ist nicht möglich!
Siehe Beitrag 3!
 
Hallo Squicky,

Die iptables-Befehle und die Absicht dahinter sind nicht kompatibel mit dem Linux Kernel.
Zuallererst nimmt jede Regel nur ein Target hinter dem Jump-Parameter. Das heißt, dass jedes Paket nur von einer einzigen Regel in einer Chain bearbeitet werden kann. Dann wird es n den nächsten Cnain weitergereicht bzw verworfen, abgelehnt oder gelangt in den nächsten Teil des Netzwerkstacks. Die Grafik hier zeigt den Paketfluss unter Linux.

Das SNAT-Target ist nur valide in der POSTROUTING- und der INPUT-Chain in der NAT-Tabelle.
Das DNAT-Target ist nur valide in der PREROUTING- und der OUTPUT-Chain in der NAT-Tabelle.

Das heißt, dass du jeweils eine Regel in einer Chain und Tabelle anlegen musst für das, was du tun willst.

Unabhängig davon habe ich einen anderen Vorschlag:
Du kannst dem Kernel über die Routing-Tabelle vorgaukeln, dass die Adresse nicht lokal ist.
Dafür musst du das Keyword "to unicast $IP" nutzen. (Statt $IP bitte deine IP einsetzen.)
Desweiteren müssen bei dir die korrekten Geräte eingesetzt werden.
Zum Beispiel so: (Das ist der gesamte Vorgang)
Hierbei ist es wichtig die Route in der Tabelle "local" zu ändern.
Denn diese Tabelle wird tatsächlich vom Kernel genutzt um die Pakete lokal zuzustellen. Spricht: Ziel-IP ist auf dem gleichen Rechner.
Unnötiger Ausgabeunsinn ist weggelassen.
Die IP von eth0 ist 192.168.178.43. Die Netzmaske ist 255.255.255.0 (CIDR-Notation ist /24).

Code:
sudo ip addr add 192.168.178.44/32 dev eth1
Code:
ip route show table local   
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1
broadcast 192.168.178.0 dev eth0  proto kernel  scope link  src 192.168.178.43
local 192.168.178.43 dev eth0  proto kernel  scope host  src 192.168.178.43
local 192.168.178.44 dev eth0  proto kernel  scope host  src 192.168.178.44
broadcast 192.168.178.255 dev eth0  proto kernel  scope link  src 192.168.178.43

Hier sollte nun eine Route zu sehen sein, die anzeigt, dass 192.168.178.44/32 lokal über 192.168.178.44 erreichbar ist.
Diese ist so zu ändern, sodass dem Kernel gesagt wird, dass 192.168.178.44 tatsächlich über 192.168.178.43 auf der Schnittstelle eth0 zu erreichen ist.
Das ist durch den folgenden Befehl zu bewerkstelligen:
Code:
sudo ip route change to unicast 192.168.178.44 scope global src 192.168.178.43 dev eth0 proto kernel table local
Code:
ip route show table local
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1 
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1 
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1
broadcast 192.168.178.0 dev eth0  proto kernel  scope link  src 192.168.178.43 
local 192.168.178.43 dev eth0  proto kernel  scope host  src 192.168.178.43 
192.168.178.44 dev eth0  proto kernel  src 192.168.178.43 
broadcast 192.168.178.255 dev eth0  proto kernel  scope link  src 192.168.178.43

Man beachte die zweitletzte Route.

Wireshark bestätigt, dass es funktioniert hat: (Das ist von eth0)
Bildschirmfoto - 27.08.2014 - 22:39:56.png

Nach dem manuellen Bekanntmachen der MAC-Adresse der IP 192.168.178.44 beginnt der Rechner auch Pakete zu schicken: (Man beachte die Quell-MAC-Adresse und die Ziel-MAC-Adresse)
Bildschirmfoto - 27.08.2014 - 22:44:33.png

Beachte, dass bei mir nun der lokale Verkehr zwischen den IPs nicht funktioniert, da die Pakete erst wieder in den Netzwerkstack gelangen, wenn sie physikalisch in die Schnittstelle wandern. Da meine Switch hier aber Pakete, deren Zielport der gleiche ist wie der Quellport, nicht in den gleichen Port switcht, gelangen diese nie an meinen Rechner und werden nie beantwortet. Bei dir sollte das jedoch dank dem physikalischen Loopback funktionieren.

Grüße,
Thermi
 
Zuletzt bearbeitet: (Noch ein bisschen Ausgabeunsinn gelöscht)
Hi

Deine Lösung sieht sehr gut aus.
Leider habe ich aber noch ein Problem:

eth0: 192.168.2.227
eth1: 192.168.2.205

Da die Daten an 227 aus eth0 gesendet werden sollen und die daten an 205 aus eth0 gesendet werden sollen, muss man doch "sudo ip route change to unicast" zwei mal ausführen. Oder? ABer beim zweitem Befehl kommt ein Fehler: "sudo ip route change to unicast"

Siehe selber:
Was ist falsch?

Code:
ip route show table local

Code:
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1 
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1 
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1 
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1 
broadcast 192.168.2.0 dev eth0  proto kernel  scope link  src 192.168.2.227 
broadcast 192.168.2.128 dev eth1  proto kernel  scope link  src 192.168.2.205 
local 192.168.2.205 dev eth1  proto kernel  scope host  src 192.168.2.205 
local 192.168.2.227 dev eth0  proto kernel  scope host  src 192.168.2.227 
broadcast 192.168.2.255 dev eth0  proto kernel  scope link  src 192.168.2.227 
broadcast 192.168.2.255 dev eth1  proto kernel  scope link  src 192.168.2.205

Code:
sudo ip route change to unicast 192.168.2.205 scope global src 192.168.2.227 dev eth0 proto kernel table local

Code:
ip route show table local

Code:
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1 
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1 
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1 
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1 
broadcast 192.168.2.0 dev eth0  proto kernel  scope link  src 192.168.2.227 
broadcast 192.168.2.128 dev eth1  proto kernel  scope link  src 192.168.2.205 
192.168.2.205 dev eth0  proto kernel  src 192.168.2.227 
local 192.168.2.227 dev eth0  proto kernel  scope host  src 192.168.2.227 
broadcast 192.168.2.255 dev eth0  proto kernel  scope link  src 192.168.2.227 
broadcast 192.168.2.255 dev eth1  proto kernel  scope link  src 192.168.2.205

Code:
sudo ip route change to unicast 192.168.2.227 scope global src 192.168.2.205 dev eth1 proto kernel table local
RTNETLINK answers: Invalid argument


Es kommt auf die Reihenfolge an: Wenn "sudo ip route change to unicast 192.168.2.227 ..." zuerst eingegeben wird, dann gibt es aber einen Fehler bei "sudo ip route change to unicast 192.168.2.205 ...".
 
Zuletzt bearbeitet:
Zurück
Oben