Ang trapiko ng Docker container ay lumalampas sa VPN ng host: paano ito suriin
Ang VPN ng host ay sumasaklaw lamang sa network namespace ng host. Gamitin ang mga pagsusuring ito upang malaman kung ang trapiko ng container sa bridge ay pumapasok sa tunnel o direktang lumalabas.
Ang browser mo sa host ay nagpapakita ng exit address ng VPN, ang container ay nag-uulat ng iyong koneksyon sa bahay, at may tumatawag nito na pagtagas. Walang nagtagas. Ang tunnel ng host ay isang grupo ng mga interface, ruta at patakaran na kabilang sa network namespace ng host, at ang container sa bridge ay ibang namespace na may sariling default na ruta. Nakaupo ako sa isang Compose stack kung saan ang VPN client ay nakakonekta nang ilang linggo at wala kahit isang packet ng container ang pumasok doon.
Suriin ang namespace bago ang icon sa tray
Ang mga namespace ang buong argumento. Kapag naglunsad ang Docker ng container sa isang bridge network, gumagawa ito ng network namespace, ikinakabit ang isang dulo ng veth pair sa loob nito, at binibigyan ang namespace na iyon ng address at default na ruta. Ang interface ng tunnel, anuman ang itawag dito, ay naninirahan sa namespace ng host. Hindi ito nakikita ng trapiko sa loob ng container, at walang setting ng client ang nagbabago nito mula sa labas.
Dalawang sinusuportahang hakbang ang naglalabas sa iyo mula sa paghihiwalay. Inilalagay ng --network host ang container sa loob ng namespace ng host, kaya namamana nito ang mga ruta ng host at dahil dito ang tunnel. Ibinabahagi ng --network container:vpn ang namespace ng ibang container, at ganoon din ang ginagawa ng karamihan sa mga disenyong sidecar upang ipadala ang workload sa isang container ng VPN. Pareho silang malinaw na pagpipilian; karaniwang isa lamang sa kanila ang tunay na intensyon ng taong nagde-deploy.
Ang host mode ay hindi libreng upgrade. Nawawalan ang container ng sariling address, hindi na nalalapat ang paglalathala ng port, at ang prosesong may hawak ng NET_ADMIN doon ay maaaring mag-rewrite ng routing ng host. Ang tanggapin iyon ay maaaring tamang desisyon. Ang ipagpalagay na nakabukas na ito ang dahilan kung bakit may mga taong gumugugol ng isang gabi sa pag-debug ng tunnel na hindi kailanman nasa landas.
Sundan ang packet palabas ng bridge
Ang container sa bridge ay nagpapadala ng packet nito sa default na gateway, na siyang interface ng bridge sa host. Pagkatapos ay ipinapasa ng host ang packet at, sa default na configuration, isinasalin ang source address sa sarili nito bago lumabas ang packet. Ang hakbang na iyon ng pagsasalin ang tahimik na tumatalo sa patakaran.
Pagdating ng packet sa endpoint ng tunnel, dala na nito ang address ng host. Anumang patakaran, ruta ng patakaran o desisyon sa split tunnel na nakabatay sa orihinal na address ng container ay hindi na tumutugma, at dalawang container na dapat lumabas sa magkaibang exit ay hindi matutukoy sa source lamang. Kung kailangan mo ng routing kada container, ang desisyon ay dapat mangyari bago ang pagsasalin o sa loob ng namespace na kinokontrol mo.
Ang Docker mismo ang nagpapanatili ng mga patakarang ito, sa pamamagitan ng alinmang firewall backend na ginamit sa daemon. Ang mga patakarang isinulat sa kamay sa labas ng sinusuportahang hook para sa forwarded na trapiko, DOCKER-USER, ay maaaring muling ayusin o alisin kapag nag-restart ang daemon o nag-upgrade ang host. Ang dokumentasyon ng Docker sa pag-filter ng packet ay nagpapakita ng pagkakasunod-sunod ng mga chain; ang praktikal na punto ay kailangan ng bawat patakaran ng may-ari at ng landas ng muling pag-load na talagang sinubukan mo.
Subukan ang dalawang sistema nang hiwalay
Ang ebidensya mula sa isang namespace ay walang sinasabi tungkol sa isa pa. Ang kahilingang pinatakbo sa loob ng container ng VPN ay nagpapatunay na gumagana ang tunnel para sa container na iyon. Hindi ito ebidensya tungkol sa host, at ang parehong utos na pinatakbo mula sa container ng --network host ay hindi ebidensya tungkol sa bridge.
# host namespace
ip route get 1.1.1.1
ip -brief addr show
# a fresh container on the same bridge network
docker run --rm --network appnet alpine sh -c 'ip route; cat /etc/resolv.conf; ip -6 route'
Pagkatapos ay ulitin ang pagsubok sa loob ng tunay na container ng application at hindi sa kahawig na image. Maaaring may dalang karagdagang ruta, environment variable ng proxy o ibang resolver ang app, at bawat isa sa mga iyon ay nagbabago ng sagot. Suriin ang resolution ng pangalan at ang pangalawang pamilya ng address sa bawat pagkakataon: ang mga container sa mga bridge na tinukoy ng user ay niresolba sa pamamagitan ng built-in na resolver ng Docker sa 127.0.0.11, at ang default na rutang IPv6 sa bridge ay maaaring magdala ng trapiko palabas habang abala ka sa pagsubok ng tunnel na IPv4 lamang.
Basahin ang pattern bago hawakan ang mga kredensyal
Kapag gumagana ang host at hindi ang container, ang sanhi ay halos palaging estruktural, at ang pag-ikot ng mga susi o muling pag-install ng client ay nagsasayang ng isang hapon. Ayusin muna ang sintomas at karaniwang pinangalanan ng pagwawasto ang sarili nito.
| What you see | Usual cause | First check |
|---|---|---|
| Host exits through the VPN, container shows the ISP address | The container never entered the tunnel | Default route inside the container |
| Container works until the daemon restarts, then stops | Rules outside the supported hook, or a changed backend | Daemon's reported firewall backend and DOCKER-USER |
| Container loses internal hosts after the tunnel comes up | VPN prefix overlaps the Docker bridge subnet | ip route on the host, then docker network inspect |
| Small replies arrive, large ones hang | Tunnel MTU or missing MSS clamping | Link MTU on both ends of the tunnel |
| Container falls back to the ISP address when the tunnel drops | Nothing enforces the kill switch for forwarded traffic | Stop the tunnel with a request in flight |
Ang hilera ng overlap ay may karapatan sa sariling pangungusap. Ang profile ng VPN na nagtutulak ng ruta para sa 172.17.0.0/16, o para sa 10.0.0.0/8 na nagkataong naglalaman ng prefix ng iyong bridge, ay nagpipilit sa tunnel na angkinin ang subnet ng container, at ang mga sagot sa isinaling address ay pupunta sa maling direksyon o mawawala. Ang muling pag-numero ng network ng Docker ay karaniwang mas malinis kaysa sa pag-iipon ng mga eksepsyon.
Gawing malinaw ang saklaw, pagkatapos ay sadyang sirain ito
Dalawang disenyo ang nananatili sa pagsusuri. Ibahagi ang namespace ng container ng VPN at bawat sakop na workload ay gumagamit ng isang tunnel na may isang hangganan ng restart, na simple hanggang sa isang serbisyo ang mangailangan ng ibang exit o sariling landas ng DNS. O iruta ang network ng container papunta sa gateway ng VPN sa host: bukas ang forwarding, nakaturo ang prefix ng bridge sa tunnel, tahasang hinawakan ang trapikong pabalik. Binibili niyan ang kontrol kada network at nagkakahalaga sa iyo ng isang set ng patakarang dapat mong panatilihin sa mga upgrade ng daemon at client.
Anuman ito, ang pagsubok na mahalaga ay ang kaso ng pagkabigo. Ihinto ang tunnel habang nasa hangin ang isang kahilingan ng container at tingnan kung saan pupunta ang packet. Kung bumabalik ito sa direktang landas, hindi kailanman naipatupad ang saklaw, dahil ang kill switch ng client ay namamahala sa sariling trapiko ng client at hindi sa mga forwarded na packet mula sa bridge. Pagkatapos ay i-restart ang daemon at ang host at kumpirmahin ang resulta sa pangalawang pagkakataon; iyon ang sandaling nawawala ang mga patakarang isinulat sa kamay.
Bago mo sabihing tapos na, kumpirmahin ang apat na bagay: ang interface ng tunnel ay nasa parehong namespace ng trapiko, ang pagsubok ng container ay tumakbo sa loob ng tunay na container, sinuri ang resolution ng pangalan at ang dalawang pamilya ng address, at ang pagsubok ng pagkabigo ng tunnel ay nabibigo pa rin nang sarado. Pagkatapos ay isulat ang backend ng firewall, bersyon ng client at may-ari ng bawat patakaran. Ang rekord na iyon ang pumipigil sa susunod na upgrade na mag-iwan ng hindi dokumentadong halo ng lumang mga palagay.