Ang packet ng container ay hindi kailanman umabot sa tun0 , at ang karagdagang kakayahan sa container ay hindi ito babaguhin. Sa pagitan ng bisita at tunnel may dalawang paghahanap ng ruta: isa sa loob ng network namespace ng bisita, isa sa host pagkatapos lumapag ang frame sa tulay, at ang pangalawa ay nagtatanong sa ibang talahanayan na may ibang tuntunin sa pagtutugma. Ang reference layout ko ay isang Linux host na nagpapatakbo ng OpenVPN client na may hawak na 10.8.0.10 sa tun0 , isang tulay ng Docker sa 172.18.0.0/16 , at isang pribadong address na mahi-hit lang ng gilid ng tunnel. Nananatiling makitid ang layunin: ang subnet ng bisitang iyon ay lumalabas sa tunnel habang pinapanatili ng host ang karaniwang uplink nito.

Ang pagpapatakbo ng VPN client sa loob ng container ay ibang disenyo , hindi shortcut. Pagkatapos ang container ay nagmamay-ari ng sarili nitong tunnel at mga credential, at ang trabaho ay lumilipat sa Dockerfile sa halip na manatili sa iptables.

Pinipili ng forwarding ang ruta ayon sa destinasyon, pagkatapos isinusulat muli ng NAT ang pinagmulan

Kapag nakatakda ang net.ipv4.ip_forward=1 , ang na-forward na packet ay niruruta ayon sa destinasyon lamang, sa pangunahing talahanayan. Walang bahagi ang pinagmulan sa desisyong iyon. Pagkatapos lamang piliin ang ruta ay pinapatakbo ng kernel ang POSTROUTING , at doon nakalagay ang sariling tuntunin ng Docker: -s 172.18.0.0/16 ! -o br-appnet -j MASQUERADE . Ang lahat ng umaalis sa tulay patungo sa ibang interface ay isinasalin, at ang address na nagiging ito ay depende sa interface kung saan ito ipinadala ng ruta.

Ipinapaliwanag ng tuntuning iyon ang karamihan sa mga sintomas na itinatanong sa akin. Kung walang ruta ang pangunahing talahanayan para sa pribadong destinasyon, lumalabas ang packet sa uplink bitbit ang pisikal na address ng host. Itinatapon ng provider mo ang destinasyon, o itinatapon ng malayong site ang pinagmulang RFC 1918 na hindi nito inasahan, at nauubusan ng oras ang container habang nananatiling nakaangat at malusog ang tunnel. Walang ipinapakita ang pagkuha sa tun0 , at iyon ang palatandaan. Kung talagang tumuturo ang ruta sa tun0 , isinusulat muli ng MASQUERADE ang pinagmulan sa 10.8.0.10 , at gumagana ang parehong container nang hindi mo hinahawakan ang anuman.

Hilingin ang paghahanap na nagngangalan sa pinagmulan ng bisita. Kung wala ang from at iif sumasagot ang host para sa sarili nitong socket at nag-uulat ng landas na hindi kailanman tatahakin ng na-forward na packet:

ip route get 192.168.11.222 from 172.18.0.5 iif br-appnet

Kung pinangalanan ng sagot na iyon ang uplink, wala ang tunnel sa larawan at walang setting sa gilid ng tunnel ang makakatulong.

Ilipat ang bisita sa sariling address ng tunnel

Ang pinakamaliit na pagbabagong gumagana ay isang hayagang muling pagsulat ng pinagmulan sa paglabas. Isingit ito sa halip na idagdag: nakaupo na ang Docker sa unahan ng POSTROUTING , kaya ang tuntuning idinagdag gamit ang -A ay sinusuri sa likod ng tuntunin ng Docker at hindi kailanman pumaputok.

iptables -t nat -I POSTROUTING 1 -s 172.18.0.0/16 -o tun0 -j SNAT --to-source 10.8.0.10

Dalawang kundisyon ang nagpapasya kung mananatili ito. Ang address ay dapat isang tunay na hawak ng client, kaya i-pin ito gamit ang entry bawat client na naglalaman ng ifconfig-push 10.8.0.10 255.255.255.0 ; ang tuntuning nagngangalan sa address na hindi kailanman inilaan ay gumagawa ng tahimik na pagtatapon, hindi error. At kailangang tanggapin ng malayong gilid ang pinagmulang iyon at i-route ang mga sagot pabalik, kaya pinangalanan ng allowlist doon ang address ng tunnel at hindi ang subnet ng bisita. Kapag dynamic ang address ng client, -j MASQUERADE kasama ng -o tun0 sinusundan ang hawak ng interface, sa halaga ng malayong patakarang hindi mo maisusulat ang isang nakapirming halaga laban dito.

Ang pag-filter ang kabilang kalahati. Itinatakda ng Docker ang patakarang FORWARD sa drop at nililinis ang mga chain na pag-aari nito sa bawat restart ng daemon, kaya ilagay ang lokal na patakaran sa DOCKER-USER , na nananatili:

