Hindi mo maaaring ihiwalay ang isang programa mula sa isang WireGuard host na may buong tunnel sa pamamagitan ng pag-edit ng mga ruta. Pumipili ang mga ruta ng landas ayon sa destinasyon, at ang gusto mong ihiwalay ay isang proseso, kaya wala ang kernel na maihahambing. Ang gumaganang paraan ay bigyan ang prosesong iyon ng sarili nitong konteksto ng network: isang namespace na may sariling interface, mga address at default na ruta, na konektado sa host sa pamamagitan ng isang pares na veth. Pinatakbo ko ito sa Ubuntu 24.04 gamit ang wireguard-tools 1.0.20210914, at hindi kailanman naging problema ang namespace — ang patakaran sa pagpapasa ng host at ang mga patakaran sa pagmamarka ng tunnel ang problema.

Piliin muna ang uri ng konteksto na kailangan mo

Sa pagsasagawa, dalawang anyo ang lumilitaw. Kung ang host ay nagpapatakbo ng buong tunnel at isang programa ang kailangang lumabas sa landas ng ISP, gagawa ka ng pangalawang namespace, ikokonekta ito sa host at hahayaan ang host na ipasa at isalin ang trapiko para dito. Kung ang isang namespace ay mayroon nang interface ng VPN at kailangan mo lang ng utos na sinimulan sa loob nito, iyon ang karaniwang ip netns exec na kaso at karamihan ng gawain sa pagruruta ay tapos na.

Wala sa mga anyo ang nagbibigay sa iyo ng patakarang limitado sa isang process ID. Tinutugma ng Netfilter ang mga address, port, marka at interface; walang routing table para sa bawat proseso. Maaaring idirekta ng pagmamarka ang trapiko, ngunit ang marka ay dapat ilagay sa mga packet na natukoy mo na, at iyon din ang problemang isang patong sa ibaba. Hinihiwalay ng namespace ang buong stack para sa puno ng mga prosesong iyon, at iyon ang dahilan kung bakit ito ang karaniwang sagot.

Kung ang pangangailangan ay talagang walang lumalabas sa tunnel, itigil ang tunnel sa halip. Umiiral ang namespace para sa halo-halong kaso: isang programa sa labas, lahat ng iba sa loob, sa parehong makina, sa parehong oras.

Buuin ang pangalawang konteksto at ikonekta ito sa host

Isang nakapagpapalarawang kaayusan: may interface ng WireGuard ang host na nagdadala ng default na ruta, at may namespace ng network na tinatawag na clearnet na konektado sa host sa pamamagitan ng pares na veth. Ang mga address sa ibaba ay mga halimbawa.

ip netns add clearnet
ip link add veth-clear-out type veth peer name veth-clear-in
ip addr add 192.168.100.1/24 dev veth-clear-out
ip link set veth-clear-out up
ip link set veth-clear-in netns clearnet
ip netns exec clearnet ip addr add 192.168.100.2/24 dev veth-clear-in
ip netns exec clearnet ip link set veth-clear-in up
ip netns exec clearnet ip route add default via 192.168.100.1

Naabot na ng namespace na iyon ang host at wala nang iba. Dapat ipasa ng host ang trapiko at muling isulat ang source address, dahil pribado ang 192.168.100.0/24 at walang ruta pabalik dito ang router sa itaas:

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o <wan-interface> -j MASQUERADE

Kumpirmahin ang panig ng namespace bago magpatuloy.ip netns exec clearnet ip route ay dapat magpakita ng rutang veth at ng default na ruta sa pamamagitan ng 192.168.100.1, at ang ping sa address na iyon ay dapat tumugon. Kung mabigo ang ping sa address ng host, mali ang mga address o ang estado ng link at walang patakaran ng firewall na makakatulong.

Kapag nalutas ang mga pangalan ngunit walang bumabalik, basahin ang FORWARD

Ang klasikong kabiguan ay mukhang bug sa pagruruta: nilulutas ng namespace ang isang pangalan, lumalabas ang packet at kailanman ay walang dumarating na sagot. Sa mga host na may patakarang FORWARD na DROP — ginagawa ito ng ilang distribusyon at ng karamihan sa mga pinatigas na image — itinatapon ang packet sa daan, at walang sinasabi ang error na inilalathala ng aplikasyon tungkol sa pag-filter.

Basahin ang chain bago magdagdag ng anuman:

iptables -S FORWARD
nft list chain inet filter forward

Pagkatapos ay payagan ang trapiko sa dalawang direksyon, may mga counter, upang malaman mo kung tumugma kailanman ang patakaran:

iptables -A FORWARD -i veth-clear-out -o <wan-interface> -j ACCEPT
iptables -A FORWARD -i <wan-interface> -o veth-clear-out -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
watch -n1 'iptables -L FORWARD -v -n'

Ang patakarang may sero na counter ng packet ay wala sa landas. Alinman sa iba ang mga pangalan ng interface kaysa sa inakala mo, o may naunang patakaran sa chain na tumanggap, nagtapon o nagbalik ng packet nang una. Ayusin ang pagkakasunod-sunod, hindi ang teksto ng patakaran.

Ang trapikong pang-sagot ang kalahating nakakalimutan ng mga tao. Kailangan ng patakaran sa pagbabalik ng parehong pangalan ng veth at tugma sa estado ng koneksyon, o simpleng pagtanggap ng interface kung pinananatili mong bukas ang patakaran. Idagdag lamang ang palabas na patakaran at bumabalik ang orihinal na sintomas, habang nakatayo roon ang bago mong patakaran at mukhang tama.

Ilayo ang mga patakaran sa pagmamarka ng tunnel mula sa bagong landas

