Odjemalec VPN se poveže, brskalnik deluje, edini ukaz, ki vas res zanima, pa še vedno odhaja skozi domačo povezavo. Ali pa se zgodi nasprotno: tunel prevzame privzeto pot in lokalni strežnik datotek izgine z namizja. To sem doživel z agentom za gradnjo, ki je moral doseči notranje zrcalo artefaktov, medtem ko je preostali gostitelj ostal v pisarniškem omrežju LAN, odjemalec pa je ponujal natanko dve možnosti, ves promet ali nič. Zahteva je v obe smeri ista, ta program in ne cel stroj, in večina odjemalcev zanjo nima potrditvenega polja, ker usmerjevalna tabela nikoli ni vedela, kaj je program.

Zakaj usmerjevalna tabela ne vidi vašega programa

Ko proces pošlje paket, sklad poišče ciljni naslov v usmerjevalni tabeli. V to iskanje ne vstopita niti ime izvršljive datoteke niti vrata. Domenska imena odpovejo iz istega razloga: tunel prenaša promet na naslov, in ko se ime razreši v naslov, je usmerjanje edini vzvod, ki ga jedro še ima. Zato »VPN samo za to spletno mesto« na koncu pomeni posrednik, »VPN samo za ta program« pa enega od majhnega nabora mehanizmov.

MehanizemKaj izberePokrivaOb padcu tunela
Vezava vtičaizvorni naslovodjemalec, ki ga nadzorujetepovezave odpovejo
Pravilo UID (Linux)lastniški uporabnikvsi procesi enega računapovezave odpovejo
Profil požarnega zidu (Windows)profil vmesnikaen programodpove zaprto
Omrežni imenski prostorčlanstvo v imenskem prostoruvse, kar se zažene znotrajpovezave odpovejo
Skok SOCKSnastavitev posrednika v aplikacijiena aplikacija ali en profil brskalnikapovezave odpovejo

Nobeno od teh ni pot za posamezni proces. Vsako prestavi odločitev v plast, ki vidi program, uporabnika ali lastno konfiguracijo aplikacije.

En sam cilj je še vedno pot, ne pravilo za program. V macOS je običajen recept odkljukati »Pošlji ves promet prek VPN« in dodati pot do gostitelja: sudo route add -host internal-tuner.example -interface ppp0, ki jo znova odstranite z sudo route delete -host internal-tuner.example -interface ppp0. Ime vmesnika preberite iz ifconfig najprej, saj je ppp0 le primer. Nadomestni znaki v poti do gostitelja ne delujejo, zato storitev, ki se pogovarja z več imeni, potrebuje en vnos na ime, pravilo pa pokriva vsak proces na stroju, ne tistega, ki ste ga imeli v mislih.

Vežite vtič na naslov tunela

Ko nadzorujete odjemalca, je vezava najcenejši izbirnik. Vtič, vezan na lokalni naslov tunela, odhaja skozi ta vmesnik, dokler tam obstaja pot do cilja, vse drugo na stroju pa ohrani običajno pot. Podrobnost je v tem, da vezava izbere izvorni naslov, medtem ko izhod še vedno izbira usmerjevalna tabela. Vezava sama ne preseli v tunel prometa, ki nima poti, in to je napaka za večino poročil »vezal sem ga, pa vseeno odhaja po napačni poti«.

import socket
s = socket.socket()
s.bind(("10.8.0.2", 0))
s.connect(("build.internal.example", 443))

Orodja višje ravni ponujajo isto zamisel: curl --interface 10.8.0.2, CURLOPT_INTERFACE v PHP in argument source_address v odjemalcih HTTP za Python. Naslov mora pripadati tunelu, tipkarska napaka pa se tu pokaže kot običajna napaka povezave, ne kot pritožba zaradi usmerjanja. Vezava na ime naprave namesto na naslov je privilegij Linuxa in se ne prenese na Windows ali macOS, zato prenosljivi skripti posredujejo naslov.

Linux: ujemajte lastnika, ne imena programa

Jedro lahko ujame lastniškega uporabnika vtiča, zato namenski račun postane izbirnik. Postavite tunel v svojo usmerjevalno tabelo in tja pošiljajte samo promet tega računa:

ip rule add uidrange 1001-1001 lookup 100
ip route add default dev tun0 table 100

To deluje le, če tunel ni že privzeta pot. Zaženite odjemalca z --route-nopull ali filtrirajte vsiljeno preusmeritev z --pull-filter ignore "redirect-gateway" na OpenVPN 2.4 in novejšem, nato vnos v tabelo dodajte sami. Sicer obstajata obe privzeti poti in zmaga tista z nižjo prioriteto. Namenjena različica tega je usmeriti privzeto pot na prehod tunela ali to storiti iz skripta za odklop: promet ostane zunaj interneta, ko tunel pade, vendar je to stikalo za izklop, ne izbirnik, in ostane, dokler ga nekdo ne odstrani.

