Wer auf einem Server die Kombination von Docker und ufw (uncomplicated firewall) einsetzt, hat vielleicht schon bemerkt, dass Docker geöffnete Ports durch eine entsprechende iptables-Regel automatisch auch “nach Außen” öffnet und dabei die ufw komplett umgeht.

Dieses Verhalten lässt sich glücklicherweise abstellen, erfordert aber anschließend weitere Einstellungen an der ufw.

Hinweis: Alternativ zu dem im Anschluss beschriebenen Vorgehen können Ports beim Erzeugen des Containers auch explizit an 127.0.0.1 gebunden werden und sind damit nur noch auf dem jeweiligen Host selbst erreichbar.
Um z.B. den Container-Port 80 an den Host-Port 8080 zu binden, muss der docker run-Aufruf folgendermaßen gestaltet werden:

docker run [...] -p 127.0.0.1:8080:80 [...]

Docker

Um den Zugriff auf die iptables-Regeln abzustellen, reicht es aus, die Datei /etc/docker/daemon.json mit folgendem Inhalt anzulegen und den Service neuzustarten.

{
    "iptables": false
}
systemctl restart docker.service

ufw

Nach einem Neustart können die Docker-Container nun nicht mehr untereinander kommunizieren oder auf das Internet zugreifen.
Daher müssen zwei Dateien der ufw angepasst werden:

In der /etc/default/ufw-Datei muss Zeile 19 folgendermaßen verändert werden:

DEFAULT_FORWARD_POLICY="ACCEPT"

Außerdem müssen die nachfolgenden Zeilen an das Ende der /etc/ufw/after.rules-Datei angefügt werden.
Verifizieren Sie vorher mittels ip addr den Namen des Interfaces (docker0) und den Netzbereich (172.17.0.0/16).

*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE
COMMIT

Anschließend muss auch die ufw neugestartet werden:

systemctl restart ufw.service

Abschluss

Prüfen Sie nun die Netzwerkeinstellungen auf korrekte Funktion:

  • Sind “von Außen” keine eigentlich geschlossenen Ports erreichbar?
  • Können die Container intern noch miteinander kommunizieren?
  • Können die Container das Internet erreichen?
  • Können geöffnete Ports der Container vom Host erreicht werden?