Tengo problemas para acceder a una interfaz privada (ip) de host desde un contenedor docker. Estoy bastante seguro de que está relacionado con mis reglas de Iptables (o quizás con el enrutamiento). Cuando agrego el --net=host
bandera a docker run
, todo funciona como se esperaba. De manera similar, cuando especifico que la política de ENTRADA sigue un liberal -P INPUT ACCEPT
, las cosas también funcionan como yo esperaría. Sin embargo, estas son opciones indeseables e inseguras que me gustaría evitar.
Como no es específico de mis servicios (DNS), lo he excluido del problema, ya que buscarlo en combinación con docker produce un área problemática diferente (popular), lo que agrega ruido a los resultados de búsqueda.
Además, la vinculación de contenedores Docker no es una opción viable, porque ciertos contenedores deben ejecutarse con la opción --net=host, lo que impide la vinculación y quiero crear una situación coherente siempre que sea posible.
Tengo las siguientes reglas de Iptables. Una combinación de CoreOS, Digital Ocean y Docker, supongo.
-P INPUT DROP-P FORWARD ACCEPT-P OUTPUT ACCEPT-N DOCKER-A INPUT -i lo -j ACCEPT-A INPUT -i eth1 -j ACCEPT-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT-A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT-A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT-A FORWARD -o docker0 -j DOCKER-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT-A FORWARD -i docker0 ! -o docker0 -j ACCEPT-A FORWARD -i docker0 -o docker0 -j ACCEPT
Mis interfaces de host (relevantes) :
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 inet 10.129.112.210/16 brd 10.129.255.255 scope global eth1 valid_lft forever preferred_lft forever4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default inet 172.17.42.1/16 scope global docker0 valid_lft forever preferred_lft forever
Y ejecuto un contenedor Docker:
$ docker run --rm -it --dns=10.129.112.210 debian:jessie # Specifying the DNS is so that the public DNS servers aren't used.
En este punto, quiero poder usar un servicio local, vinculado a 10.129.112.210: 53. De modo que lo siguiente debería dar una respuesta:
$ ping google.com^C$ ping user.skydns.local^C
Cuando ejecuto el mismo comando desde mi host:
$ ping photo.skydns.localPING photo.skydns.local (10.129.112.206) 56(84) bytes of data.64 bytes from 10.129.112.206: icmp_seq=1 ttl=64 time=0.790 ms^C
Mi resolv.conf
$ cat /etc/resolv.confnameserver 10.129.112.210nameserver 127.0.0.1nameserver 8.8.8.8nameserver 8.8.4.4
El punto aquí no es acceder a los hosts públicos, sino a los internos, utilizando el servicio DNS local disponible en el host (a través de otra instancia de docker).
Para ilustrarlo aún más (mis habilidades de diseño de arte ascii superan mis habilidades de iptables, por lo que debería ser suficiente en este punto):
______________________________________________| __________________________ Host || | Docker DNS container | || ``````````````````````|``` || | || ,----------,---( private n. interface ) || | | || | | ( public n. interface )---| | | || | | ( loopbck n. interface ) || | | || | | || | __|_______________________ || | | Docker service container | || | `````````````````````````` || | || | || [ Local host service using DNS. ] || ||______________________________________________| private (host) network interface: eth1 (10.129.0.0/16) Docker network interface: docker0 (172.17.0.0/16)
He buscado, leído y aplicado diferentes configuraciones de Iptables de ejemplo, pero sé muy poco de las reglas de Iptables más "avanzadas" para comprender qué está sucediendo y, por lo tanto, obtener el resultado deseado.
Salida de iptables -t nat -nL
:
Chain PREROUTING (policy ACCEPT)target prot opt source destinationDOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCALChain INPUT (policy ACCEPT)target prot opt source destinationChain OUTPUT (policy ACCEPT)target prot opt source destinationDOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCALChain POSTROUTING (policy ACCEPT)target prot opt source destinationMASQUERADE all -- 172.17.0.0/16 0.0.0.0/0Chain DOCKER (2 references)target prot opt source destination
Salida de cat /proc/sys/net/ipv4/ip_forward
:
1