Močnejša različica je omrežni imenski prostor. Ustvarite ga, zaženite odjemalca znotraj in aplikacijo zaženite z ip netns exec. Nič zunaj imenskega prostora ne vidi vmesnika tunela, zato aplikacija ne more po nesreči pasti nazaj na pot gostitelja. Cena je resnična: imenski prostor potrebuje par veth za dostop do fizičnega omrežja in lastno datoteko resolverja, ker imenski prostor priklopa ne deli nastavitev razreševanja imen gostitelja.

Dva načina odpovedi pojasnjujeta večino uhajanj. Razreševanje imen še vedno poteka v resolverju gostitelja, zato poizvedba odide zunaj tunela, tudi ko gre povezava TCP navznoter. In IPv6 potrebuje svoje ip -6 rule, ker pravilo v4 tega ne pokriva.

Windows in macOS: omejite požarni zid ali predajte posrednika

Tudi Windows nima izbirnika poti za posamezno aplikacijo, a pravila požarnega zidu je mogoče omejiti na profil, vmesnik VPN pa lahko uvrstite med javne, medtem ko domače omrežje LAN ostane zasebno. Ustvarite pravila za blokiranje odhodnega prometa za program v profilih Zasebno in Domena, pustite Javno odprto, in aplikacija bo dosegla omrežje le skozi tunel. Najprej nastavite kategorijo omrežja povezave, nato v nadzorni plošči požarnega zidu potrdite, da je pravilo zajelo. To je blokada, ne pot: ob padcu tunela odpove zaprto in ne more ustaviti aplikacije, ki požarni zid ignorira.

macOS sledi isti logiki z drugimi orodji. Poslušalec SOCKS, dosežen prek SSH, je najmanj invazivna možnost, saj ssh -D 1080 user@host ustvari en lokalni port in po tej poti gredo le aplikacije, nastavljene nanj. Pravilo pf lahko blokira program po uporabniku ali skupini, a še vedno ne more izbrati tunela samo za ta program. Tunnelblick sploh ne zna filtrirati po domeni, ker poti delujejo z naslovi; uporabniki OpenConnect posežejo po vpn-slice, ko strežnik pošlje preširok seznam predpon.

Dve obvoznici pokrijeta, kar orodja platforme zgrešijo. Razširitve brskalnika, ki preklapljajo posrednika po domeni, so praktičen odgovor za »samo to spletno mesto«, ker delujejo na aplikacijski ravni, kjer imena še obstajajo; pokrijejo en brskalnik in nič drugega. Groba možnost je zagnati odjemalca ponudnika v virtualnem stroju, da gost prevzame spremembo poti, gostitelj pa obdrži svojo, za ceno dveh omrežnih skladov za vzdrževanje.

Skok SOCKS za orodja brez možnosti vezave

Večino aplikacij je mogoče usmeriti na posrednika HTTP ali SOCKS, tudi če o vmesnikih ne vedo nič. Odjemalec SSH ga priskrbi brez sprememb na strežniku:

ssh -N -D 127.0.0.1:9999 [email protected]

Vse, kar je nastavljeno na ta vrata, odide skozi bastion, medtem ko preostalo namizje ohrani običajno povezavo. Lokalna instanca 3proxy, vezana na naslov tunela, stori isto za ena vrata brez SSH, stunnel pa pokrije ena vrata, ovita v TLS. Omejitve so praktične: posrednik prenaša le protokole, ki ga znajo uporabljati, UDP potrebuje pridružitev UDP SOCKS5, ki je nastavitev »SOCKS5« pri mnogih odjemalcih ne omogoči, DNS pa mora razrešiti posrednik (socks5h v curl), sicer ime uide lokalnemu resolverju.

Poslušalec pustite na loopbacku, razen če ga potrebuje drug stroj.

Pot preverite z zajemom prometa, ne s sporočilom o stanju

Okna stanja aplikacije opisujejo nastavitev, ne paket. Zajemite promet na obeh vmesnikih in primerjajte:

tcpdump -i any -n port 443
ss -tnp | grep 443

Če se povezava pojavi na fizičnem vmesniku brez ustreznega vnosa na tunelu, izbirnik ne učinkuje, ne glede na to, kaj poroča odjemalec. Ločeno preverite IPv6 in resolver ter poiščite drugo pot, na primer pomožni proces ali podedovani sistemski posrednik.

Nato izberite mejo, ki ustreza zahtevi: posrednik zadostuje za eno spletno mesto, pravilo UID za en račun, profil požarnega zidu, ko mora povezava odpovedati zaprto, imenski prostor pa je edina možnost, ki skrije tunel pred vsem zunaj njega.

Sorodni članki