
Mein Ziel besteht darin, einen Container so zu konfigurieren, dass er sich wie ein Router verhält, der die Last über mehrere VPN-Verbindungen ausgleicht.
Zu diesem Zweck markiere ich die initialen Pakete wahrscheinlichkeitsmäßig mit:
iptables -I PREROUTING -t mangle -j CONNMARK --restore-mark
iptables -A PREROUTING -t mangle -m statistic --mode random --probability .50 -j MARK --set-mark 200 -m mark --mark 0
iptables -A PREROUTING -t mangle -j MARK --set-mark 201 -m mark --mark 0
iptables -A POSTROUTING -t mangle -j CONNMARK --save-mark
Dadurch wird eine von zwei Routingtabellen ausgewählt:
echo "200 tun0" >> /etc/iproute2/rt_tables
echo "201 tun1" >> /etc/iproute2/rt_tables
ip rule add fwmark 200 table tun0
ip rule add fwmark 201 table tun1
Ich glaube, dass die Routing-Tabelle richtig ausgewählt wird, denn wenn ich eine der Tabellen tun0/1 so konfiguriere, dass das VPN-Gateway verwendet wird, scheint der Datenverkehr nicht zurückgegeben zu werden. A tcpdump
zeigt an, dass Datenverkehr abgeht, aber jeder Befehl schlägt fehl.
ip route add default 10.7.7.1 dev tun0 table tun0
ip route add default 10.7.7.1 dev tun1 table tun1
Wenn die Tabellen tun0/1 den Nicht-VPN-Gateway- 10.10.10.1
Verkehr verwenden, verhält er sich wie erwartet. Ich kann auch zwischen VPN-Gateways wählen, indem ich die Standardroute in der Haupttabelle einstelle:
ip route add default 10.7.7.1 dev tun0/1
Das Problem scheint also darin zu liegen, dass das VPN-Gateway über eine der benutzerdefinierten Tabellen und nicht über die Haupttabelle ausgewählt wird. Alle Hinweise/Diagnosen/Ratschläge sind willkommen!
NB: Ich habe die erforderlichen Optionen konfiguriert:
echo 0 > /proc/sys/net/ipv4/conf/**/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
sysctl -w net.ipv4.fwmark_reflect=1
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o tun1 -j MASQUERADE
ANTWORT:
Die Antwort von @AB bietet die Lösung. Ich muss in den tun0/1-Tabellen eine Route für den zum lokalen Netzwerk zurückkehrenden Datenverkehr hinzufügen:
ip r a 10.10.10.0/24 via 10.10.10.1 table tun0
ip r a 10.10.10.0/24 via 10.10.10.1 table tun1
Wie @AB sagte, werden Pakete ohne diese Markierung an den Kanal zurückgesendet, in dem sie empfangen wurden.
Antwort1
Lassen Sie uns verfolgen, was passiert.
- Ein Paket (das erste eines neuen Datenflusses) kommt von einer Nicht-Tunnelschnittstelle an
- Kontakteinen neuen Eintrag für dieses Paket erstellen und einen neuen Fluss starten
- Paket empfängt (zufällig, dieses Mal:) Markierung 200 vor der Routing-Entscheidung
- Paket wird über Tabelle 200 geroutet
- Tabelle 200 hat eine einzige Möglichkeit: Das Paket wird gesendet durchtun0
- Die Markierung des Pakets wird für den gesamten Fluss gespeichert.KontaktEintrag (dh: derconnmark).
Soweit alles gut, das Paket (und sein Fluss) wurde lastausgeglichen durchtun0.
Was passiert nun, wenn einAntwortKommt ein Paket in diesem Fluss zurück?
Antwortpaket kommt vontun0
Antwortpaket wird identifiziert durchKontaktals Teil eines bestehenden Flusses
Paket erbt Markierung 200 von seinemconnmarkdem bestehenden Fluss vor der Routing-Entscheidung zugeordnet
Paket wird über Tabelle 200 geroutet
Tabelle 200 hat eine einzige Möglichkeit: Das Paket wird gesendet durchtun0
Ups: Das Antwortpaket wird von dort zurückgeleitet, wo es herkam: der Tunnelschnittstelle, und nicht von dort, wo das ursprüngliche Paket des Datenflusses herkam.
Abhängig davon, ob der Router des nächsten Hops (der Remote-Endpunkt des Tunnels) auch die strikte Reverse-Path-Weiterleitung (
rp_filter=0
) deaktiviert hat oder nicht, wird das Paket entweder gelöscht oder erneut zurückgeleitet, wodurch eine Schleife entsteht, bis sein dekrementierender TTL 0 erreicht.
Das Problem scheint also darin zu bestehen, dass das VPN-Gateway über eine der benutzerdefinierten Tabellen und nicht über die Haupttabelle ausgewählt wird.
Tatsächlich ist diehauptsächlichRouting-Tabelle hat mehr als eine einzige Standardroute. Sie enthält normalerweise eine oder mehrere LAN-Routen. Wenn also keine Markierung beteiligt ist, wird die Antwort nach einer Auswertung von korrekt geroutetalleder Einträge der Hauptroutingtabelle, und nicht nur der Standardroute folgen.
Diese zusätzlichen LAN-Routen: Routen übereth0Undeth1oder zumindest die mit den Client-Anfragen, wenn nicht beide, müssen auch in die zusätzlichen Routing-Tabellen 200 und 201 kopiert werden.
Zusätzliche Bemerkung (die nicht auf den Fall des OP zutrifft): In einem Setup, das in die entgegengesetzte Richtung arbeitet: ursprüngliche Flows von separaten Knoten, die dieselbe (private) IP-Quelladresse für denselben Dienst verwenden, könnten zwei unterschiedliche Flows vorhanden sein, die bis auf ihre Tunnelschnittstelle identisch aussehen (dasselbe 5-fach-Protokoll, Saddr, Sport, Daddr, Dport). StandardmäßigKontaktwürde einen einzigen Fluss sehen. Um dies zu verhindern, kann man verwendenConntrack-Zonen, (mit einem Wert, der die Schnittstelle darstellt) zu habenKontaktBehandeln Sie sie separat.