Mon objectif est de limiter l'accès aux conteneurs Docker à seulement quelques adresses IP publiques. Existe-t-il un processus simple et reproductible pour atteindre mon objectif? Comprendre uniquement les bases d'iptables lors de l'utilisation des options par défaut de Docker, je trouve cela très difficile.
Je voudrais exécuter un conteneur, le rendre visible sur Internet public, mais autoriser uniquement les connexions à partir d'hôtes sélectionnés. Je m'attendrais à définir une politique d'entrée par défaut de REJET et à n'autoriser que les connexions de mes hôtes. Mais les règles et chaînes NAT de Docker se mettent en travers et mes règles INPUT sont ignorées.
Quelqu'un peut-il fournir un exemple de la façon d'atteindre mon objectif compte tenu des hypothèses suivantes?
- Hôte IP publique 80.80.80.80 sur eth0
- Hôte IP privé 192.168.1.10 sur eth1
docker run -d -p 3306:3306 mysql
- Bloquer toute connexion à l'hôte / conteneur 3306 sauf à partir des hôtes 4.4.4.4 et 8.8.8.8
Je suis heureux de ne lier le conteneur qu'à l'adresse IP locale, mais j'aurais besoin d'instructions sur la façon de configurer correctement les règles de transfert iptables qui survivent au processus de docker et aux redémarrages de l'hôte.
Merci!
--ctdir
? J'utilise-m conntrack --ctstate NEW --ctorigdstport 3306 --ctdir ORIGINAL
DOCKER-USER
tableau par défaut contient l'entrée:-A DOCKER-USER -j RETURN
qui s'exécutera avant ce qui précède si vous utilisez-A
. Une solution consiste à insérer les règles en tête dans l'ordre inverse avec-I
.FILTERS
chaîne, et-I
insérez de nouvelles règles (comme vous l'avez dit), pour y-I INPUT -j FILTERS
-I DOCKER-USER -i eth0 -j FILTERS
-I
cependant, juste pour être sûr.Avec Docker v.17.06, il existe une nouvelle chaîne iptables appelée DOCKER-USER. Celui-ci est pour vos règles personnalisées: https://docs.docker.com/network/iptables/
Contrairement à la chaîne DOCKER, elle n'est pas réinitialisée lors de la construction / démarrage des conteneurs. Vous pouvez donc ajouter ces lignes à votre configuration / script iptables pour provisionner le serveur avant même d'installer Docker et de démarrer les conteneurs:
Maintenant, le port pour MySQL est bloqué de l'accès externe (eth0), même si docker ouvre le port pour le monde. (Ces règles supposent que votre interface externe est eth0.)
Finalement, vous devrez d'abord nettoyer iptables, redémarrer le service docker, si vous l'avez trop gâché en essayant de verrouiller le port comme je l'ai fait.
la source
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION
c'est pourquoi, les instructions personnalisées sont exécutées avant la chaîne DOCKER.--dport
DOCKER-USER, cela doit correspondre à l' IP interne du service de conteneur, pas au port exposé. Celles-ci correspondent souvent mais pas toujours et cela pourrait facilement entrer en conflit avec d'autres services, donc je soutiens toujours que cette solution DOCKER-USER est à moitié cuite.MISE À JOUR : Bien que valide en 2015, cette solution n'est plus la bonne façon de le faire.
La réponse semble être dans la documentation de Docker à https://docs.docker.com/articles/networking/#the-world
J'ai fini par faire:
Je n'ai pas touché aux options
--iptables
ou--icc
.la source
iptables -vnL DOCKER
, les ports de destination sont tous les ports du conteneur. Si je comprends bien, cela signifie que les règles ci-dessus n'affecteraient que le port3306
dans le conteneur - c'est-à-dire que si vous étiez dans-p 12345:3306
votre conteneur, votre règle serait toujours celle requise pour verrouiller l'accès (c'est--dport 12345
-à- dire ne fonctionnerait pas) , car les règles ACCEPT de la chaîne DOCKER sont post-NAT.--iptables=false
, car cela semble être le pire choix de tous.MISE À JOUR: Bien que cette réponse soit toujours valide, la réponse de @SystemParadox
DOCKER-USER
en combinaison avec--ctorigdstport
est meilleure.Voici une solution qui persiste bien entre les redémarrages et vous permet d'affecter le port exposé plutôt que le port interne .
iptables -t mangle -N DOCKER-mysql iptables -t mangle -A DOCKER-mysql -s 22.33.44.144/32 -j RETURN iptables -t mangle -A DOCKER-mysql -s 22.33.44.233/32 -j RETURN iptables -t mangle -A DOCKER-mysql -j DROP iptables -t mangle -A PREROUTING -i eth0 -p tcp -m tcp --dport 3306 -j DOCKER-mysql
J'ai construit une image Docker qui utilise cette méthode pour gérer automatiquement les iptables pour vous, en utilisant soit des variables d'environnement, soit dynamiquement avec etcd (ou les deux):
https://hub.docker.com/r/colinmollenhour/confd-firewall/
la source