iptables -I DOCKER-USER -i br-appnet -o tun0 -j ACCEPT
iptables -I DOCKER-USER -i tun0 -o br-appnet -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Mahalaga ang tuntunin ng pagbabalik: ang sagot na dumarating sa tun0 para sa koneksyong binuksan ng tulay ay hindi tinatanggap dahil lang tinanggap ang direksyong palabas.

Panatilihing direkta ang host gamit ang tuntunin ng pinagmulan

Kapag dapat gamitin ng buong tulay ang tunnel pero wala nang iba sa host, laktawan ang NAT at bigyan ang pinagmulang iyon ng sariling talahanayan. Nananatiling nakikita ang mga address ng bisita mula simula hanggang wakas.

echo "200 vpnbox" >> /etc/iproute2/rt_tables
ip rule add from 172.18.0.0/16 lookup vpnbox pref 1000
ip route add default dev tun0 table vpnbox

Ang mga tuntunin ay kinukumusta bago ang pangunahing talahanayan, at from tumutugma sa pinagmulan. Ang sariling panlabas na packet ng tunnel ay bitbit ang pisikal na pinagmulan ng host, kaya hindi kailanman tumutugma sa from 172.18.0.0/16 , at hindi maaaring i-route ng tunnel ang sarili nito pabalik sa sarili nito. Ang pagbubukod-sa-sarili na iyon ang nagpapatatag sa layout.

Kailangan na ngayon ng tulong ang pabalik na landas. Nakikita ng malayong gilid ang 172.18.0.x na hindi isinalin at walang dahilan para malaman kung saan ito nakatira. Sa server, kailangan ng file bawat client ang iroute 172.18.0.0 255.255.0.0 upang maibigay ng panloob na talahanayan ng server ang prefix na iyon sa client na ito, at ng itinulak na route 172.18.0.0 255.255.0.0 upang malaman ng ibang client na mayroon ito.

Dalawang pagsusuri bago ito pagkatiwalaan. Patakbuhin ang ip route show default : kasama ng redirect-gateway def1 hawak ng talahanayan ang 0.0.0.0/1 at 128.0.0.0/1 sa pamamagitan ng tun0 , at ang host ay hindi talaga direkta, dahil pananalo ng mga kalahati-default na iyon nang hindi pinapalitan ang default . Ang mga tuntuning idinagdag gamit ang ip rule add ay nawawala rin sa reboot, kaya dalhin ang mga ito sa isang up script.

Ang laki ng packet ang ikalawang pagkabigo na makakaharap mo

Ang interface ng tulay sa 1500 bytes ay nagbibigay sa tunnel ng higit sa kaya nitong bitbitin kapag naidagdag ang panlabas na UDP at IP header. Dumadaan ang maliliit na palitan, kaya nareresolba ang DNS at natatapos ang TLS handshake, pagkatapos ay nag-hang ang mas malaking upload nang walang error kahit saan. Paulit-ulit na sinusubukan ng nagpapadala ang parehong laki ng segment dahil ang mensahe ng ICMP tungkol sa pangangailangan ng fragmentation, na magsasabi sa kanya na bawasan, ay hindi kailanman dumarating.

Ayusin ito sa interface, sa MSS, o pareho. Ang clamping ay hindi nangangailangan ng pakikipagtulungan ng bisita:

ip link set dev tun0 mtu 1400
iptables -t mangle -A FORWARD -o tun0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Ang clamp ay nagsusulat muli ng TCP lamang. Ang UDP, kasama ang QUIC, ay nangangailangan sa halip ng mas mababang interface ng bisita, gamit ang --opt com.docker.network.driver.mtu=1400 sa paggawa ng network o ang tugmang compose na tumutugma.

DNS at ang mga pagsusuring sulit ulitin

Ang resolusyon ng pangalan ay sumusunod sa parehong landas. Ang naka-embed na resolver ng Docker sa 127.0.0.11 ay nagpapasa sa mga naka-configure na server ng host, kaya namamana ng container ang ginagamit ng host. Kapag ang pribadong zone ay sinasagot lamang ng resolver na maabot sa tunnel, ituro ang bisita sa address na iyon, at subukan gamit ang getent hosts sa loob ng container at hindi sa host.

  • Patakbuhin ang nabibigong kahilingan sa loob ng bisita; ang pagsubok sa gilid ng host ay gumagamit ng ibang pinagmulang address at itinatago ang problema.
  • Basahin ang mga counter sa mga tuntunin ng NAT at filter na idinagdag mo. Ang tuntuning walang tugma ay pagkakamali sa routing, hindi sa patakaran.
  • Kumpirmahin na ang address ng tunnel sa iyong tuntunin ng SNAT ay isang tunay na hawak ng client.
  • Bawasan ang MTU ng bisita o i-clamp ang MSS bago sisihin ang server sa paghinto.

Sundan ang listahang iyon at huminto sa unang pagkabigo. Ang layer na iyon ang dapat ayusin; anumang idinagdag sa ibaba ay nagtatago lamang ng hangganang nasisira.

Kaugnay na mga artikulo