ฉันมีปัญหาในการเข้าถึงโฮสต์ private interface (ip) จาก container docker ฉันค่อนข้างแน่ใจว่าเกี่ยวข้องกับกฎ Iptables ของฉัน (หรืออาจกำหนดเส้นทาง) เมื่อฉันเพิ่มการ--net=host
ตั้งค่าสถานะdocker run
ทุกอย่างทำงานตามที่คาดไว้ ในทำนองเดียวกันเมื่อฉันระบุว่านโยบายการป้อนข้อมูลกำลังติดตามเสรีนิยม-P INPUT ACCEPT
สิ่งต่าง ๆ ก็ทำงานได้ตามที่ฉันคาดหวัง อย่างไรก็ตามสิ่งเหล่านี้เป็นตัวเลือกที่ไม่พึงประสงค์และไม่ปลอดภัยที่ฉันต้องการหลีกเลี่ยง
เนื่องจากมันไม่ได้เฉพาะเจาะจงกับบริการของฉัน (DNS) ฉันได้แยกสิ่งนั้นออกจากปัญหาเนื่องจากการค้นหาสิ่งนั้นร่วมกับนักเทียบท่าให้ผลในพื้นที่ปัญหาที่แตกต่างกัน (เป็นที่นิยม) เพิ่มเสียงให้กับผลการค้นหา
การเชื่อมโยงคอนเทนเนอร์ Docker นั้นไม่ใช่ตัวเลือกที่ใช้งานได้เนื่องจากคอนเทนเนอร์บางตัวจำเป็นต้องรันด้วยตัวเลือก --net = host เพื่อป้องกันการเชื่อมโยงและฉันต้องการสร้างสถานการณ์ที่สอดคล้องกันหากเป็นไปได้
ฉันมีกฎ Iptables ต่อไปนี้ การรวมกันของ CoreOS, Digital Ocean และ 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
อินเตอร์เฟสโฮสต์ของฉัน (เกี่ยวข้อง):
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
และฉันเรียกใช้คอนเทนเนอร์นักเทียบท่า:
$ docker run --rm -it --dns=10.129.112.210 debian:jessie # Specifying the DNS is so that the public DNS servers aren't used.
ณ จุดนี้ฉันต้องการที่จะสามารถใช้บริการในท้องถิ่นที่ถูกผูกไว้กับ 10.129.112.210:53 ดังนั้นสิ่งต่อไปนี้ควรตอบกลับ:
$ ping google.com
^C
$ ping user.skydns.local
^C
เมื่อฉันเรียกใช้คำสั่งเดียวกันจากโฮสต์ของฉัน:
$ 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.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
จุดที่นี่ไม่ได้เข้าถึงโฮสต์สาธารณะ แต่เป็นโฮสต์ภายในโดยใช้บริการ DNS ท้องถิ่นที่มีอยู่ในโฮสต์ (ผ่านอินสแตนซ์นักเทียบท่าอื่น)
เพื่อแสดงให้เห็นถึงมันยิ่งขึ้นไป (ทักษะการออกแบบงานศิลปะ ascii ของฉันทำได้ดีกว่า iptables ของฉันดังนั้นควรจะพูดได้เพียงพอ ณ จุดนี้):
______________________________________________
| __________________________ 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)
ฉันค้นหาอ่านและใช้ตัวอย่างการกำหนดค่า Iptables ที่แตกต่างกันแล้ว แต่ฉันรู้กฎกฎขั้นสูง "ขั้นสูง" น้อยเกินไปที่จะเข้าใจสิ่งที่เกิดขึ้นและเพื่อให้ได้ผลลัพธ์ตามที่ต้องการ
ผลลัพธ์ของ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
ผลลัพธ์ของcat /proc/sys/net/ipv4/ip_forward
:
1
$ cat /proc/sys/net/ipv4/ip_forward -> 1
และ-A INPUT -i eth1 -j ACCEPT
ยอมรับการเชื่อมต่อทั้งหมดบนอินเทอร์เฟซส่วนตัว กฎอะไรที่คุณขาดหายไป?
-A INPUT -i docker0 -j ACCEPT
iptables -t nat -nL
? คุณทำการวิเคราะห์แพ็กเก็ตหรือไม่ทำการ ping จาก container container และใช้ tcpdump เพื่อดักจับแพ็กเก็ตบนโฮสต์