Frage

Ich arbeite an einem System, Linux-basierten Server in dem es zwei Netzwerkschnittstellen, die beide im selben Subnetz (für jetzt, kann nur sagen, sie sind 172.17.32.10 & 172.17.32.11). Wenn ich Daten an einen Host im Netzwerk senden, würde ich angeben, wie die Schnittstelle auf meinem Server werden die Daten übertragen auf. Ich muss von einer Schnittstelle zur anderen wechseln können (oder vielleicht sogar auf beide übertragen) in Software (statische Routing-Regeln werden nicht für diese Anwendung geeignet).

fand ich eine weitere Frage in Stackoverflow, der die netlink Bibliothek vorgeschlagen mit Routen on the fly zu ändern. Dies scheint intuitiv wie es funktionieren soll, aber ich frage mich, ob es noch andere Optionen waren das gleiche Ergebnis zu erzielen.

War es hilfreich?

Lösung

Nichts für ungut, aber die Antwort über die Verwendung von bind () ist falsch. bind () wird die Quell-IP-Adresse innerhalb des IP-Paket-Header platziert steuern. Es steuert nicht, welche Schnittstelle das Paket senden verwendet werden: die Routingtabelle des Kernel wird zu Rate gezogen werden, um zu bestimmen, welche Schnittstelle die niedrigsten Kosten ein bestimmtes Ziel zu erreichen hat. (* Siehe Anmerkung)

Sie sollten stattdessen eine SO_BINDTODEVICE sockopt verwenden. Dies macht zwei Dinge:

  • Die Pakete werden immer Austritt aus der Schnittstelle von Ihnen angegebenen, unabhängig davon, was der Kernel Routing-Tabellen sagt.
  • Nur Pakete auf der angegebenen Schnittstelle ankommen, werden an die Buchse ausgehändigt werden. Pakete auf andere Schnittstellen ankommen nicht.

Wenn Sie mehrere Schnittstellen haben Sie zwischen wechseln wollen, würde ich vorschlagen, eine Steckdose pro Schnittstelle zu schaffen. Da Sie auch nur werden Pakete an die Schnittstelle erhalten Sie gebunden haben, müssen Sie alle diese Buchsen an Ihrem select() / poll() hinzufügen / was auch immer Sie verwenden.

#include <net/if.h>

struct ifreq ifr;

memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "eth1", sizeof(ifr.ifr_name));
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
            (void *)&ifr, sizeof(ifr)) < 0) {
    perror("SO_BINDTODEVICE failed");
}

(* Anmerkung) Bind() an eine Schnittstelle IP-Adresse kann verwirrend führen aber dennoch die richtige Verhalten. Wenn Sie zum Beispiel der IP-Adresse bind() für eth1, aber die Routing-Tabelle sendet das Paket aus eth0, dann wird ein Paket auf dem eth0 Draht erscheinen, aber den Quell-IP-Adresse der eth1 Schnittstelle trägt. Das ist komisch, aber erlaubt, wenn Pakete zurück in der eth1 IP-Adresse gesendet würden zurück zu eth1 verlegt werden. Sie können dies testen ein Linux-System mit zwei iP Schnittstellen. Ich habe einen, und es habe zu testen, und bind() ist nicht wirksam in das Paket aus einer physikalischen Schnittstelle steuern.

Obwohl technisch erlaubt, je nach Topologie kann dies funktioniert jedoch nicht. Um verteilte Denial-of-Service-Angriffe zu dämpfen, wo die Angreifer geschmiedeten verwenden IP-Quelladressen, führen viele Router jetzt Reverse Path Forwarding (RPF) überprüft. Pakete mit einer Quell-IP-Adresse auf dem „falschen“ Weg fallen gelassen werden können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top