Aturan Iptables-set sehingga wadah docker dapat mengakses layanan pada IP host

Saya mengalami masalah dalam mengakses antarmuka pribadi host (ip) dari wadah buruh pelabuhan. Saya cukup yakin bahwa ini terkait dengan aturan Iptables saya (atau mungkin perutean). Ketika saya menambahkan --net=host bendera untuk docker run, semuanya bekerja seperti yang diharapkan. Demikian pula ketika saya menentukan bahwa kebijakan INPUT mengikuti liberal -P INPUT ACCEPT, hal-hal juga berfungsi seperti yang saya harapkan. Namun ini adalah opsi yang tidak diinginkan dan tidak aman yang ingin saya hindari.

Karena tidak spesifik untuk layanan saya (DNS), Saya telah mengecualikannya dari masalah, karena mencari itu dalam kombinasi dengan hasil buruh pelabuhan di area masalah (populer) yang berbeda, menambahkan noise ke Hasil Pencarian.

Juga menautkan wadah buruh pelabuhan bukanlah opsi yang layak, karena wadah tertentu perlu dijalankan dengan opsi --net=host, mencegah penautan dan saya ingin membuat situasi yang konsisten jika memungkinkan.

Saya memiliki aturan Iptables berikut. Kombinasi CoreOS, Digital Ocean dan Docker saya asumsikan.

-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

Antarmuka host saya (relevan) :

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

Dan saya menjalankan wadah 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.

Pada titik ini saya ingin dapat menggunakan layanan lokal, terikat pada 10.129.112.210:53. Sehingga berikut ini harus menghasilkan balasan:

$ ping google.com^C$ ping user.skydns.local^C

Ketika saya menjalankan perintah yang sama dari host saya:

$ 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

Resolv saya.conf

$ cat /etc/resolv.confnameserver 10.129.112.210nameserver 127.0.0.1nameserver 8.8.8.8nameserver 8.8.4.4

Intinya di sini bukan untuk mengakses host publik, melainkan yang internal, menggunakan layanan DNS lokal yang tersedia di host (melalui instance docker lain).

Untuk mengilustrasikannya lebih jauh (keterampilan desain seni ascii saya melampaui iptables fu saya, jadi itu harus mengatakan cukup pada saat ini):

 ______________________________________________|  __________________________           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)

Saya telah mencari, membaca, dan menerapkan contoh konfigurasi Iptables yang berbeda, tetapi saya tahu terlalu sedikit aturan Iptables yang lebih "canggih" untuk memahami apa yang terjadi dan dengan demikian untuk mendapatkan hasil yang diinginkan.

Output dari 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

Output dari cat /proc/sys/net/ipv4/ip_forward:

1

Kontainer berkomunikasi dengan host menggunakan docker0 interface.To izinkan lalu lintas dari container add:

-A INPUT -i docker0 -j ACCEPT

Saya mengalami situasi yang sangat mirip tetapi menambahkan -A INPUT -i docker0 -j ACCEPT akan membuka semua akses melalui antarmuka eth0 saya dari host buruh pelabuhan ke wadah yang sama sekali bukan yang saya inginkan.

Dan karena saya perhatikan bahwa wadah saya hanya memiliki akses terbatas (katakanlah hanya port 22) ke antarmuka host alih-alih benar-benar dimatikan dari jaringan host, saya meninjau aturan iptables saya dan menemukan aturan dalam rantai IN_public_allow yang seharusnya bertanggung jawab untuk ini. Aturannya adalah -A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT. Jadi saya menambahkan aturan serupa untuk memungkinkan wadah saya mengakses port host lain yang diinginkan, yang menurut saya bisa menjadi cara yang sedikit lebih tepat untuk membuka akses jaringan host ke wadah.

Saya pikir paket dari wadah berasal dari antarmuka docker0, bukan eth1. coba ’ - INPUT - I docker0-j terima`

Tentu saja, terima kasih telah membantu sejauh ini: Chain PREROUTING (policy ACCEPT)target prot opt source desti - Pastebin.com (tidak sesuai dengan komentar…)- [edit] - > memperbarui tautan ke pastebin yang tidak kedaluwarsa.

Mungkin saya tidak mengerti dengan benar masalah Anda, tetapi saya tidak melihat aturan apa pun untuk mengizinkan kueri DNS di host. Juga, apakah ip_forward diaktifkan?

Hai @ LaurentiuRoescu. '$cat/proc/sys/net/ipv4 / ip_forward → 1dan-A INPUT-I eth1-j ACCEPT` menerima semua koneksi pada antarmuka private. Aturan apa yang Anda lewatkan?

Saya pikir Anda berhasil @LaurentiuRoescu. Ketika saya menambahkan baris Anda tampaknya bekerja. Saya tidak pernah berpikir itu adalah sesuatu yang sepele… Bisakah Anda menambahkannya sebagai jawaban atas pertanyaan saya? Saya ingin menghargai jawaban Anda.

Bisakah Anda memposting output dari ‘iptables-t nat-nL’? Apakah anda melakukan analisis paket, mengatakan melakukan ping dari wadah sumber dan menggunakan tcpdump untuk menangkap paket pada host.