Iptables para Docker en un servidor expuesto a internet

Hoy os traigo una pequeña guía para aquellos que queráis instalar Docker en un servidor cuya interfaz de red está expuesta a internet. Debido a las reglas de iptables que Docker configura por defecto cuando utilizamos la opción -p para hacer forward de un puerto sin decirle una interfaz en concreto nos encontraremos con que dicho puerto queda también expuesto a internet, cosa poco deseable en el mayor de los casos.

Para solucionar esto debemos decirle a Docker que no toque nuestras reglas de iptables. En sistemas como Debian que utilizan systemd esto lo conseguiremos ejecutando los siguientes comandos:

mkdir /etc/systemd/system/docker.service.d
cat << EOF > /etc/systemd/system/docker.service.d/noiptables.conf
[Service]
ExecStart=
ExecStart=/usr/bin/docker daemon -H fd:// --iptables=false
EOF
systemctl daemon-reload

Source

Reiniciamos nuestras iptables utilizando iptables-restore por ejemplo, reiniciamos Docker y veremos que ya no genera la tabla Docker ni ninguna otra tabla. Pero, y siempre existe un pero, esto ha dejado nuestros containers sin acceso a internet.

El primer paso para solucionar esto será activar el forwarding si no lo tenemos ya:

sysctl -w net.ipv4.ip_forward=1

Y ahora añadiremos las siguientes reglas de iptables:

iptables -A FORWARD -i docker0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o docker0 -j ACCEPT

Esto permitirá que el tráfico llegue a los containers pero el problema vendrá en que no sabrán que hacer con la respuesta, para ello necesitaremos añadir una regla con MASQUERADE, si utilizáis el rango por defecto de Docker la regla se vería así:

iptables -t nat -A POSTROUTING -s 172.17.0.0/24 -o eth0 -j MASQUERADE

Esto deberéis hacerlo para cada segmento de red que utilicéis en Docker y queráis que tenga acceso a internet.

Con esto ya podéis abrir y cerrar puertos de la forma habitual en vuestro servidor sin que Docker los abra por su cuenta.

Wazuh

Este problema me lo encontré revisando mi instalación de Wazuh, el problema vino en que cuando realice los anteriores cambios los clientes dejaron de ser capaces de conectarse a Wazuh.

El problema viene de que Wazuh ve que la ip de origen es la de nuestro servidor en lugar de nuestro cliente debido al MASQUERADE y al no coincidir con ningún cliente rechaza los paquetes.

La única solución que he encontrado hasta ahora para esto es ha sido quitar los clientes y volver a registrarlos utilizando any como ip de tal manera que Wazuh acepte cualquier ip de origen para dicho cliente.

Recordad que para que los containers tengan internet, si habéis utilizado el docker-compose, necesitais añadir el MASQUERADE para la red correspondiente, en mi caso 172.17.0.0/24.

Espero os haya gustado y os salve de algún susto como el que yo me lleve al ver mis containers expuesto a internet a pesar de mi arduo trabajo con iptables para que esto no sucediera, pero de todo se aprende.

Saludos, y como siempre, gracias por vuestra visita!

Esta entrada fue publicada en docker, tutorial, wazuh. Guarda el enlace permanente.

Deja un comentario