Ho problemi ad accedere a un'interfaccia privata host (ip) da un contenitore docker. Sono abbastanza certo che sia legato alle mie regole di Iptables (o forse al routing). Quando aggiungo la --net=host
bandiera a docker run
, tutto funziona come previsto. Allo stesso modo, quando specifico che la politica INPUT segue un modello liberale -P INPUT ACCEPT
, anche le cose funzionano come mi aspetterei. Tuttavia, queste sono opzioni indesiderabili e non sicure che vorrei evitare.
Dal momento che non è specifico per i miei servizi (DNS) l'ho escluso dal problema, dal momento che la ricerca in combinazione con la finestra mobile produce in una diversa area (popolare) del problema, aggiungendo rumore ai risultati della ricerca.
Anche il collegamento dei contenitori Docker non è un'opzione praticabile, poiché alcuni contenitori devono essere eseguiti con l'opzione --net = host, impedendo il collegamento e voglio creare una situazione coerente, ove possibile.
Ho le seguenti regole di Iptables. Presumo una combinazione di CoreOS, Digital Ocean e Docker.
-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
Le mie interfacce host (pertinenti):
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 forever
4: 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
E corro un container 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.
A questo punto voglio essere in grado di utilizzare un servizio locale, associato a 10.129.112.210:53. In modo che quanto segue possa dare una risposta:
$ ping google.com
^C
$ ping user.skydns.local
^C
Quando eseguo lo stesso comando dal mio 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
Il mio resolv.conf
$ cat /etc/resolv.conf
nameserver 10.129.112.210
nameserver 127.0.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4
Il punto qui non è quello di accedere agli host pubblici, ma piuttosto a quelli interni, utilizzando il servizio DNS locale disponibile sull'host (tramite un'altra istanza docker).
Per illustrarlo ulteriormente (Le mie capacità di progettazione artistica ascii superano il mio fu di iptables, quindi a questo punto dovrei dire abbastanza):
______________________________________________
| __________________________ 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)
Ho cercato, letto e applicato diverse configurazioni di Iptables di esempio, ma conosco troppo poco delle regole Iptables più "avanzate" per capire cosa sta succedendo e quindi ottenere il risultato desiderato.
Uscita di iptables -t nat -nL
:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
Chain DOCKER (2 references)
target prot opt source destination
Uscita di cat /proc/sys/net/ipv4/ip_forward
:
1
$ cat /proc/sys/net/ipv4/ip_forward -> 1
e -A INPUT -i eth1 -j ACCEPT
accetta tutte le connessioni sull'interfaccia privata . Quali regole manchi?
-A INPUT -i docker0 -j ACCEPT
iptables -t nat -nL
? Hai fatto qualche analisi di pacchetto, diciamo di fare un ping dal contenitore di origine e hai usato tcpdump per catturare i pacchetti sull'host.