Rekebisha trafiki ya Docker na WSL inayopuuza VPN ya mwenyeji
Kontena na WSL huweka njia, kitatuzi na njia ya upelekaji zao wenyewe, kwa hiyo handaki la mwenyeji linalofanya kazi huwaachia DNS ya zamani au bila njia ya kutoka. Rekebisha kila tabaka.
Wakati wa masika mwaka huu nilikaa sehemu kubwa ya asubuhi moja nikifukuza kontena ambalo halikuweza kutatuwa hata jina moja la ndani, huku kivinjari kilichokuwa kando kikifungua wiki bila malalamiko. Handaki lilikuwa juu, kivinjari kilithibitisha hilo, na kontena lilikuwa katika nafasi nyingine ya majina ya mtandao yenye jedwali lingine la njia na kitatuzi kingine. Kinachofuata ni mpangilio ninaokagua sasa: kwanza majedwali ya njia, pili utatuzi wa majina, tatu upelekaji na mwisho jukwaa la mwenyeji. Simama katika hatua ya kwanza ambayo tayari inashindikana, kwa sababu kuongeza kanuni chini zaidi kwenye rafu huficha mpaka badala ya kuuhamisha.
Linganisha majedwali matatu ya njia kabla ya kubadilisha kanuni
Kontena kwenye daraja la kawaida la Docker lina njia moja ya kawaida kuelekea lango la docker0, na halijui kuwa tun0 ipo. Mwenyeji ana tun0, njia zilizosukumwa na VPN, na labda kanuni ya sera inayotuma trafiki ya majaribio kupitia kiolesura tofauti na unachotarajia. WSL huongeza jedwali la tatu nyuma ya kirekebishaji chake pepe. Chapisha zote tatu kabla ya kuhariri yoyote.
| Context | Command | What a wrong answer looks like |
|---|---|---|
| Host | ip route get 10.8.0.20 | Leaves a physical interface instead of tun0 |
| Container | ip route | Only 172.17.0.0/16 via 172.17.0.1 |
| Container DNS | cat /etc/resolv.conf | A public resolver, or an upstream the tunnel never pushed |
| WSL | ip addr; ip route | Only the WSL subnet, no Windows VPN adapter |
Ikiwa njia pekee ya kontena ni daraja na tun0 haionekani kamwe katika nafasi yake ya majina, hakuna kitu chini kitakachosaidia: hakuna mabadiliko ya seva ya majina yanayounda njia, na hakuna njia inayounda utambulisho wa handaki ambao mwenzake atakubali. Mpangilio ni muhimu kwa sababu kushindikana kwa DNS na kushindikana kwa njia huonekana sawa kutoka ndani ya shell.
Elekeza kitatuzi kwenye handaki badala ya kile cha umma
Kwenye mwenyeji, resolvectl status huorodhesha seva za DNS kwa kila kiungo, na readlink -f /etc/resolv.conf hukuambia kama faili ni stub ya systemd, faili ya NetworkManager, au kitu kilichoandikwa upya na mteja wa msambazaji. Ndani ya kontena kwenye mtandao uliofafanuliwa na mtumiaji, /etc/resolv.conf huitaja 127.0.0.11, kitatuzi kilichojengwa ndani ya Docker, ambacho hupeleka kwa upstream ambao daemon iliwekwa nayo. Kontena kwenye daraja la kawaida badala yake lilipokea nakala ya faili ya mwenyeji lilipoundwa, na huiweka.
Nakala hiyo ndiyo sababu handaki linaloinuka baada ya kontena kuanza humwacha kontena likiuliza upstream wa zamani. Ama peana kitatuzi cha VPN waziwazi kwa docker run --dns 10.8.0.53, au weka "dns": ["10.8.0.53"] katika /etc/docker/daemon.json na uanzishe upya daemon, au unda upya kontena handaki linapokuwa juu. Kuunda upya kwa kawaida ni nafuu kuliko kutatua kitatuzi kilichokuwa sahihi saa moja iliyopita.
Kubadilisha na kitatuzi cha umma ni urekebishaji unaohifadhi dalili. Hutatua intaneti na hushindikana katika kila eneo la kibinafsi, na unaweza kupita kwa utulivu uchujaji ambao handaki lipo kwa ajili yake. Ukijaribu kuandika ndani ya /etc/resolv.conf ya kontena linaloendesha, tarajia Device or resource busy: Docker hufanya bind-mount ya faili hiyo, kwa hiyo uhariri unahitaji kwanza kufungua. Kuweka --dns wakati wa kuunda ndiyo mfululizo unaostahimili kuanzishwa upya.
Peleka na tafsiri wakati kontena zinakopa handaki
Kwa daraja la kawaida, mwenyeji ni kipanga njia kati ya docker0 na tun0, na kwa kawaida hafanyi kazi zote mbili. Washa upelekaji na utafsiri anwani ya chanzo ili mwenzake aone anwani ya handaki ya mwenyeji badala ya ile ambayo hana njia ya kurudi (badilisha tun0 na jina ambalo mteja wako huita kiolesura):
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
iptables -A FORWARD -i docker0 -o tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o docker0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPTKanuni za FORWARD ni muhimu kwenye wenyeji ambao sera yao ya upelekaji ni DROP. Docker huingiza minyororo yake mwenyewe, kwa hiyo jaribu kwa pakiti badala ya kusoma iptables -S: kutoka kwa kontena, ip route get 10.8.0.20 inapaswa kutaja lango la daraja, na nc -vz 10.8.0.20 443 inapaswa kuunganisha au kuisha muda kwenye handaki badala ya kwenye kitatuzi.
Bila MASQUERADE mwenzake anahitaji njia ya kurudi hadi 172.17.0.0/16, ambayo VPN nyingi za ufikiaji wa mbali hazitasukuma. Hapa pia mteja anayetegemea sera huvunja mpango: ikiwa anakamata trafiki ya UID au cgroups maalum tu, kanuni zako za upelekaji hazioni pakiti ndani ya handaki kamwe, na urekebishaji ni wa sera ya upangaji njia ya mteja na si iptables. Kanuni zilizoongezwa kwa mkono hupotea wakati wa kuanzisha upya, kwa hiyo ziweke katika kitengo cha systemd au jedwali la netfilter-persistent na ujaribu tena baada ya kuanzisha upya, kwa sababu handaki linaloinuka kwa kuchelewa linaweza kuzifuta.
Weka handaki ndani ya kontena wakati lengo ni kutenganisha
Ikiwa kontena moja lazima litoke kupitia nodi maalum, endesha mteja katika kontena hilo. Linahitaji --cap-add NET_ADMIN na --device /dev/net/tun, na kisha linamiliki tun0 yake, njia zake na ukuta wake wa moto. Ikiwa kontena nyingine zinapita ndani yake, linahitaji pia upelekaji na kanuni ya MASQUERADE ndani ya kontena, na wenzake hao wanahitaji njia au proksi iliyo wazi inayoelekea kwake; daraja la kawaida la Docker haliongezi njia hiyo kwa ajili yako.
Mtandao wa mwenyeji, docker run --network host, ni toleo la bei nafuu: kontena linajiunga na nafasi ya majina ya mwenyeji na kuona njia za handaki moja kwa moja. Pia huacha kutenganisha mtandao, hualika migongano ya porti, na kwa vitendo ni chaguo la Linux. Porti iliyochapishwa si mbadala. -p 8080:80 hufanya huduma ifikike kutoka kwa mwenyeji; haifanyi anwani za ndani za 10.x zifikike kutoka ndani ya kontena, na kuchanganya hizo mbili ndiyo njia ambayo tatizo la upangaji njia linakuwa porti ya hifadhidata iliyo wazi.
Tofautisha kushindikana kwa jina na subnet inayopishana
Daraja la kawaida la Docker ni 172.17.0.0/16, na dimbwi nyingi za VPN za kampuni ziko ndani ya 172.16.0.0/12. Handaki linapomiliki safu hiyo, trafiki iliyokusudiwa kwa kontena inaweza kuelekezwa ndani ya handaki badala yake. Majina hushindikana, hitilafu huonekana kama DNS, na tatizo ni anwani. Angalia lengwa, si kitatuzi: ip route get 172.17.0.5 kwenye mwenyeji, kisha linganisha kiambishi cha daraja na dimbwi la VPN na docker network inspect bridge --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'.
Urekebishaji ni kuhamisha moja ya safu: ama dimbwi lingine la kawaida la anwani kwa Docker katika daemon.json au dimbwi lingine kwenye kikolezo. Kuongeza seva nyingine ya majina hakufanyi chochote hapa, na ssh -b pia haifanyi: kufunga mteja kwenye kiolesura hubadilisha anwani ya chanzo, si njia ya lengwa inayoelekea ndani ya handaki. Mgawanyo wa haraka wa kazi: jina linalotatuliwa kwenye mwenyeji lakini si ndani ya kontena ni tatizo la kitatuzi, wakati muunganisho wa moja kwa moja wa IP unaoning'inia ndani ya kontena lakini unafanya kazi kwenye mwenyeji ni tatizo la njia au mnyororo wa upelekaji.
WSL na Docker Desktop hazifuati kanuni za Linux
Katika hali yake ya kawaida ya NAT, WSL hukaa nyuma ya kirekebishaji chake pepe na haipokei njia za ndani au viambishi vya DNS vya VPN ya Windows, ndiyo sababu kivinjari kinafanya kazi na ping ndani ya usambazaji hakifanyi. Mtandao wa kioo, unaopatikana katika builds za hivi karibuni za Windows 11, hushiriki badala yake violesura vya mwenyeji, lakini lazima uwezeshwe katika .wslconfig na usambazaji uanzishwe upya kwa wsl --shutdown. Thibitisha hali inayotumika kwa wslinfo --networking-mode kabla ya kutumia urekebishaji, kwa sababu jibu la NAT si sahihi kwa hali ya kioo na kinyume chake.
Docker Desktop huongeza tabaka lingine. Kontena za Linux kwenye Windows hukaa nyuma ya utekelezaji wa NAT unaojulikana kihistoria kama vpnkit, na njia yao inatofautiana na ile ya mwenyeji asilia wa Linux. Kontena za Windows huunganishwa kupitia swichi pepe ya Hyper-V, na mteja wa kampuni anaweza kuzuia trafiki kutoka swichi hiyo, kwa hiyo kontena za Linux kwenye mashine moja zinaweza kufikia mtandao wakati kontena za Windows hazina chochote. Swichi ya nje iliyofungwa kwenye kirekebishaji halisi ndiyo suluhisho la kawaida, na hubadilisha utambulisho wa mtandao wa kontena kwa njia ambazo sera huenda haziruhusu.
Kabla ya kuandika kanuni nyingine, pita tabaka nne kwa mpangilio na usimame pale ambapo moja yao si sahihi:
- Ndani ya kontena: je,
ip routeinafikia kiambishi cha kibinafsi, na je,/etc/resolv.confinataja upstream unaotatua hilo? - Kwenye mwenyeji: upelekaji umewashwa, NAT imefungwa kwenye kiolesura cha handaki, na mnyororo wa upelekaji unakubali daraja hadi handaki?
- Kwa mwenzake: anajua njia ya kurudi, au unategemea NAT kuficha subnet ya kontena?
- Kwenye jukwaa: WSL iko katika hali ya NAT au kioo, na kontena ni Linux au Windows?
Endesha tena kila jaribio katika kontena au shell mpya. Mchakato wa muda mrefu wenye jibu lililohifadhiwa au muunganisho ulioanzishwa utaendelea kushindikana baada ya usanidi kuwa sahihi, na kushindikana huko kunaonekana sawa na urekebishaji ambao haukufanya kazi.