Docker con iptables=false
Configurando Docker en nuestro servidor nos dimos cuenta que teníamos un problema, Docker crea por defecto las reglas necesarias en iptables para poder acceder a los contenedores desde todas las interfaces y el resto del universo.
Nosotros tenemos securizadas las conexiones de la máquina con APF, un firewall basado en conjunto de scripts que mediante un fichero de configuración se encarga de generar las reglas de iptables simplificando la tediosa tarea de configuración iptables. A pesar de tener bloqueados los puertos expuestos de los contenedores mediante el firewall, nos dimos cuenta que los puertos estaban expuestos a internet.
Para evitar este problema la mejor solución es desactivar el uso de iptables por parte de Docker. Para ello hay que añadir la configuración iptables=false
al demonio de docker. En nuestro caso como el servidor es Debian hemos tenido que añadir la configuración en formato JSON al fichero /etc/docker/daemon.json
.
# modificamos (o creamos) el fichero de configuración nano /etc/docker/daemon.json # START - Contenido del fichero { "iptables": false } # END - Contenido del fichero # reiniciamos el servicio docker /etc/init.d/docker restart
A partir de este momento cuando se arranque un contenedor los puertos expuestos en la máquina no serán accesibles desde internet.
¡Un problema menos! Genial, nos vemos en la siguiente entrada…. espera, espera… parece que tenemos un problema. Con esta operación hemos perdido la conectividad desde los contedores a internet 🙁.
Conectividad de los contendores a internet
Tenemos un problema pero también la solución, podemos añadir a iptables las reglas necesarias para poder acceder a internet desde los contenedores. Ejecutando los siguientes comandos conseguimos tener conectividad a internet desde los contenedores.
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE iptables -t filter -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i docker0 ! -o docker0 -j ACCEPT iptables -t filter -A FORWARD -i docker0 -o docker0 -j ACCEPT
Si como en nuestro caso utilizas un firewall externo como APF, cada vez que lo recargues las reglas necesarias para Docker se perderán.
En el caso de APF hay una forma de persistir estas reglas, añadiéndolas al fichero /etc/apf/postroute.rules
se ejecutarán justo después de haberse creado todas las reglas generadas por APF.
Añadiendo al final del fichero las siguientes líneas cada vez que arranquemos APF también se cargarán las reglas necesarias por Docker 😀
# editamos el fichero añadiendo al final nano /etc/apf/postroute.rules # START - PEGAR AL FINAL DEL FICHERO iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE iptables -t filter -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i docker0 ! -o docker0 -j ACCEPT iptables -t filter -A FORWARD -i docker0 -o docker0 -j ACCEPT # END - PEGAR AL FINAL DEL FICHERO
Redes personalizadas Docker
En el caso de utilizar redes personalizadas docker para establecer la conectividad de nuestros contenedores tenemos un problema, con la configuración actual no tenemos conectividad a internet. Si queremos tener salida a internet desde estos contenedores, tendremos que añadir una configuración adicional a iptables.
Antes de poder ejecutar las reglas necesitamos saber los rangos IP de estas redes docker personalizadas. En nuestro caso tenemos 2 redes personalizadas de tipo bridge, como todas estas redes comienzan por br-
podemos ejecutar el siguiente comando para ver los rangos de las redes:
# comando basename -a /sys/class/net/* | grep br- | xargs -n 1 ip -f inet addr show | grep -Po 'inet \K[^ ]+' # resultado 172.18.0.1/16 172.19.0.1/16
Con eso podemos ver que en nuestro caso las redes bridge de docker son 172.18.0.1
y 172.19.0.1
. Ahora que sabemos los rangos podemos ejecutar las reglas de iptables:
iptables -t nat -A POSTROUTING -s 172.18.0.0/16 ! -o docker0 -j MASQUERADE iptables -t nat -A POSTROUTING -s 172.19.0.0/16 ! -o docker0 -j MASQUERADE
Espero que os haya sido de ayuda. ¡Nos vemos!
Responder