Kann ein Multihomed-Linux-Rechner ein echtes Strong ES-Modell implementieren?
Spezifischer Anwendungsfall
Ich habe ein System mit fünf verschiedenen Schnittstellen, die alle mit demselben Subnetz verbunden sind, also demselben Gateway zum Internet.
- Ich möchte jede Schnittstelle separat am selben Port abhören und sicherstellen, dass Pakete immer über dieselbe Schnittstelle hinausgehen, an der sie angekommen sind, und sicherstellen, dass Pakete, die versuchen, an der „falschen“ Schnittstelle anzukommen, verworfen werden.
- Ich möchte in der Lage sein, mich an jede Schnittstelle zu binden und ausgehende Verbindungen zu Internetzielen herzustellen, die immer von derselben Quell-IP stammen, an die ich gebunden habe. Beispiel:
curl --interface interface_ip http://ipecho.net/plain
sollte immer dieselbe IP-Adresse anzeigen, an die ich mit
--interface
gebunden habe . - Statische Routen können aufgrund der Verwendung von DHCP auf einer dieser Schnittstellen problematisch sein.
RFC 1122
Aus RFC 1122 – Anforderungen für Internet-Hosts – Kommunikationsschichten, Abschnitt 3.3.4.2 – Multihoming-Anforderungen:
Internet-Host-Implementierer haben zwei verschiedene
konzeptionelle Modelle für Multihoming verwendet, die in der folgenden Erörterung
kurz zusammengefasst werden. Dieses Dokument nimmt keinen
Standpunkt dazu ein, welches Modell bevorzugt wird; jeder scheint einen
Platz zu haben. Diese Ambivalenz spiegelt sich darin wider, dass die Themen (A)
und (B) optional sind.
-
Starkes ES-Modell
- Das starke ES-Modell (Endsystem, d. h. Host)
betont die Unterscheidung von Host/Gateway (ES/IS),
und würde daher in
Fragen MUST durch MAY ersetzen (A ) und (B) oben. Es neigt dazu, einen
Multihomed-Host als einen Satz logischer Hosts innerhalb
desselben physischen Hosts zu modellieren.In Bezug auf (A) bemerken Befürworter des Strong ES
-Modells, dass automatische Internet-Routing-Mechanismen
ein Datagramm nicht an eine
physische Schnittstelle leiten konnten, die nicht der
entspricht Zieladresse.Unter dem Strong ES-Modell ist die Routenberechnung
für ein ausgehendes Datagramm das Mapping:route(src IP addr, dest IP addr, TOS) -> gateway
Hier wird die Quelladresse als Parameter
angegeben, um ein Gateway auszuwählen, das auf der entsprechenden physikalischen Schnittstelle
direkt erreichbar ist.
Beachten Sie, dass dieses Modell logischerweise voraussetzt, dass
im Allgemeinen mindestens ein Standard-Gateway und
vorzugsweise mehrere Standard-Gateways für jede IP-Quelladresse
vorhanden sind.
Schwaches ES-Modell
- Diese Ansicht schwächt die ES/IS-Unterscheidung ab und
würde daher in
den Themen (A) und (B) MUST NOT durch MAY ersetzen. Dieses Modell ist möglicherweise das
natürlichere für Hosts, die Gateway-Routingprotokolle
abhören, und ist für Hosts mit
eingebetteter Gateway-Funktionalität erforderlich.
Das schwache ES-Modell kann dazu führen, dass der Redirect-Mechanismus
fehlschlägt. Wenn ein Datagramm über eine physische
Schnittstelle gesendet wird, die nicht der
Zieladresse entspricht, erkennt das First-Hop-Gateway
nicht, wann es eine Umleitung senden muss. Wenn der Host andererseits
über eine eingebettete Gateway-Funktion
verfügt, verfügt er über Routing-Informationen
ohne auf Redirects zu hören.
Im schwachen ES-Modell ist die Routenberechnung für ein
ausgehendes Datagramm das Mapping:
route(dest IP addr, TOS) -> gateway, interface
Linux ist standardmäßig ein schwaches ES-Modell, während FreeBSD und andere Unix-Varianten als starke ES-Systeme fungieren. Gibt es eine Möglichkeit, es sich eher wie ein Strong ES-System zu verhalten?
Was sysctl
oder die Konfiguration zur Kompilierzeit müsste so eingestellt werden, dass sie sich standardmäßig wie ein Strong ES verhält, ohne spezifische Routing-Regeln für jede neue Schnittstelle hinzuzufügen, die Sie hinzufügen? Ich weiß, dass wir eine strenge Source-Route-Filterung über net.ipv4.conf.default.rp_filter = 1
durchführen können , aber da scheint noch viel mehr dahinter zu stecken. Wie kann ich standardmäßig quellenbasiertes Routing durchführen?
Akzeptierte Antwort:
Nur das Hinzufügen von Firewall-Regeln wird für diese nicht ausreichen. Sie möchten, dass das System den Datenverkehr so weiterleitet, als ob es sich um zwei unabhängige Systeme handelt, die sich zufällig dieselbe Hardware und dieselben Prozesse teilen:Das ist es, was das Strong ES-Modell effektiv ist.
Verwandte:Linux – Manpage nur gefunden, nachdem sie mit root ausgeführt wurde?Wenn Sie ein starkes ES-Modell unter Linux anstreben, benötigen Sie zunächst diese sysctl-Einstellungen:
net.ipv4.conf.all.arp_filter=1
net.ipv4.conf.all.arp_ignore=1 # or even 2
net.ipv4.conf.all.arp_announce=2
Diese Einstellungen sorgen dafür, dass sich ARP mit dem Strong ES-Modell angemessen verhält, d. h. wenn eine ARP-Anfrage empfangen wird, antwortet nur die Schnittstelle mit der exakt angeforderten Adresse und nur dann, wenn der Datenverkehr an die Ursprungsadresse tatsächlich über diese spezifische gesendet wird Schnittstelle.
Da Sie fünf Schnittstellen haben, die sich in Bezug auf das Routing unterschiedlich verhalten sollen, müssen Sie fünf benutzerdefinierte Routing-Tabellen einrichten. Sie könnten Nummern verwenden, um sie zu identifizieren, aber im Allgemeinen ist es klarer, Namen für sie anzugeben. Wählen Sie also für jeden von ihnen Nummern zwischen 1 und 252 und einige passende Namen aus. (Die Nummern 0, 253, 254 und 255 sind reserviert.)
Nehmen wir zum Beispiel 100 =rtable0, 101 =rtable1, 102 =rtable2, 103 =rtable3 und 104 =rtable4. Fügen Sie diese Nummern und Namen am Ende von /etc/iproute2/rt_tables
hinzu Datei:
# ...default stuff above...
100 rtable0
101 rtable1
102 rtable2
103 rtable3
104 rtable4
Füllen Sie dann jede benutzerdefinierte Routing-Tabelle mit einem minimalen Satz von Routeneinträgen, die für jede Schnittstelle geeignet sind. (Ich ersetze tatsächliche Werte durch hoffentlich aussagekräftige Umgebungsvariablennamen.)
ip route add $ETH0_NET dev eth0 proto static src $ETH0_IP table rtable0
ip route add default via $ETH0_GW dev eth0 proto static src $ETH0_IP table rtable0
ip route add $ETH1_NET dev eth1 proto static src $ETH1_IP table rtable1
ip route add default via $ETH1_GW dev eth1 proto static src $ETH1_IP table rtable1
# ... and so on, for all 5 interfaces
Fügen Sie schließlich erweiterte Routing-Regeln hinzu, die die Quelladresse jedes Pakets prüfen und die entsprechend zu verwendende Routing-Tabelle auswählen:
ip rule add from $ETH0_IP table rtable0
ip rule add from $ETH1_IP table rtable1
#...
Um all diese Konfigurationen über Neustarts hinweg dauerhaft zu machen, müssen Sie möglicherweise benutzerdefinierte Startskripts schreiben (oder möglicherweise ifup-pre
oder ifup-post
Skripte), um den Konventionen Ihrer Linux-Distribution zu entsprechen.
Für eine zusätzliche Sicherheit können Sie iptables-Regeln pro Schnittstelle hinzufügen, um alle eingehenden Pakete, die möglicherweise auf der falschen Schnittstelle empfangen werden, stillschweigend zu verwerfen. Wenn alles in Ordnung ist, sollten die Paketzähler für diese Nullen bleiben:Wenn sie anfangen zu steigen, haben Sie möglicherweise etwas in der Konfiguration übersehen.
iptables -A INPUT -m addrtype --dst-type UNICAST -i eth0 ! -d $ETH0_IP -j DROP
iptables -A INPUT -m addrtype --dst-type UNICAST -i eth1 ! -d $ETH1_IP -j DROP
# ... and so on for each interface
Hinweis: Ich habe einmal ein solches Setup basierend auf einer alten Internetdiskussion von Rick Jones und anderen Netzwerk-Gurus implementiert. Sie sagten paraphrasiert, „während all dies eindeutig notwendig ist Um ein starkes Hostmodell-Verhalten unter Linux zu erreichen, kann ich nicht garantieren, dass es ausreichend ist für alle möglichen Anwendungsfälle“. Es funktionierte einwandfrei für mich; Es kann für Sie ausreichen oder nicht, je nachdem, wofür Sie es verwenden möchten.
Warnung: Stellen Sie sicher, dass Sie beim Einrichten dieser Konfiguration über eine Art lokalen oder Remote-Konsolenzugriff auf das System verfügen. Es ist sehr wahrscheinlich, dass diese Einrichtung Ihren Netzwerkzugriff vollständig durcheinander bringt, während sie nur halb fertig ist.
Während es möglich wäre, N Schnittstellen mit nur (N-1) benutzerdefinierten Routing-Tabellen einzurichten, ist es meine persönliche Präferenz, die gesamte Routing-Konfiguration in benutzerdefinierte Tabellen zu verschieben, wenn ich erweitertes Routing verwende. Mit route -n
oder ip route show
im Wesentlichen leer erscheinen, während das System eindeutig Netzwerkverbindungen hat, wird ein sehr großer Hinweis darauf sein, dass etwas ganz Besonderes vor sich geht. Trotzdem habe ich damals, als ich ein solches System eingerichtet habe, auch einen permanenten Hinweis in /etc/motd
eingerichtet über das aktive Routing und die Speicherorte der eigentlichen Skripte, die es einrichten.