Estoy corriendodos contenedores Docker en el mismo hostVivo en Docker la misma red puente y tengo nftables configurados para restringir más o menos todo el tráfico (reglas a continuación).
Mi único problema (que yo sepa) es queEl tráfico de un contenedor a otro está bloqueado., si un contenedor usala URL pública del servicio proporcionado por el otro contenedor.
Por ejemplo, el servicio A es un servidor SMTP que tiene una entrada DNS pública mail.acme.com
y el servicio B es una aplicación que desea enviar correos electrónicos al servidor web.usando esta URL. El servidor SMTP está configurado de manera que sea accesible desde el exterior (es decir, reenvío de puertos como 0.0.0.0:25:25
en Docker Compose).
En este caso particular, la interfaz de entrada en nftables no es mi interfaz externa, sino la interfaz de la red Docker en la que se encuentra el contenedor. El tráfico no se enruta FORWARD
, las reglas agregadas por Docker no se aplican y el tráfico termina en INPUT
donde se deja caer.
No quiero configurar reglas individuales para permitir el tráfico desde las interfaces de Docker a los puertos permitidos.
Estoy buscando una solución que permita a los servicios usar sus respectivas URL y que sea independiente de los puertos e interfaces utilizados en la configuración de Docker. ¿Es esto posible incluso solo con nftables?
Lo único que se me ocurrió hasta ahora es saltar de INPUT
a FORWARD
si la interfaz de entrada no es una interfaz externa, pero parece que no debería hacerlo.
Aquí están mis INPUT
reglas:
chain INPUT {
type filter hook input priority filter; policy drop;
ct state vmap { invalid : drop, established : accept, related : accept }
iifname "lo" accept
iifname "externalif0" icmp type echo-request accept
iifname "externalif0" icmpv6 type echo-request accept
}
Esto es lo que sucede cuando un contenedor intenta llegar a otro contenedoren el mismo anfitrión: (He truncado un poco del resultado del seguimiento que no parecía demasiado relevante)
trace id 196c1ae6 ip filter trace_chain packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443
trace id 196c1ae6 ip nat PREROUTING packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443
trace id e7c2ca4b ip filter INPUT packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443
Y aquí estátráfico exterioral mismo servicio:
trace id 29f9da6c ip filter trace_chain packet: iif "externalif0" ip saddr <someip> ip daddr <public host ip> sport 36382 tcp dport 443
trace id 29f9da6c ip nat PREROUTING packet: iif "externalif0" ip saddr <someip> ip daddr <public host ip> sport 36382 tcp dport 443
trace id 29f9da6c ip nat DOCKER rule iifname != "dockerbr0" dport 443 dnat to <dockerip>:443 (verdict accept)
trace id 29f9da6c ip filter FORWARD packet: iif "externalif0" oif "dockerbr0" ip saddr <someip> daddr <containerip> sport 36382 tcp dport 443
trace id 29f9da6c ip filter DOCKER rule iifname != "dockerbr0" oifname "dockerbr0" daddr <containerip> tcp dport 443 accept (verdict accept)
trace id 29f9da6c ip nat POSTROUTING packet: iif "externalif0" oif "dockerbr0" ip saddr <someip> ip daddr <containerip> sport 36382 tcp dport 443
También en el anfitrión:
iptables-legacy -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT