Klient VPN sa pripojí, prehliadač funguje a jediný príkaz, na ktorom vám naozaj záleží, stále odchádza cez domáce pripojenie. Alebo to je naopak: tunel si vezme predvolenú trasu a lokálny súborový server zmizne z pracovnej plochy. Zažil som to s build agentom, ktorý sa potreboval dostať k internej zrkadlovej kópii artefaktov, kým zvyšok hostiteľa zostal v kancelárskej LAN, a klient ponúkal presne dve možnosti, celú prevádzku alebo nič. Požiadavka je v oboch smeroch rovnaká, táto aplikácia a nie celý stroj, a väčšina klientov na ňu nemá zaškrtávacie pole, pretože smerovacia tabuľka nikdy nevedela, čo je program.

Prečo smerovacia tabuľka nevidí váš program

Keď proces odošle paket, zásobník vyhľadá cieľovú adresu v smerovacej tabuľke. Ani názov spustiteľného súboru, ani port do tohto vyhľadávania nevstupujú. Doménové názvy zlyhávajú z rovnakého dôvodu: tunel prepravuje prevádzku na adresu a v čase, keď sa názov preloží na adresu, je smerovanie jedinou pákou, ktorú jadro ešte má. Preto „VPN iba pre tento web“ napokon znamená proxy a „VPN iba pre tento program“ znamená jeden z malej množiny mechanizmov.

MechanizmusČo vyberáPokrývaPri páde tunela
Priradenie socketuzdrojová adresaklient, ktorého ovládatespojenia zlyhajú
Pravidlo UID (Linux)vlastniaci používateľvšetky procesy jedného účtuspojenia zlyhajú
Profil firewallu (Windows)profil adaptérajeden programzlyhá v zatvorenom stave
Sieťový menný priestorčlenstvo v mennom priestorevšetko spustené vnútrispojenia zlyhajú
Skok SOCKSnastavenie proxy v aplikáciijedna aplikácia alebo jeden profil prehliadačaspojenia zlyhajú

Žiadne z nich nie je trasa pre jednotlivý proces. Každé presúva rozhodnutie do vrstvy, ktorá vidí program, používateľa alebo vlastnú konfiguráciu aplikácie.

Jediný cieľ je stále trasa, nie pravidlo pre program. V macOS je zvyčajný postup odškrtnúť „Posielať všetku prevádzku cez VPN“ a pridať trasu k hostiteľovi: sudo route add -host internal-tuner.example -interface ppp0, ktorú zase odstránite pomocou sudo route delete -host internal-tuner.example -interface ppp0. Prečítajte si názov rozhrania z ifconfig najprv, pretože ppp0 je len príklad. Zástupné znaky v trase k hostiteľovi nefungujú, takže služba, ktorá komunikuje s viacerými názvami, potrebuje jeden záznam pre každý názov, a pravidlo pokrýva každý proces na stroji, nie ten, ktorý ste mali na mysli.

Priraďte socket k adrese tunela

Keď klienta ovládate, priradenie je najlacnejší selektor. Socket priradený k lokálnej adrese tunela odchádza cez toto rozhranie, pokiaľ tam existuje trasa k cieľu, a všetko ostatné na stroji si zachová svoju obvyklú cestu. Jemnosť je v tom, že priradenie vyberá zdrojovú adresu, kým odchod stále vyberá smerovacia tabuľka. Samotné priradenie nepresunie do tunela prevádzku, ktorá nemá trasu, a to je chyba za väčšinou hlásení „priradil som to a aj tak to odchádza nesprávnou cestou“.

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

Nástroje vyššej úrovne ponúkajú ten istý nápad: curl --interface 10.8.0.2, CURLOPT_INTERFACE v PHP a argument source_address v HTTP klientoch Pythonu. Adresa musí patriť tunelu a preklep sa tu prejaví ako obyčajná chyba spojenia, nie ako sťažnosť na smerovanie. Priradenie k názvu zariadenia namiesto adresy je privilégium Linuxu a neprenáša sa na Windows ani macOS, preto prenosné skripty odovzdávajú adresu.

Linux: zhodujte sa s vlastníkom, nie s názvom programu

Jadro dokáže porovnať vlastniaceho používateľa socketu, takže vyhradený účet sa stáva selektorom. Umiestnite tunel do vlastnej smerovacej tabuľky a posielajte tam iba prevádzku tohto účtu:

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

Toto funguje len vtedy, ak tunel už nie je predvolenou trasou. Spustite klienta s --route-nopull alebo odfiltrujte vynútené presmerovanie pomocou --pull-filter ignore "redirect-gateway" na OpenVPN 2.4 a novšom, a potom záznam v tabuľke pridajte sami. Inak existujú obe predvolené trasy a vyhráva tá s nižšou prioritou. Zámernou verziou toho je nasmerovať predvolenú trasu na bránu tunela alebo to urobiť z odpojovacieho skriptu: udrží prevádzku mimo internetu, keď tunel padne, ale to je kill switch, nie selektor, a zostáva, kým ho niekto neodstráni.

Silnejšia verzia je sieťový menný priestor. Vytvorte ho, spustite klienta vnútri a aplikáciu naštartujte cez ip netns exec. Nič mimo menného priestoru nevidí rozhranie tunela, takže aplikácia nemôže omylom skončiť na trase hostiteľa. Cena je reálna: menný priestor potrebuje pár veth na prístup k fyzickej sieti a vlastný súbor resolvera, pretože menný priestor pripojenia nezdieľa nastavenia prekladu názvov hostiteľa.

Dva režimy zlyhania vysvetľujú väčšinu únikov. Preklad názvov stále prebieha v resolveri hostiteľa, takže dotaz odchádza mimo tunela, aj keď TCP spojenie ide dovnútra. A IPv6 potrebuje vlastné ip -6 rule, pretože pravidlo v4 ho nepokrýva.

Windows a macOS: obmedzte firewall alebo odovzdajte proxy

Ani Windows nemá selektor trasy pre jednotlivú aplikáciu, ale pravidlá firewallu možno obmedziť na profil a adaptér VPN možno zaradiť do profilu Verejný, kým domáca LAN zostáva Privátna. Vytvorte pravidlá blokovania odchodu pre program v profiloch Privátny a Doména, nechajte Verejný otvorený a aplikácia sa dostane do siete iba cez tunel. Najprv nastavte kategóriu siete pripojenia, potom v monitorovacej table firewallu overte, že pravidlo zabralo. Je to blokovanie, nie trasa: pri páde tunela zlyhá v zatvorenom stave a nedokáže zastaviť aplikáciu, ktorá firewall ignoruje.

macOS postupuje podľa rovnakej logiky s inými nástrojmi. SOCKS listener dostupný cez SSH je najmenej invazívna možnosť, pretože ssh -D 1080 user@host vytvorí jeden lokálny port a touto cestou idú len aplikácie nastavené na jeho používanie. Pravidlo pf dokáže zablokovať program podľa používateľa alebo skupiny, ale stále nevie vybrať tunel iba pre ten program. Tunnelblick nevie filtrovať podľa domény vôbec, pretože trasy pracujú s adresami; používatelia OpenConnect siahnu po vpn-slice, keď server posiela príliš široký zoznam predpôn.

Dve obchádzky pokrývajú to, čo nástroje platformy nezvládnu. Rozšírenia prehliadača, ktoré prepínajú proxy podľa domény, sú praktickou odpoveďou na „iba tento web“, pretože pôsobia na aplikačnej vrstve, kde názvy ešte existujú; pokrývajú jeden prehliadač a nič iné. Hrubou možnosťou je spustiť klientsky program dodávateľa vo virtuálnom stroji, aby hosť vlastnil zmenu trasy, kým hostiteľ si zachová svoju cestu, za cenu dvoch sieťových zásobníkov na údržbu.

Skok SOCKS pre nástroje bez možnosti priradenia

Väčšinu aplikácií možno nasmerovať na HTTP alebo SOCKS proxy, aj keď o rozhraniach nevedia nič. SSH klient poskytne jeden bez zmeny na strane servera:

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

Čokoľvek nastavené na tento port odchádza cez bastion, kým zvyšok pracovnej plochy si zachováva obvyklé pripojenie. Lokálna inštancia 3proxy priradená k adrese tunela robí to isté pre jeden port bez SSH a stunnel pokrýva jediný port zabalený do TLS. Obmedzenia sú praktické: proxy prenáša len protokoly, ktoré ho vedia použiť, UDP potrebuje UDP asociáciu SOCKS5, ktorú nastavenie „SOCKS5“ mnohých klientov nezapína, a DNS musí prekladať proxy (socks5h v curl), inak názov unikne lokálnemu resolveru.

Nechajte listener na loopbacku, ak ho nepotrebuje iný stroj.

Overte cestu zachytením prevádzky, nie správou o stave

Okná stavu aplikácie opisujú nastavenie, nie paket. Zachyťte prevádzku na oboch rozhraniach a porovnajte:

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

Ak sa spojenie objaví na fyzickom rozhraní bez zodpovedajúceho záznamu na tuneli, selektor neúčinkuje, nech klient hlási čokoľvek. Skontrolujte oddelene IPv6 a resolver a hľadajte druhú cestu, napríklad pomocný proces alebo zdedenú systémovú proxy.

Potom vyberte hranicu, ktorá zodpovedá požiadavke: proxy stačí na jeden web, pravidlo UID stačí na jeden účet, profil firewallu stačí, keď spojenie musí zlyhať v zatvorenom stave, a menný priestor je jediná možnosť, ktorá skryje tunel pred všetkým vonku.

Súvisiace články