Warum Ihr öffentlicher Linux-Dienst stattdessen über das VPN antwortet
Ein lokaler Dienst kann auf eth0 Anfragen annehmen und über ein Full-Tunnel-VPN antworten. Eine Quellregel mit einer vollständigen WAN-Tabelle hält diese Antworten auf dem ursprünglichen Pfad.
Nichts im Socket erinnert sich daran, welche Schnittstelle die Anfrage transportiert hat, daher kann eine Full-Tunnel-VPN-Standardroute eine Antwort abfangen, die auf das WAN gehört. Der Dienst ignoriert die eingehende Schnittstelle nicht; Linux leitet eine lokal erzeugte Antwort anhand von Ziel und Quellrichtlinie weiter. Eine quellenbasierte Regel kann stattdessen nur die Antworten des Dienstes über eine vollständige WAN-Tabelle senden und den gewöhnlichen Ausgang auf dem Tunnel belassen. Der Port bleibt offen, während die Antwort über den falschen Pfad hinausgeht, weshalb das Symptom einseitig wirkt.
Das Missverständnis: Antworten folgen der Schnittstelle, auf der sie ankamen
Es wirkt logisch, dass ein Paket, das auf eth0 ankommt, eth0 wieder verlässt. Zustandslose Paketfilter lassen sich so schreiben, und tcpdump auf der Eingangsseite zeigt die Anfrage genau dort, wo man sie erwartet. Das Routing funktioniert bei Verkehr, den der Host selbst erzeugt, nicht so.
Sobald der Dienst die Verbindung annimmt, ist seine Antwort ein neues, lokal erzeugtes Paket. Der Kernel konsultiert die Routingregeln für Ziel und Quelle der Antwort, und die Standardroute des VPN ist eine völlig gültige Antwort. Nichts im Socket erinnert sich daran, welche Schnittstelle die Anfrage transportiert hat.
Deshalb wirkt das Symptom einseitig: Anfragen kommen an, Antworten verschwinden. Deshalb ändert auch eine Firewallregel für den eingehenden Port nichts. Das Paket wird nicht auf dem Weg hinein blockiert; es wird auf dem Weg hinaus woandershin geleitet. Verfolgen Sie die Antwort mit einer quellqualifizierten Suche, und der Umweg wird sichtbar.
Was der Kernel wirklich routet: die Quelladresse
Der Ansatzpunkt, den Sie brauchen, ist die lokale Adresse, die der Dienst für Antworten verwendet. Auf einem Host mit der beispielhaften eth0-Adresse 192.0.2.10/24 und dem Gateway 192.0.2.1 ist diese Adresse auf der Schnittstelle vorhanden. Bei einer Cloud-VM kann die öffentliche Adresse vorgelagert übersetzt und im Gast nicht vorhanden sein; verwenden Sie daher die Adresse, die der Host tatsächlich besitzt.
Prüfen Sie den aktuellen Zustand, bevor Sie eine Tabellennummer oder eine Regelpriorität reservieren. Vorhandene Richtlinienregeln können eine neue überdecken, und eine alte Tabelle mit derselben Nummer kann bereits fremde Routen enthalten:
ip -4 addr show dev eth0
ip -4 rule show
ip -4 route show table all
Wählen Sie dann eine Tabelle anhand der Quelle. Die Regel trifft Antworten, die bereits 192.0.2.10 tragen, also genau den lokal beendeten Verkehr, den Sie ausnehmen wollen. Weitergeleiteter Verkehr und Pakete anderer lokaler Adressen passen nicht.
Bauen Sie eine vollständige Rücktabelle, keine halbe Standardroute
Eine Tabelle mit nur einer Standardroute reicht nicht. Der Kernel muss noch das Gateway auflösen, und diese Auflösung braucht das verbundene Präfix in derselben Tabelle. Eine Tabelle, der dieses Präfix fehlt, scheitert an der Gateway-Auflösung, selbst wenn ihre Standardroute korrekt aussieht. Fügen Sie beides hinzu und zeigen Sie dann mit der Quellregel auf die Tabelle:
ip -4 route add table 100 192.0.2.0/24 dev eth0 src 192.0.2.10
ip -4 route add table 100 default via 192.0.2.1 dev eth0
ip -4 rule add priority 1000 from 192.0.2.10/32 lookup 100
Verwenden Sie das echte Präfix und das echte Gateway, statt das Beispiel zu kopieren. Eine Cloud-Schnittstelle, die als /32 mit einem On-Link-Gateway konfiguriert ist, braucht eine andere verbundene Route, und eine aus dem falschen Präfix gebaute Tabelle scheitert am ersten Hop. Das Attribut src nennt die bevorzugte Quelle für diese Route; es ersetzt nicht die Quellregel.
Auch die Reihenfolge zählt. Eine breite Regel mit einer niedrigeren Prioritätsnummer wird zuerst ausgewertet, daher muss die Quellregel vor jeder Regel erreicht werden, die diesen Verkehr zurück in die Haupttabelle schicken würde. Prüfen Sie die Prioritäten mit ip rule show nach dem Hinzufügen, nicht nur beim Start.
Mit einer quellqualifizierten Suche prüfen
Bitten Sie den Kernel, ein Testziel von der Dienstadresse aus zu routen. Die Antwort sollte eth0 und das WAN-Gateway nennen, nicht den Tunnel:
ip -4 route get 198.51.100.25 from 192.0.2.10
Stellen Sie dann eine neue autorisierte Verbindung her und beobachten Sie beide Richtungen. Eine Suche, die die richtige Tabelle wählt, während die reale Verbindung weiterhin scheitert, deutet auf Reverse-Path-Filterung oder eine Firewallregel hin, nicht auf die Tabelle. Prüfen Sie diese Kontrollen, bevor Sie irgendetwas global abschalten.
Legen Sie die endgültigen Routen und die Regel unter den Netzwerkmanager, dem die Schnittstelle gehört. Adressänderungen, DHCP-Erneuerung und VPN-Wiederverbindungen schreiben alle den Kernelzustand neu, und eine von Hand hinzugefügte Regel verschwindet oder zeigt nach dem nächsten Ereignis auf ein veraltetes Gateway.
Wo diese Ausnahme endet
Die Regel nimmt lokal beendeten Verkehr von einer Quelladresse aus. Sie deckt keine von Docker veröffentlichten Ports, kein DNAT und keine über den Host weitergeleiteten Dienste ab, weil diese Pakete als weitergeleiteter Verkehr geroutet werden und niemals auf dieselbe Weise die lokale Quelle des Hosts tragen. Solche Entwürfe brauchen meist eine beim Eingang gesetzte Markierung und eine Regel, die auf diese Markierung passt.
Sie sorgt auch nicht dafür, dass die öffentliche Adresse des Hosts auf der Schnittstelle erscheint. Wenn ein vorgelagertes NAT diese Adresse besitzt, muss die Antwort weiterhin über den Pfad hinausgehen, den dieses NAT erwartet, weshalb die WAN-Tabelle das ursprüngliche Gateway und Präfix spiegeln muss statt eines geratenen öffentlichen Bereichs.
Dokumentieren Sie die Ausnahme mit ihrer Tabellennummer, ihrer Regelpriorität und der genauen Quelladresse. Die nächste Änderung am VPN oder an der Schnittstelle kann sie stillschweigend brechen, und eine Notiz, die die drei Werte nennt, ist schneller zu prüfen, als das Symptom aus einem Kundenbericht neu zu entdecken.
Wenn der Dienst nach bestandener quellqualifizierter Suche weiterhin auf dem falschen Pfad antwortet, vergleichen Sie die Quelladresse des realen Sockets mit der in der Regel. Ein Dienst, der an eine Platzhalteradresse gebunden ist, kann eine andere Quelle wählen als die getestete Adresse, und diese Abweichung ist die verbleibende Lücke.