Die Anfrage kommt mit der Tunnel-IP als Ziel an und verlässt denselben Container mit der Adresse eines Nachbardienstes. Zwischen diesen beiden Momenten hat DNAT das Ziel umgeschrieben, und das Paket war kein Input für den VPN-Container mehr. Jetzt ist es weitergeleiteter Verkehr, über den eine andere Regel entscheidet. Dieser Wechsel erklärt, warum eine Firewall-Regel, die für die Tunneladresse richtig aussieht, keine Wirkung auf die übersetzte Verbindung hat.

Verfolgen Sie das Paket nach der Übersetzung

Nehmen Sie einen Client-Pool von 10.90.0.0/24 und eine Tunneladresse von 10.90.0.1. Zwei Container liegen auf einer Bridge: 192.0.2.2 betreibt das VPN, 192.0.2.3 die Anwendung. Ein Client verbindet sich mit 10.90.0.1:8080, und die DNAT-Regel im Namespace des VPN-Containers schreibt das auf die echte Adresse und den Port der Anwendung um. Eine Route schickt das Paket dann über die Bridge. Diese Adressen sind illustrativ, kein Deployment-Rezept.

Der Port, auf dem die Anwendung tatsächlich lauscht, kann von jedem auf dem Host veröffentlichten Port abweichen. Lesen Sie den Listener im Container, statt anzunehmen, dass beide Nummern übereinstimmen.

Die Erlaubnis gehört auf den Forward-Pfad

Der VPN-Container braucht IP-Forwarding und eine Forwarding-Entscheidung, die auf den Client-Pool, die Anwendungsadresse und den vorgesehenen Port begrenzt ist. Bestätigte Antworten brauchen ihre eigene Erlaubnis. Eine Regel, die auf die ursprüngliche Tunneladresse passt, passt nach DNAT nicht mehr, weil das Ziel bereits geändert ist. Eine INPUT-Erlaubnis ist der falsche Haken für Verkehr, der nicht mehr an diesen Host adressiert ist.

Halten Sie den Umfang eng: ein Quellbereich, ein Ziel, ein Dienst. Eine großzügige Forward-Regel ist leichter zu schreiben und später viel schwerer zu verteidigen.

docker exec vpn-container ip route get 192.0.2.3
docker exec vpn-container iptables -t nat -S
docker exec vpn-container iptables -S FORWARD

Dockers Ketten sind nicht die Ketten Ihres Containers

Regeln im Namespace des Containers sind nicht die Regeln des Docker-Hosts. Wenn Verkehr von der Tunnel-Schnittstelle zur Bridge wechselt, kann die Bridge-Firewall des Hosts eine andere Entscheidung treffen. Beim iptables-Backend von Docker sind die dokumentierten Forward-Ketten und die Match-Punkte nach DNAT die Stelle, an der diese Entscheidung auftaucht.

Die Docker-Firewall-Referenz beschreibt diese Ketten und den Abgleich nach DNAT. Beheben Sie eine fehlende Freigabe nicht, indem Sie Dockers Firewall-Verwaltung abschalten oder jede Kette großzügig machen, denn das entfernt die Grenze, die Sie nutzen wollen.

Machen Sie den Rückweg zu einer bewussten Wahl

Bleibt die Quelladresse erhalten, sieht die Anwendung 10.90.0.x und muss Antworten über den VPN-Container zurückleiten. Sonst schickt ihr gewöhnliches Docker-Gateway sie an den Host, dem der Tunnel nicht gehört. Die Alternative ist eine eng begrenzte Quellübersetzung am VPN-Container, die die Antwort vereinfacht, aber den Client vor der Anwendung verbirgt. Wählen Sie bewusst und schreiben Sie auf, wofür Sie sich entschieden haben.

Testen Sie eine neue erlaubte Verbindung von einem gewöhnlichen Client und bestätigen Sie dann, dass unbeteiligte Ports geschlossen bleiben. Wenn ein Paket verschwindet, prüfen Sie den VPN-Namespace, den Namespace der Anwendung und das eigene Log der Anwendung. Ein Ping auf das Bridge-Gateway ist kein Abnahmetest für den Dienst.

Halten Sie die Regeln in der unterstützten Startkonfiguration des Containers, denn interaktive Änderungen verschwinden, wenn er neu erstellt wird. Die Veröffentlichung eines Host-Ports ist ein anderer Expositionsweg und nicht nötig, nur weil der Dienst über den Tunnel erreichbar ist.

Ähnliche Artikel