Kürzlich hatte ich das Problem, dass ein Prozess in einem Docker Container Pakete an eine falsche IP-Adresse schickt: Statt an den Host gingen die Pakete an das Standard Gateway des Bridge Netzwerks. Leider ließ sich die IP-Adresse im Prozess wegen eines Bugs nicht anpassen. Unter Windows funktioniert zudem das Host Netzwerk von Docker nicht richtig. Die einzige Wahl war daher die Umleitung der Pakete an die richtige IP-Adresse.
Möglich ist das durch die Verwendung von iptables
.
Docker nutzt iptables
selbst, um den Netzwerk-Traffic des Containers zu isolieren.
Um selbst Änderungen vorzunehmen, muss das Argument --cap-add=NET_ADMIN
beim Ausführen des Containers hinzugefügt werden.
Anschließend kann folgendes Kommando als root
ausgeführt werden:
iptables -t nat -I OUTPUT 1 -p TCP --destination-port 5432 -j DNAT --to-destination `dig +short host.docker.internal`
Dadurch wird folgendes bewirkt:
In der Tabelle nat
wird in der Chain OUTPUT
an erster Stelle eine Regel hinzugefügt, die alle Pakete betrifft, die an Port 5432
gerichtet sind.
Diese Regel ändert das Ziel des Pakets (DNAT
), indem es auf eine andere IP-Adresse umleitet.
Die IP-Adresse wird hier dynamisch mittels dig
aus dem Hostname host.docker.internal
ermittelt, der wiederum die IP-Adresse des Hosts enthält.
Als Chain muss OUTPUT
und nicht etwa PREROUTING
verwendet werden, weil PREROUTING
nicht auf Pakete zutrifft, die im Container erzeugt werden.
Die Regel muss zudem an die erste Stelle gesetzt werden, damit sie vor den durch Docker hinzugefügten Regeln ausgeführt wird.
Beispielhaft werden hier alle Pakete abgefangen, die an einen bestimmten Port gehen.
Natürlich sind dafür auch andere Kriterien denkbar.
Wichtig: Die IP-Adresse des Hosts kann sich ändern.
Daher wird hier die IP-Adresse aus dem Hostname host.docker.internal
ausgelesen.
Das bedeutet auch, dass das iptables
Kommando bei jedem Start des Containers neu ausgeführt werden muss.
Beim Herunterfahren des Containers werden die Regeln zurückgesetzt, sodass alte Regeln beim erneuten Hochfahren nicht extra gelöscht werden müssen.