Introducción
En el mundo actual de contenedores, Docker se ha convertido en una solución popular para implementar y administrar aplicaciones. Un caso de uso común implica reenviar el tráfico de red desde un puerto específico en la computadora host a un puerto dentro de un contenedor Docker. Esto puede resultar especialmente útil cuando desea exponer al mundo exterior un servicio que se ejecuta dentro de su contenedor o cuando necesita configurar un proxy inverso para el equilibrio de carga.
En este artículo, lo guiaremos a través de los pasos necesarios para reenviar un puerto a un contenedor Docker usando iptables, una utilidad de firewall potente y flexible disponible en la mayoría de las distribuciones de Linux.
Identificar la dirección IP del contenedor Docker
Ejecute el siguiente comando para encontrar la dirección IP de su contenedor Docker:
docker inspect -f '{{.NetworkSettings.IPAddress }}' <CONTAINER_NAME_OR_ID>
Reemplace con el nombre o ID de su contenedor. Tenga en cuenta la dirección IP que se muestra en el resultado.
Reenvío de puertos a contenedores Docker
Usando Iptables
Para reenviar un puerto a un contenedor Docker usando iptables, puedes seguir estos pasos:
Agregue reglas de iptables para el reenvío: ahora configure reglas de iptables para reenviar el puerto deseado a su contenedor Docker. Reemplace <HOST_PORT> con el número de puerto en la computadora host, <CONTAINER_IP> con la dirección IP de su contenedor y <CONTAINER_PORT> con el número de puerto dentro del contenedor.
sudo iptables -t nat -A PREROUTING -p tcp --dport <HOST_PORT> -j DNAT --to-destination <CONTAINER_IP>:<CONTAINER_PORT>
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
Por ejemplo, si desea redirigir el puerto 8080 desde la computadora host al puerto 80 en un contenedor Docker con una IP 172.21.0.7, ejecute los comandos proporcionados:
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.21.0.7:80
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
Guarde las reglas de iptables: para que las reglas de iptables persistan durante los reinicios, puede guardarlas usando el comando iptables-save:
sudo iptables-save > /etc/iptables/rules.v4
Tenga en cuenta que la ruta al archivo de reglas puede variar según su distribución de Linux.
Haga que la regla iptables sea persistente: si está utilizando una distribución basada en Debian/Ubuntu, puede instalar el paquete iptables-persistent para que las reglas sean persistentes durante los reinicios:
sudo apt-get install iptables-persistent
Durante la instalación, se le preguntará si desea guardar las reglas actuales de iptables. Seleccione "Sí" para guardar las reglas.
Para reenviar un puerto a un contenedor Docker usando firewall-cmd, que forma parte de la utilidad firewalld en sistemas basados en RHEL/CentOS/Fedora, siga estos pasos:
Agregue reglas de firewall-cmd para el reenvío: ahora configure reglas de firewall-cmd para reenviar el puerto deseado a su contenedor Docker. Reemplace <HOST_PORT> con el número de puerto en la computadora host, <CONTAINER_IP> con la dirección IP de su contenedor y <CONTAINER_PORT> con el número de puerto dentro del contenedor.
Primero, habilite el enmascaramiento en la zona activa:
sudo firewall-cmd --zone=public --add-masquerade --permanent
A continuación, cree la regla de reenvío de puertos:
sudo firewall-cmd --zone=public --add-forward-port=port=<HOST_PORT>:proto=tcp:toaddr=<CONTAINER_IP>:toport=<CONTAINER_PORT> --permanent
Por ejemplo, para reenviar el puerto 8080 en la computadora host al puerto 80 en un contenedor Docker con una dirección IP de 172.17.0.7, usaría el siguiente comando:
sudo firewall-cmd --zone=public --add-forward-port=port=8080:proto=tcp:toaddr=172.17.0.7:toport=80 --permanent
Vuelva a cargar las reglas del firewall: después de agregar reglas, debe volver a cargar la configuración del firewall para que los cambios surtan efecto:
sudo firewall-cmd --reload
Ahora, el reenvío de puertos debería funcionar y todo el tráfico que llegue a <HOST_PORT> en la computadora host se reenviará a <CONTAINER_PORT> en el contenedor Docker.
Usando UFW
Para reenviar un puerto a un contenedor Docker usando ufw (Uncomplicated Firewall), que es la herramienta de firewall predeterminada en Ubuntu y otros sistemas basados en Debian, debe seguir estos pasos:
Habilite el reenvío de UFW: edite el archivo de configuración de UFW en /etc/default/ufw:
sudo nano /etc/default/ufw
Busque la línea que contiene DEFAULT_FORWARD_POLICY="DROP" y cámbiela a DEFAULT_FORWARD_POLICY="ACCEPT":
DEFAULT_FORWARD_POLICY="ACCEPT"
Guarde el archivo y salga del editor.
Configure el reenvío de IP: edite el archivo de configuración sysctl en /etc/sysctl.conf:
sudo nano /etc/sysctl.conf
Agregue o elimine el comentario de la siguiente línea:
net.ipv4.ip_forward=1
Guarde el archivo y salga del editor. Aplique los cambios ejecutando:
sudo sysctl -p
Actualice las reglas de UFW: primero cree un nuevo archivo de reglas de UFW para el reenvío de puertos. Reemplace <HOST_PORT> con el número de puerto en la computadora host, <CONTAINER_IP> con la dirección IP de su contenedor y <CONTAINER_PORT>> con el número de puerto dentro del contenedor.
sudo nano /etc/ufw/before.rules
Agregue las siguientes líneas al principio del archivo, después de los comentarios del encabezado:
*nat:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport <HOST_PORT> -j DNAT --to-destination <CONTAINER_IP>:<CONTAINER_PORT>
COMMIT
Por ejemplo, para reenviar el puerto 8080 en la computadora host al puerto 80 en un contenedor Docker con una dirección IP de 172.17.0.7, agregaría:
*nat:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.7:80
COMMIT
Guarde el archivo y salga del editor.
Recargar UFW: Finalmente, recarga la configuración de UFW para que los cambios surtan efecto:
sudo ufw disable
sudo ufw enable
Ahora, el reenvío de puertos debería funcionar y todo el tráfico que llegue a <HOST_PORT> en la computadora host se reenviará a <CONTAINER_PORT> en el contenedor Docker.
Conclusión
En conclusión, reenviar un puerto a un contenedor Docker usando iptables es un proceso simple que implica identificar la dirección IP del contenedor, agregar las reglas de iptables necesarias y garantizar que las reglas persistan durante los reinicios. Si sigue los pasos de este artículo, puede asegurarse de que el tráfico enviado a un puerto específico en la computadora host se redirija sin problemas al puerto correspondiente dentro del contenedor. Este enfoque le permite exponer servicios que se ejecutan dentro de contenedores, configurar servidores proxy inversos o implementar equilibrio de carga, entre otros casos de uso, mejorando así la flexibilidad y eficiencia de su infraestructura en contenedores.