Le pare-feu simple (UFW) ne bloque rien lorsque vous utilisez Docker

44

C’est la première fois que je configure un serveur Ubuntu (14.04 LTS) et j’ai des problèmes pour configurer le pare-feu (UFW).

J'ai seulement besoin sshet http, alors je fais ceci:

sudo ufw disable

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp

sudo ufw enable
sudo reboot

Mais je peux toujours me connecter à des bases de données sur d'autres ports de cette machine . Une idée de ce que je fais mal?

EDIT : ces bases de données sont sur des conteneurs Docker. Cela pourrait-il être lié? est-ce que cela remplace ma configuration ufw?

EDIT2 : sortie desudo ufw status verbose

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)
ESala
la source
quelle base de données? quel port? Êtes-vous sûr que c'est la même machine? quel est le résultat de ufw status
solsTiCe
@solsTiCe Oui, je suis sûr que c'est la même machine. La base de données est InfluxDB (sur un conteneur Docker) avec les ports 8083et 8086. J'ai ajouté le ufw status verboserésultat dans la question. Merci.
ESala

Réponses:

64

Le problème consistait à utiliser le -pdrapeau sur les conteneurs.

Il se trouve que Docker apporte des modifications directement sur votre ordinateur iptables, qui ne sont pas affichées avec ufw status.

Les solutions possibles sont:

  1. Arrêtez d'utiliser le -pdrapeau. Utilisez plutôt une liaison ou des réseaux avec un menu fixe .

  2. Liez les conteneurs localement afin qu'ils ne soient pas exposés en dehors de votre machine:

    docker run -p 127.0.0.1:8080:8080 ...

  3. Si vous insistez pour utiliser le -pdrapeau, dites à docker de ne pas le toucher iptablesen le désactivant /etc/docker/daemon.jsonet en le redémarrant:

    { "iptables" : false }

Je recommande les options 1 ou 2. Attention, l'option 3 a des effets secondaires , comme l'impossibilité pour les conteneurs de se connecter à Internet.

ESala
la source
8
C'est tellement utile - je devenais folle de pouvoir accéder à des ports que je n'avais pas autorisés dans ufw. Cependant, utiliser iptables = false casse beaucoup, comme les conteneurs devenant accessibles sur localhost, par exemple pour le proxy inverse. Mieux vaut vous assurer que le conteneur écoute correctement, n'utilisez pas -p 80:80, mais utilisez -p 127.0.0.1:80:80 ou un port différent, comme 127.0.0.1:3000:80, pour le proxy inverse avec nginx ou apache et sans port. affrontements.
Andreas Reiff
2
@AndreasReiff, vous avez raison, mais dernièrement, j'ai jugé préférable d'éviter -pautant que possible. Par exemple, dans le cas d'un proxy inverse, je ne mappe aucun port pour les conteneurs de travail, puis mets nginx dans son propre conteneur avec -p 80:80et --linkvers les autres. De cette façon, il ne peut y avoir d’affrontements de ports et le seul point d’accès est nginx.
ESala
1
Vérifiez également ce poste pour une troisième précaution que vous devez prendre! svenv.nl/unixandlinux/dockerufw
Henk
1
Important : /etc/default/dockerest un fichier de configuration utilisé par la configuration upstart. Si vous êtes passé de upstart à systemd, ce fichier ne sera pas utilisé.
Orshachar
@ESala Vous devriez penser à dé-marquer cette réponse comme étant correcte car elle est datée.
ctbrown
8

16.04 présente de nouveaux défis. J'ai exécuté toutes les étapes comme indiqué. Running Docker derrière le pare-feu ufw MAIS je ne pouvais PAS faire en sorte que docker plus UFW fonctionne le 16.04. En d'autres termes, peu importe ce que j'ai fait, tous les ports de docker sont devenus globalement exposés à Internet. Jusqu'à ce que j'ai trouvé ceci: Comment configurer Docker 1.12+ pour qu'il n'interfère pas avec IPTABLES / FirewallD

Je devais créer le fichier /etc/docker/daemon.jsonet mettre ce qui suit dans:

{
    "iptables": false
}

Je me suis alors émis sudo service docker stopalors sudo service docker startENFIN docker est tout simplement en suivant les règles appropriées dans UFW.

Données supplémentaires: Docker annule UFW!

Hal Jordan
la source
Avec Ubuntu 16.04 et Docker version 17.09, cette solution rompt la connexion sortante des conteneurs. Voir les réponses askubuntu.com/a/833363/262702 et askubuntu.com/a/954041/262702
ctbrown
5

Si vous utilisez le système init de systemd (Ubuntu 15.10 et versions ultérieures) et modifiez-le /etc/docker/daemon.json(vous devrez peut-être le créer s'il n'existe pas), assurez-vous qu'il a la iptablesclé configurée:

{   "iptables" : false }

EDIT : cela pourrait vous faire perdre la connexion à Internet à partir de conteneurs internes

