Isang ruta palabas ng workstation na ito ay isang SOCKS proxy, at ang OpenVPN sa likod nito ay nag-uulat ng connect timeout na walang kapaki-pakinabang na detalye. Gumagana ang browser sa parehong makina sa pamamagitan ng proxy na iyon, tama ang mga kredensyal, at sumasagot ang port. Tatlong bagay ang madalas na naiiba nang sapat para unahing suriin: ang bersyon ng SOCKS na sinasalita ng proxy, ang transport na pinili ng client, at kung saan nangyayari ang paglutas ng pangalan. Tiyakin ang bawat isa bago magpasya na ang firewall ang may kasalanan.

Itugma ang Bersyon ng SOCKS Bago ang Firewall

Nagsasalita ang community OpenVPN ng SOCKS5 para sa socks-proxy. Ituro ito sa proxy na nag-aalok lamang ng SOCKS4 at bubukas ang TCP connection, pagkatapos ay titigil, dahil hinihintay ng client ang sagot sa isang pagbati na hindi kailanman binabasa ng kabilang dulo. Mula sa labas, ang pagtigil na iyon ay mukhang port na na-filter, kaya nauuna ang tanong sa bersyon sa anumang firewall rule. Isang fetch na may kaalaman sa SOCKS ang magpapasya nito sa isang utos.

curl --socks5-hostname 127.0.0.1:9050 gw.lab.example

Ang kumpletong kahilingan ay nagpapatunay ng dalawang bagay nang sabay: tinanggap ng proxy ang SOCKS request at nilutas nito ang pangalan. Walang kailangang URL scheme, dahil itinuturing ng curl ang hubad na host bilang HTTP, sapat na para sa pagsubok na ito.

Inaalis din ng fetch na iyon ang pagkasira na itinatago ng client log. Maaaring payagan ng proxy ang browser at tanggihan pa rin ang VPN destination, at sa ganoong kaso nangyayari ang pagtanggi sa CONNECT, bago ang anumang VPN authentication. Timeout lang ang iniuulat ng OpenVPN, kaya ang sagot mismo ng proxy ang ebidensyang kailangan mo.

Dapat TCP ang Transport sa Magkabilang Panig

Nagdadala ang SOCKS5 ng TCP stream dito, kaya ang tunnel mismo ay nangangailangan ng proto tcp-client. Ang profile na nakatakda pa rin sa UDP ay hindi gagana sa rutang ito, dahil hindi ginagamit ng client ang UDP association mode ng protocol. Ang pagbaliktad ng profile ay tunay na pagbabago at hindi pormalidad: kailangang makinig ang far end sa TCP sa parehong port. Pagkatapos ang payload ay nagiging TCP sa loob ng TCP, kung saan ang nawalang segment ay muling ipinapadala nang dalawang beses at bumababa ang pacing, na mas kapansin-pansin sa mga interactive session kaysa sa malalaking transfer.

proto tcp-client
remote gw.lab.example 8443
socks-proxy 127.0.0.1 9050

Kinukuha ng directive ang proxy host, opsyonal na port at opsyonal na credentials file. Ilagay ang mga iyon sa profile mismo para magkapareho ang kilos ng isang kopya sa ibang lugar.

Isara ang Buong Chain sa Isang Container

Ang gawin ang chain sa host ay nangangahulugang sakupin ang default route nito at iwanan ang resolver sa estadong walang makapagpapaliwanag mamaya. Nililimitahan ito ng namespace o container sa halip, kaya pinapanatili ng host ang sariling ruta habang magkasamang nabubuhay ang SOCKS hop at ang tunnel. Walang tumatayo sa loob nito nang walang tunnel device, mga karapatan para i-configure ang device na iyon, at maaabot na proxy. Nakukuha ito ng isang Compose service sa cap_add: NET_ADMIN at isang bind-mounted na /dev/net/tun.

cap_add:
  - NET_ADMIN
devices:
  - /dev/net/tun:/dev/net/tun

Mas makitid ang pares na iyon kaysa sa pagpapatakbo ng container nang privileged, at iyon ang buong pag-access sa device na kailangan. Maaaring magbigay ng listener ang isang Tor client o hiwalay na proxy container. Sa alinmang kaso, i-bind ito sa loopback, at abutin mula sa namespace sa pamamagitan ng host sa halip na ilantad ang proxy sa network.

Ang Paglutas ng Pangalan ang Lugar Kung Saan Nabibigo ang Isolation

Ang tunnel na nagdadala ng packet habang nagtatanong sa resolver ng host ay walang naisarang anuman. Dalawang bagay ang nagpapaging totoo sa isolation: may sariling resolver ang namespace, at dumadaan ang mga query nito sa proxy o tunnel, hindi kailanman sa pisikal na interface. Gumamit ng dalawang pangalan sa pagsubok: isa na umiiral lamang sa likod ng tunnel, at isang pampubliko na dapat sumunod sa parehong ruta.

docker compose exec vpn cat /etc/resolv.conf
docker compose exec vpn getent hosts internal.lab.example

Kung nalutas ang pangalan sa kalayuan at hindi ang pampubliko, ang chain ay pili at hindi sira, at sinasabi ng pagkakaiba kung aling ruta ang tinahak ng bawat query. Kung parehong nalutas mula sa host ngunit wala ang nalutas sa loob ng container, hiniram pa rin ng container ang resolver ng host. Itala ang resolver file na natagpuan, dahil iyon ang setting na dapat baguhin.

Patunayan ang Bawat Hop sa Ayos

Maikli ang listahan. May sagot ang isang SOCKS5 request, naaabot ng tunnel ang listener nito sa pamamagitan ng proxy, at ang mga packet na lumalabas sa namespace ay may address na inaasahan ng far side. Tiyakin ang bawat isa nang isa-isa sa halip na magdagdag pa ng configuration. Kapag sinabi ng client na konektado at walang gumagalaw, ang putol ay halos palaging nasa ikalawa o ikatlong katotohanan.

curl --socks5-hostname 127.0.0.1:9050 gw.lab.example
docker compose exec vpn ip route get 203.0.113.10
docker compose exec vpn getent hosts internal.lab.example

Isulat ang kombinasyong gumana: bersyon ng SOCKS, transport, resolver at mga setting ng namespace. Ang lutasin muli ang chain na ito mula sa memorya ay mas mahal kaysa sa tala. Itago ang apat na katotohanang iyon sa ticket at hindi sa chat thread.

Ang chain na nag-uulat ng konektado at walang naipapasa ay kadalasang nabigo sa hop na hindi mo pa napatunayan. Subukan ang hop na iyon bago magdagdag ng isa pang layer.

Kaugnay na mga artikulo