Ginagawa ng hakbang na ito na tumutulo ang isang gumaganang namespace. Karaniwang naglalagay ang mga setup ng WireGuard ng patakaran sa marka ng firewall kasama ng sarili nilang mga patakaran sa pagruruta at isang nakalaang table, kaya bumabalik sa pangunahing table ang mga packet na walang marka habang ginagamit ng mga may marka ang table ng tunnel. Ang trapikong ipinasa mula sa namespace ay sinusuri laban sa policy routing paglabas, at depende sa kung paano isinulat ang mga patakarang iyon, maaari itong mahulog sa table ng tunnel.

Dalawang dagdag ang naghihiwalay ng mga landas. Bumalik nang maaga sa chain ng mangle para sa subnet ng namespace, at magdagdag ng patakarang nakabatay sa source na naglalagay sa subnet na iyon sa pangunahing table:

iptables -t mangle -I PREROUTING -s 192.168.100.0/24 -j RETURN
ip rule add from 192.168.100.0/24 lookup main priority 100

Ang priority 100 ay nauuna sa mga patakaran ng tunnel sa host ko, kaya para sa source na iyon ang ordinaryong table ang nagpapasya. Huwag kopyahin nang bulag ang numero: ang mga priority na wg-quick ini-install ay nagkakaiba sa pagitan ng mga bersyon at sa pagitan ng mga setup ng IPv4 at IPv6, kaya patakbuhin ang ip rule show at pumili ng priority na nahuhulog bago ang mga patakaran ng tunnel sa iyong makina.

I-verify gamit ang paghahanap na partikular sa source sa halip na magtiwala sa listahan ng patakaran:

ip route get 1.1.1.1 from 192.168.100.2
ip netns exec clearnet ip route get 1.1.1.1

Kung iniuulat ng unang utos ang interface ng WireGuard, wala pa sa unahan ng patakaran ng tunnel ang bagong patakaran. Kung iniuulat nito ang interface ng WAN habang ipinapakita pa rin ng pangalawa ang default na rutang veth, hindi nagkakasundo ang host at ang namespace at dapat mong basahin muli ang dalawang routing table.

Simulan ang prosesong nagbubukas ng koneksyon

Ang paglunsad ng utos ay isang linya, ngunit simulan ang prosesong talagang gumagawa ng socket.ip netns exec clearnet curl -s https://ifconfig.me ang pinakamaliit na tapat na pagsubok: ipinapakita nito ang address na inihaharap ng namespace sa mundo, hindi ang gagamitin ng host.

Para sa isang serbisyo, ikabit ang namespace ayon sa landas upang manatili rito ang proseso sa buong buhay nito:

[Service]
NetworkNamespacePath=/run/netns/clearnet

Ang mga grapikong aplikasyon ang lugar kung saan tahimik na nabibigo ang paraang isang linya. Ang browser na inilunsad mula sa menu ay madalas na ibinibigay ang kahilingan sa isang instance na tumatakbo na sa labas ng namespace, kaya lumilitaw ang bagong window at lumalabas pa rin ang trapiko sa tunnel. Bigyan ito ng hiwalay na profile upang tunay na malikha ang bagong instance, pagkatapos ay suriin ang konteksto ng proseso sa halip na manghula:

readlink /proc/$(pgrep -f clearnet-profile | head -1)/ns/net
readlink /run/netns/clearnet

Dapat magtugma ang dalawang output. Gumagana ang parehong pagsusuri para sa anumang matagalang programa, at sulit itong gawin isang beses sa bawat aplikasyon sa halip na ipagpalagay na ginawa ng launcher ang ibig mong sabihin.

Kailangan ng resolusyon ng pangalan ang sarili nitong pasya. Ang paggawa ng namespace ay hindi nagbibigay nito ng konfigurasyon ng resolver; ang mga file sa bawat namespace ay sinusuportahan sa pamamagitan ng /etc/netns/<name>/resolv.conf at kung wala iyon ay namamana ka ng pag-uugaling madaling mabasa nang mali. Kailangan ng IPv6 ang parehong pagtrato: kung walang default na rutang v6 ang namespace habang mas gusto ng aplikasyon ang v6, maaaring mag-hang ang mga kahilingan bago bumalik, na mukhang sirang tunnel.

Suriin ang balangkas, hindi lamang ang address ng labasan

Ang gumaganang pampublikong address ay nagpapatunay ng ruta, hindi ng buong pangangailangan. Dumaan sa natitira sa ganitong pagkakasunod-sunod:

  • ip netns exec clearnet ip route get 1.1.1.1 ay nagpapakita ng default na rutang veth, hindi ng interface ng WireGuard.
  • Tumataas ang mga counter ng FORWARD sa dalawang patakaran habang tumatakbo ang isang kahilingan.
  • Iniuulat ng proseso ng aplikasyon ang inode ng namespace na inaasahan mo.
  • Pagkatapos ng reboot, umiiral ang namespace bago magsimula ang serbisyo; ang unit na tumatakbo nang mas maaga ay nabibigo o, mas masahol pa, tumatakbo sa labas ng namespace.

Pagkatapos ay magpasya kung ano ang dapat mangyari kapag bumagsak ang tunnel. Patuloy na gumagana ang namespace, at iyon ang punto ng pagsasanay at gayundin ang panganib: nananatiling konektado ang inihiwalay na programa habang humihinto ang lahat ng iba. Itala iyon bilang pagpiling patakaran at maging malinaw sa hindi saklaw ng paghihiwalay — ang pagkakakilanlan ng account, ang naka-save na estado ng browser at ang iyong DNS provider ay pawang nasa labas ng saklaw ng isang namespace ng network, at ang ituring ang paghihiwalay bilang anonymity ay ang pagkakamaling mas matagal kaysa sa konfigurasyon.

Kaugnay na mga artikulo