Si vous avez activé UFW, vérifiez que vous pouvez accéder à Internet à partir de conteneurs. sinon - vous devez définir DEFAULT_FORWARD_POLICYcomme ACCEPTsur /etc/default/ufwet appliquer l'astuce décrite ici: https://stackoverflow.com/a/17498195/507564

Orshachar
la source
2

Une solution rapide consiste à exécuter Docker et à mapper les ports. Tu peux toujours faire

docker run ...-p 127.0.0.1:<ext pot>:<internal port> ...

pour empêcher l'accès à votre Docker de l'extérieur.

Kimy82
la source
2

Utilisation du /etc/docker/daemon.jsoncontenu

{
  "iptables": false
}

Cela peut sembler être une solution, mais cela ne fonctionne que jusqu'au prochain redémarrage . Après cela, vous remarquerez peut-être qu'aucun de vos conteneurs n'a accès à Internet. Vous ne pouvez par exemple pas envoyer de requête ping à un site Web. Ce peut être un comportement indésirable.

La même chose s'applique à la liaison d'un conteneur à une adresse IP spécifique. Vous ne pouvez pas vouloir faire ça. L'option ultime consiste à créer un conteneur et à le placer derrière UFW, peu importe ce qui se passe et comment vous créez ce conteneur. Il existe donc une solution:

Après avoir créé le /etc/docker/daemon.jsonfichier, appelez:

sed -i -e 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/g' /etc/default/ufw
ufw reload

vous devez donc configurer la politique de transfert par défaut dans UFW pour accepter et utiliser:

iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE

Si vous êtes sur le point d'utiliser Docker-Compose, la commande IP de ci-dessus doit être remplacée par l'IP du réseau créé par Docker-Compose lors de son exécution docker-compose up.

J'ai décrit le problème et la solution de manière plus complète dans cet article

J'espère que ça aide!

Mkubaczyk
la source
1

Dans mon cas, j'ai fini par modifier iptables pour permettre l'accès à Docker uniquement à partir d'adresses IP spécifiques.

Selon la réponse de ESala :

Si vous utilisez -pflag sur les conteneurs, Docker modifie directement iptables en ignorant les ufw.

Exemple d'enregistrements ajoutés à iptables par Docker

Routage vers la chaîne 'DOCKER':

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

Envoi de paquets de la chaîne 'DOCKER' au conteneur:

-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 6379 -j DNAT --to-destination 172.17.0.3:6379

Vous pouvez modifier iptables pour autoriser l'accès à la chaîne DOCKER uniquement à partir de l'adresse IP source spécifiée (par exemple 1.1.1.1):

-A PREROUTING -s 1.1.1.1 -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT -s 1.1.1.1 ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

Vous voudrez peut-être utiliser iptables-save > /tmp/iptables.confet iptables-restore < /tmp/iptables.confvider, éditer et restaurer les règles iptables.

Mécanicien d'IA
la source
0

Utilisez --network = host lorsque vous démarrez un conteneur afin que docker mappe le port sur un réseau uniquement hôte isolé au lieu du réseau de pont par défaut. Je ne vois aucun moyen légal de bloquer un réseau ponté. Vous pouvez également utiliser un réseau personnalisé défini par l'utilisateur avec isolation.

le codeur
la source
0
  1. Connectez-vous à votre console de docker:

    sudo docker exec -i -t nom_image_stockeur / bin / bash

  2. Et ensuite dans votre console de docker:

    sudo apt-get update
    sudo apt-get install ufw
    sudo ufw allow 22
    
  3. Ajoutez vos règles ufw et activez ufw

    sudo ufw enable

    • Votre image Docker doit être démarrée avec --cap-add = NET_ADMIN

Pour activer l'option "NET_ADMIN" de Docker:

1.Stop Container:

docker arrêter votre conteneur; Identifiant du conteneur 2.Get:

docker inspecter votre conteneur; 3. Modifiez hostconfig.json (chemin d'accès au menu fixe par défaut: / var / lib / docker, vous pouvez modifier le vôtre).

vim /var/lib/docker/containers/containerid/hostconfig.json

4.Recherchez "CapAdd" et modifiez null en ["NET_ADMIN"];

...., "VolumesFrom": null, "CapAdd": ["NET_ADMIN"], "CapDrop": null, .... 5.Redémarrez le menu fixe dans la machine hôte;

redémarrage du docker de service; 6.Démarrez yourconatiner;

docker démarrer votre conteneur;

Stefan
la source
0

J'avais l'habitude docker-composede démarrer plusieurs conteneurs et le problème était qu'un port était exposé au monde ignorant les règles ufw.

Le correctif pour rendre le port disponible uniquement à mes conteneurs Docker était ce changement dans mon docker-compose.ymlfichier:

ports:
- "1234:1234"

pour ça:

ports:
- "1234"

Maintenant, les autres conteneurs Docker peuvent toujours utiliser le port, mais je ne peux pas y accéder de l'extérieur.

TmTron
la source