Docker, dans son comportement par défaut modifie et ajoute des règles iptables pour permettre le bon fonctionnement et la bonne communication réseau entre les containers et l’extérieur. Ce qui peut porter préjudice si vous ne vous souciez pas de cette configuration du firewall. Voici comment procéder pour protéger l’accès à vos containers depuis l’extérieur avec UFW. Nous avions déjà abordé le sujet UFW dans certains articles sur le sujet, et sur le firewall linux.

bldwebagency-watch-folder-for-new-files-docker-linux

Comment Docker gère les flux réseaux entre l’hôte et les containers

Par défaut, Docker modifie les règles iptables sur l’hôte pour permettre le bon fonctionnement des conteneurs et la communication réseau. Il crée une chaîne spécifique appelée DOCKER dans les tables de filtrage (filter) et de nat (nat) d’iptables. Cette chaîne est utilisée pour gérer les règles de filtrage et de NAT des conteneurs. Il ajoute également des règles pour router les paquets entre les conteneurs et entre les conteneurs et l’extérieur :

  • Règles NAT (Masquerading) : Docker ajoute des règles pour faire du masquerading (NAT) afin de permettre aux conteneurs d’atteindre l’extérieur via l’adresse IP de l’hôte.
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
  • Forwarding des paquets : Docker permet le forwarding des paquets entre les interfaces Docker et les interfaces réseau de l’hôte.
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT

Lorsque vous exposez des ports de conteneurs (avec l’option -p ou --publish), Docker ajoute des règles pour rediriger le trafic de ces ports de l’hôte vers les ports du conteneur. Par exemple, si vous exposez le port 80 du container sur le port 8080 de l’hôte, voici les règles iptables ajoutées :

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A DOCKER -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80

Par défaut, Docker modifie automatiquement les règles iptables pour faciliter la communication réseau des conteneurs et permettre des fonctionnalités telles que le NAT et le port forwarding. Cependant, cela peut introduire des risques de sécurité si les règles ne sont pas bien contrôlées, car Docker expose automatiquement les ports et permet la communication entre l’hôte et les conteneurs.

UFW : le gestionnaire simplifié de règles iptables

UFW (Uncomplicated Firewall) est un outil simplifié pour la gestion des règles de pare-feu sur les systèmes Linux, en particulier ceux basés sur Debian et Ubuntu. Il sert de front-end à iptables, offrant une interface plus intuitive pour les utilisateurs moins familiers avec la gestion des pare-feu en ligne de commande.

Pour l’installer, rien de plus simple :

sudo apt-get update && sudo apt-get install ufw

Configuration initiale de UFW

Pour s’assurer que tout soit OK lorsque nous allons recharger UFW, veuillez vous assurer d’ouvrir tous les ports nécessaires vers l’extérieur. Nous commençons par refuser les accès depuis l’extérieur et autoriser les accès vers l’extérieur :

ufw default deny incoming
ufw default allow outgoing

Ensuite, nous allons ouvrir quelques flux indispensables (pensez à adapter cette configuration à vos usages) :

ufw allow OpenSSH # Ouvrir l'accès à SSH sur le port 22
ufw allow NginxFull # Ouvrir l'accès aux ports 80 et 443 pour Nginx
ufw allow from 1.1.1.1 proto tcp to any port 9100 # Ouvrir l'accès à NodeExporter pour l'IP 1.1.1.1
ufw allow 50000:50100/tcp # Ouvrir un range d'IP pour l'accès aux mode passif de ProftpD

Lorsque toutes vos règles sont prêtes, rechargez UFW :

ufw reload

Comment protéger l’accès à ses containers Docker depuis l’extérieur sans iptables

Plusieurs solutions sont envisageable pour éviter que tous les containers soient exposés depuis l’extérieur :

  • Solution radicale : empêcher docker de gérer ses règles iptables avec un paramètre dans le fichier /etc/docker/daemon.json :
{
  "iptables" : false
}
  • Solution plus souple : adapter la configuration iptables pour forcer docker à passer derrière vos règles UFW

Vous allez devoir ajouter à la fin du fichier /etc/ufw/after.rules le contenu suivant en remplaçant eth0 par le nom de votre interface réseau externe :

# Put Docker behind UFW
*filter
:DOCKER-USER - [0:0]
:ufw-user-input - [0:0]

-A DOCKER-USER -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A DOCKER-USER -m conntrack --ctstate INVALID -j DROP
-A DOCKER-USER -i eth0 -j ufw-user-input
-A DOCKER-USER -i eth0 -j DROP
COMMIT

Enfin, rechargez UFW pour appliquer les changements :

ufw reload

Désormais, les règles UFW sont prioritaires sur celles générées automatiquement par Docker. Vous pourrez donc ouvrir les flux nécessaires avec UFW sans vous soucier de failles de sécurités importantes via des règles iptables un peu trop larges.

Sources