Docker absichern mit firewalld

  Lioh Möller   Lesezeit: 5 Minuten  🗪 2 Kommentare

Mithilfe eigener Regelwerke lässt sich der Zugriff auf Docker Container über firewalld einschränken.

docker absichern mit firewalld

Auf einem System, auf dem Docker zusammen mit firewalld zum Einsatz kommt, werden standardmässig alle Ports, welche von einem Container exposed werden, in der Firewall zugänglich gemacht.

Dies erleichtert die Konfiguration, in einigen Fällen kann es jedoch notwendig sein, den Zugriff auf bestimmte Quellen zu beschränken. Im folgenden Beispiel soll ein in Docker laufender nginx Webserver aus dem lokalen Netzwerk 192.168.1.0/24 auf Port 80 und 443 erreichbar gemacht werden.


Zur initialen Konfiguration muss docker beendet werden:

systemctl stop docker.socket
systemctl stop docker.service


Daraufhin kann die DOCKER-USER Firewall chain neu erstellt werden. Sollte dabei eine Warnmeldung ausgegeben werden, kann diese ignoriert werden:

firewall-cmd --permanent --direct --remove-chain ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --remove-rules ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER-USER

Nun können einige grundlegende Regelwerke zur DOCKER-USER chain hinzugefügt werden. Zunächst soll es den laufenden Containern ermöglicht werden, nach aussen zu kommunizieren:

firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment 'Allow containers to connect to the outside world'

Docker richtet für die interne Kommunikation ein eigenes, privates Netzwerk ein. Ein Zugriff aus diesem Netz und vom Loopback Device aus sollte ebenfalls gestattet werden.

firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 1 \
  -j RETURN \
  -s 127.0.0.0/8 \
  -m comment --comment 'allow internal docker communication, loopback addresses'
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 1 \
  -j RETURN \
  -s 172.16.0.0/12 \
  -m comment --comment 'allow internal docker communication'

Nach der Basiseinrichtung können die eigentlichen Zugriffsregeln erstellt werden. Diese werden vorrangig mit 1 eingeordnet (DOCKER-USER 1) und weitere Regelwerke können auch zu einem späteren Zeitpunkt, mit DOCKER-USER 0 darüber zur Kette hinzugefügt werden.

firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 1 \
  -j RETURN \
  -p tcp -m multiport \
  --dports 80,443 -s 192.168.1.0/24 \
  -m comment \
  --comment 'Allow 192.168.1.0/24 to access http and https docker ports'

Abschliessend werden alle anderen Zugriffsversuche blockiert:

firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 10 \
  -j REJECT -m comment --comment 'reject all other traffic to DOCKER-USER'

Damit die Änderungen aktiviert werden, muss firewalld neu geladen werden:

firewall-cmd --reload

Nun kann der Docker Dienst wieder gestartet werden:

systemctl start docker.socket
systemctl start docker.service


Der Zugriff sollte ab diesem Zeitpunkt an, nur noch von dem angegebenen Netz aus möglich sein.

Mit folgendem Befehl können die erstellten direct Rules ausgegeben werden:

firewall-cmd --direct --get-all-rules

Auch zu einem späteren Zeitpunkt können beliebige weitere Regeln hinzugefügt werden. Im folgenden Beispiel wird dem Netz 192.168.2.0/24 der Zugriff auf Port 80 gestattet.

firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 1 \
  -j RETURN \
  -p tcp  \
  --dport 80 -s 192.168.2.0/24 -j ACCEPT \
  -m comment \
  --comment 'Allow 192.168.2.0/24 to access http docker port'

Die Änderungen werden mithilfe von firewall-cmd --reload aktiviert.

Grundsätzlich ist zu beachten, dass als Zielport der Port im laufenden Container angegeben werden muss, und nicht der Exposed Port.

Sollte es bei der Einrichtung zu Fehlern kommen, kann man temporär die Protokollierung auf der DOCKER-USER chain aktivieren:

firewall-cmd --direct --add-rule ipv4 filter DOCKER-USER 0 \
  -j LOG --log-prefix ' DOCKER TCP: '

Standardmässig werden die Ereignisse im systemd journal protokolliert.

Beim nächsten Aufruf von firewall-cmd --reload wird die Protokollierung wieder deaktiviert.

Quelle: https://roosbertl.blogspot.com/2019/06/securing-docker-ports-with-firewalld.html

Hinweis:

  • direct Rules in firewalld werden als deprecated angesehen, alternativ wird die Verwendung von policies empfohlen, sind allerdings weiterhin der einfachste Weg den Zugriff auf Docker Container zu steuern.
  • Eine ähnliche Konfiguration bei einer Nutzung von ufw, wurde von uns ebenfalls ausführlich dokumentiert.

Tags

firewalld, Docker, Container

miki
Geschrieben von miki am 3. April 2023 um 15:16

Das direct interface ist deprecated und verschwindet aus firewalld. Man sollte das alles mit policies bauen.

Lioh
Geschrieben von Lioh am 3. April 2023 um 15:37

Da hast du wahrscheinlich den Hinweis am Ende überlesen ;) Gerne kannst du den Artikel auf Policies adaptieren und ihn einreichen.