Mam problemy z dostępem do prywatnego interfejsu hosta (ip) z kontenera dokowanego. Jestem całkiem pewien, że jest to związane z moimi regułami Iptables (a może routingiem). Po dodaniu --net=host
flagi docker run
wszystko działa zgodnie z oczekiwaniami. Podobnie, gdy sprecyzuję, że polityka INPUT podąża za liberałem -P INPUT ACCEPT
, rzeczy również działają tak, jakbym się spodziewał. Są to jednak niepożądane i niebezpieczne opcje, których chciałbym uniknąć.
Ponieważ nie jest to specyficzne dla moich usług (DNS), wykluczyłem to z problemu, ponieważ wyszukiwanie tego w połączeniu z dokerem daje w innym (popularnym) obszarze problemu, powodując hałas w wynikach wyszukiwania.
Również łączenie kontenerów Docker nie jest realną opcją, ponieważ niektóre kontenery muszą być uruchamiane z opcją --net = host, co zapobiega łączeniu, a ja chcę stworzyć spójną sytuację tam, gdzie to możliwe.
Mam następujące zasady Iptables. Zakładam, że połączenie CoreOS, Digital Ocean i 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
Moje (odpowiednie) interfejsy hosta:
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
I prowadzę kontener dokerów:
$ docker run --rm -it --dns=10.129.112.210 debian:jessie # Specifying the DNS is so that the public DNS servers aren't used.
W tym momencie chcę móc korzystać z usługi lokalnej, związanej z 10.129.112.210:53. Tak więc poniższe powinny dać odpowiedź:
$ ping google.com
^C
$ ping user.skydns.local
^C
Po uruchomieniu tego samego polecenia z mojego hosta:
$ 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
Mój 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
Nie chodzi o to, aby uzyskać dostęp do hostów publicznych, ale wewnętrznych, za pomocą lokalnej usługi DNS dostępnej na hoście (za pośrednictwem innej instancji dokera).
Aby zilustrować to jeszcze bardziej (moje umiejętności projektowania ascii przewyższają moje iptables fu, więc w tym momencie powinno to powiedzieć dość):
______________________________________________
| __________________________ 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)
Przeszukałem, przeczytałem i zastosowałem różne przykładowe konfiguracje Iptables, ale zbyt mało znam bardziej „zaawansowanych” reguł Iptables, aby zrozumieć, co się dzieje, a tym samym uzyskać pożądany rezultat.
Wyjście 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
Wyjście cat /proc/sys/net/ipv4/ip_forward
:
1
$ cat /proc/sys/net/ipv4/ip_forward -> 1
i -A INPUT -i eth1 -j ACCEPT
akceptuje wszystkie połączenia w interfejsie prywatnym . Jakich zasad brakuje?
-A INPUT -i docker0 -j ACCEPT
iptables -t nat -nL
? Czy zrobiłeś jakąkolwiek analizę pakietu, powiedz, że wykonaj ping z kontenera źródłowego i użyj tcpdump, aby przechwycić pakiety na hoście.