IPTables (ufw) und Docker – Zwei Feinde
Docker ist eine Erleichterung was das deployen von Anwendungen angeht. – Gerade wenn es um Anwendungen für das Web geht, die oft viele Bibliotheken mit sich bringen.
Doch leider ist es teilweise nicht möglich, Docker-Container per IPTables bzw. UFW zu regulieren und bestimmte Ports zu sperren.
Gerade das ist teilweise in vielen Firmen ein hoher Sicherheitsaspekt. – Natürlich greift hier noch eine firmenweite Firewall und würde zumindest den Datenverkehr von außen blockieren, dennoch bleibt der Dienst im internen Netzwerk aufrufbar.
Selbst mit dem aktiven Blockieren (nicht nur default deny-Regel), lässt sich keine Wirkung auf Docker-Container erzielen.
Das liegt daran, das Docker eine eigene Netzwerkbrücke hat und somit Regeln für Docker selbst erstellt werden müssten. Die IPTables und EB-Tables Regeln sind separat.
Viele im Internet geben die Möglichkeit, das Docker eigene IPTables zu deaktivieren und somit stadtessen auf die systemweite Firewall hören zu lassen.
Leider birgt das viele Probleme mit sich und kann zu weiteren Komplikationen führen, die das ganze noch komplizierter machen.
Ich werde im folgenden auf zwei Lösungen eingehen, die sich für mich als würdig erwiesen haben.
Lösung 1: Docker-Container auf localhost verbannen
Docker Container lauschen ohne die Port-Forwarding Konfiguration standardmäßig auf gar nichts.
Um ein Publish bzw. Forwarding einzurichten ist die Option -p bzw. –publish nötig.
Dahinter folgt dann mit einem Leerzeichen zunächst der Host-Port und danach der Container-Port.
Für einen simplen NGINX-Webserver wäre die Option vermutlich -p 80:80.
Um nun die Zugriffe auf den eigenen PC bzw. Server zu begrenzen (also auf den Local-Host), lässt sich einfach im Host-Anteil des publish’s die Adresse 127.0.0.1 hinzufügen.
Beispiel wieder bei NGINX: -p 127.0.0.1:80:80.
Selbstverständlich lässt sich hier jegliche IP-Adresse einfügen, die an dem Host ankommt. Hat man also beispielsweise zwei Netzwerk-Interfaces lässt sich hiermit beschränken welches Interface den Publish erhält.
Tipp: Wenn beispielweise 3 Interface vorliegen, ein Wireguard-Interface und 2 Netzwerkkarten, lässt sich das ganze auch auf beide Karten erweitern, um es nicht auf dem Wireguard-Interface zu publishen.
Dafür fügt man eine weitere publish-Option (-p) hinzu und fügt hier die andere Adresse ein. Ein Container-Port lässt sich also auf mehrere Host-Ports und Host-IPs übertragen!
Lösung 2: Docker-Container mit UFW einschränken
Die Lösung besteht darin, die UFW-Konfiguration anzupassen, um sicherzustellen, dass die Docker-Container und das externe Netzwerk ordnungsgemäß miteinander interagieren können, während gleichzeitig die Sicherheit gewährleistet wird.
Öffnen Sie dazu die UFW-Konfigurationsdatei /etc/ufw/after.rules und fügen Sie am Ende die folgenden Regeln hinzu:
# BEGIN UFW AND DOCKER *filter :ufw-user-forward - [0:0] :DOCKER-USER - [0:0] -A DOCKER-USER -j RETURN -s 10.0.0.0/8 -A DOCKER-USER -j RETURN -s 172.16.0.0/12 -A DOCKER-USER -j RETURN -s 192.168.0.0/16 -A DOCKER-USER -j ufw-user-forward -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16 -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8 -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12 -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16 -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8 -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12 -A DOCKER-USER -j RETURN COMMIT # END UFW AND DOCKER
Nachdem Sie diese Regeln hinzugefügt haben, führen Sie den Befehl sudo systemctl restart ufw
aus, um die UFW mit den neuen Konfigurationen zu aktualisieren.
Mit dieser Lösung können Docker-Container und das externe Netzwerk effizient und sicher kommunizieren, ohne dass dabei die Sicherheit der Systeme beeinträchtigt wird und iptables deaktiviert wird.
Danach lässt sich nun Docker mittels ufw/iptables einschränken bzw „kontrollieren“.
Vielen Dank fürs lesen!