Mi objetivo es limitar el acceso a los contenedores acoplables a solo unas pocas direcciones IP públicas. ¿Existe un proceso simple y repetible para lograr mi objetivo? Al comprender solo los conceptos básicos de iptables al usar las opciones predeterminadas de Docker, me resulta muy difícil.
Me gustaría ejecutar un contenedor, hacerlo visible para el Internet público, pero solo permitir conexiones de hosts seleccionados. Esperaría establecer una política de ENTRADA predeterminada de RECHAZAR y luego solo permitir conexiones desde mis hosts. Pero las reglas y cadenas NAT de Docker se interponen y mis reglas INPUT son ignoradas.
¿Alguien puede proporcionar un ejemplo de cómo lograr mi objetivo teniendo en cuenta los siguientes supuestos?
- Host public IP 80.80.80.80 en eth0
- Host privado IP 192.168.1.10 en eth1
docker run -d -p 3306:3306 mysql
- Bloquee todas las conexiones al host / contenedor 3306 excepto desde los hosts 4.4.4.4 y 8.8.8.8
Me complace vincular el contenedor solo a la dirección IP local, pero necesitaría instrucciones sobre cómo configurar correctamente las reglas de reenvío de iptables que sobrevivan al proceso de acoplamiento y reinicios del host.
¡Gracias!
--ctdir
? Yo uso-m conntrack --ctstate NEW --ctorigdstport 3306 --ctdir ORIGINAL
DOCKER-USER
tabla predeterminada contiene la entrada:-A DOCKER-USER -j RETURN
que se ejecutará antes de lo anterior si la usa-A
. Una solución es insertar reglas en la cabeza en orden inverso con-I
.FILTERS
cadena e-I
inserte nuevas reglas (como usted dijo), para saltar a ella:-I INPUT -j FILTERS
y-I DOCKER-USER -i eth0 -j FILTERS
-I
embargo, es una buena idea usar , solo para estar seguro.Con Docker v.17.06 hay una nueva cadena de iptables llamada DOCKER-USER. Este es para sus reglas personalizadas: https://docs.docker.com/network/iptables/
A diferencia del DOCKER de cadena, no se reinicia al construir / iniciar contenedores. Por lo tanto, puede agregar estas líneas a su configuración / script de iptables para aprovisionar el servidor incluso antes de instalar Docker e iniciar los contenedores:
Ahora el puerto para MySQL está bloqueado de acceso externo (eth0) incluso aunque Docker abre el puerto para el mundo. (Estas reglas suponen que su interfaz externa es eth0.)
Eventualmente, tendrá que limpiar iptables, reinicie el servicio docker primero, si lo desordenó demasiado tratando de bloquear el puerto como lo hice yo.
fuente
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION
es por eso que las instrucciones personalizadas se ejecutan antes que la cadena DOCKER.--dport
dentro de DOCKER-USER, debe coincidir con la IP interna del servicio de contenedor, no con el puerto expuesto. A menudo coinciden, pero no siempre, y esto podría entrar fácilmente en conflicto con otros servicios, por lo que sigo argumentando que esta solución DOCKER-USER está a medias.ACTUALIZACIÓN : aunque es válida en 2015, esta solución ya no es la forma correcta de hacerlo.
La respuesta parece estar en la documentación de Docker en https://docs.docker.com/articles/networking/#the-world
Lo que terminé haciendo fue:
No toqué
--iptables
ni las--icc
opciones.fuente
iptables -vnL DOCKER
, los puertos de destino son todos los puertos dentro del contenedor. Si lo entiendo bien, eso significa que las reglas anteriores solo afectarían el puerto3306
dentro del contenedor, es decir, si estuviera en-p 12345:3306
su contenedor, su regla aún sería la que se requiere para bloquear el acceso (es decir--dport 12345
, no funcionaría) , porque las reglas ACEPTAR de la cadena DOCKER son posteriores a NAT.--iptables=false
, porque esta parece ser la peor opción de todas.ACTUALIZACIÓN: Si bien esta respuesta sigue siendo válida, la respuesta de @SystemParadox
DOCKER-USER
en combinación con--ctorigdstport
es mejor.Aquí hay una solución que persiste bien entre reinicios y le permite afectar el puerto expuesto en lugar del puerto interno .
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
He creado una imagen de Docker que utiliza este método para administrar automáticamente las tablas ip por usted, utilizando variables de entorno o dinámicamente con etcd (o ambos):
https://hub.docker.com/r/colinmollenhour/confd-firewall/
fuente