Looking for docker Keywords? Try Ask4Keywords

DockerIptables con Docker


Introducción

Este tema trata sobre cómo limitar el acceso a sus contenedores de la ventana acoplable desde el mundo exterior utilizando iptables.

Para las personas impacientes, puedes consultar los ejemplos. Para los demás, lea la sección de comentarios para comprender cómo crear nuevas reglas.

Sintaxis

  • iptables -I DOCKER [REGLA ...] [ACCEPT | DROP] // Para agregar una regla a la parte superior de la tabla DOCKER
  • iptables -D DOCKER [REGLA ...] [ACCEPT | DROP] // Para eliminar una regla de la tabla DOCKER
  • ipset restore </etc/ipfriends.conf // Para reconfigurar los ipset ipfriends

Parámetros

Parámetros Detalles
ext_if Su interfaz externa en el host Docker.
XXX.XXX.XXX.XXX Se debe dar una IP particular a la cual los contenedores de Docker acceden.
YYY.YYY.YYY.YYY Se debe proporcionar otra IP a la que accedan los contenedores Docker.
ipfriends El nombre del conjunto de ipsets que define las direcciones IP permitidas para acceder a sus contenedores de Docker.

Observaciones

El problema

Configurar las reglas de iptables para los contenedores Docker es un poco complicado. Al principio, usted pensaría que las reglas de firewall "clásicas" deberían hacer el truco.

Por ejemplo, supongamos que ha configurado un contenedor nginx-proxy + varios contenedores de servicio para exponer a través de HTTPS algunos servicios web personales. Entonces, una regla como esta debería dar acceso a sus servicios web solo para IP XXX.XXX.XXX.XXX.

$ iptables -A INPUT -i eth0 -p tcp -s XXX.XXX.XXX.XXX -j ACCEPT
$ iptables -P INPUT DROP

No funcionará, sus contenedores siguen siendo accesibles para todos.

De hecho, los contenedores Docker no son servicios de host. Se basan en una red virtual en su host, y el host actúa como una puerta de enlace para esta red. Y con respecto a las puertas de enlace, el tráfico enrutado no se maneja con la tabla INPUT, sino con la tabla FORWARD, que hace que la regla publicada antes sea inefectiva.

Pero no es todo. De hecho, el demonio Docker crea muchas reglas de iptables cuando comienza a hacer su magia con respecto a la conectividad de la red de contenedores. En particular, se crea una tabla DOCKER para manejar las reglas relativas a los contenedores al reenviar el tráfico de la tabla FORWARD a esta nueva tabla.

$ iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-ISOLATION  all  --  anywhere             anywhere
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (2 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             172.18.0.4           tcp dpt:https
ACCEPT     tcp  --  anywhere             172.18.0.4           tcp dpt:http

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

La solución

Si verifica la documentación oficial ( https://docs.docker.com/v1.5/articles/networking/) , se ofrece una primera solución para limitar el acceso del contenedor Docker a una IP particular.

$ iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP

De hecho, agregar una regla en la parte superior de la tabla DOCKER es una buena idea. No interfiere con las reglas configuradas automáticamente por Docker, y es simple. Pero faltan dos grandes:

  • Primero, ¿qué sucede si necesita acceder desde dos IP en lugar de una? Aquí solo se puede aceptar un src IP, el otro se eliminará sin ninguna forma de evitarlo.
  • En segundo lugar, ¿qué pasa si su docker necesita acceso a Internet? Prácticamente ninguna solicitud tendrá éxito, ya que solo el servidor 8.8.8.8 podría responder a ellos.
  • Por último, ¿y si quieres añadir otras lógicas? Por ejemplo, dé acceso a cualquier usuario a su servidor web que sirve en el protocolo HTTP, pero limite todo lo demás a una IP particular.

Para la primera observación, podemos usar ipset . En lugar de permitir una IP en la regla anterior, permitimos todas las IP desde el conjunto de datos predefinido. Como beneficio adicional, el ipset se puede actualizar sin la necesidad de redefinir la regla de iptable.

$ iptables -I DOCKER -i ext_if -m set ! --match-set my-ipset src -j DROP

Para la segunda observación, este es un problema canónico para los firewalls: si se le permite comunicarse con un servidor a través de un firewall, entonces el firewall debe autorizar al servidor a responder a su solicitud. Esto se puede hacer mediante la autorización de paquetes que están relacionados con una conexión establecida. Para la lógica docker, da:

$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT

La última observación se centra en un punto: las reglas de iptables son esenciales. De hecho, la lógica adicional para ACEPTAR algunas conexiones (incluida la que concierne a las conexiones ESTABLECIDAS) debe colocarse en la parte superior de la tabla DOCKER, antes de la regla DROP que niega todas las conexiones restantes que no coincidan con el conjunto de cambios.

Como usamos la opción -I de iptable, que inserta reglas en la parte superior de la tabla, las reglas de iptables anteriores deben insertarse en orden inverso:

// Drop rule for non matching IPs
$ iptables -I DOCKER -i ext_if -m set ! --match-set my-ipset src -j DROP
// Then Accept rules for established connections
$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT 
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 3rd custom accept rule
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 2nd custom accept rule
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 1st custom accept rule

Con todo esto en mente, ahora puede consultar los ejemplos que ilustran esta configuración.

Iptables con Docker Ejemplos relacionados