Kuidas suunata üks rakendus VPN-i kaudu ilma kogu masinata
Ükski haldamata töölaud ei paku protsessipõhist VPN-i lülitit. Valige kiht, mis valib liiklust: seotud socket, UID-reegel, tulemüüri profiil või SOCKS-hüpe.
VPN-klient ühendub, brauser töötab ja see üks käsk, millest tegelikult hoolite, väljub ikka teie koduse ühenduse kaudu. Või juhtub vastupidine: tunnel haarab vaikimisi marsruudi ja kohalik failiserver kaob töölaualt. Puutusin sellega kokku ehitusagendiga, mis pidi jõudma sisemise artefaktide peeglini, samal ajal kui ülejäänud host jäi kontori LAN-i, ja klient pakkus täpselt kahte valikut: kogu liiklus või mitte midagi. Taotlus on mõlemas suunas sama, see programm ja mitte kogu masin, ja enamikul klientidel pole selle jaoks märkeruutu, sest marsruutimistabel pole kunagi teadnud, mis on programm.
Miks marsruutimistabel ei näe teie programmi
Kui protsess saadab paketi, otsib virn sihtkoha aadressi marsruutimistabelist. Sellesse otsingusse ei lähe ei täitmisfaili nimi ega port. Domeeninimed ebaõnnestuvad samal põhjusel: tunnel viib liikluse aadressile ja kui nimi on aadressiks lahendatud, on marsruutimine ainus hoob, mis tuumal veel on. Seetõttu tähendab „VPN ainult sellele saidile“ lõpuks puhverserverit ja „VPN ainult sellele programmile“ üht väikesest mehhanismide hulgast.
| Mechanism | What selects | Covers | On tunnel drop |
|---|---|---|---|
| Socket bind | source address | a client you control | connections fail |
| UID rule (Linux) | owning user | every process of one account | connections fail |
| Firewall profile (Windows) | adapter profile | one program | fails closed |
| Network namespace | namespace membership | everything started inside | connections fail |
| SOCKS hop | app proxy setting | one app or one browser profile | connections fail |
Ükski neist ei ole protsessipõhine marsruut. Igaüks viib otsuse kihile, mis näeb programmi, kasutajat või rakenduse enda konfiguratsiooni.
Üks sihtkoht on ikka marsruut, mitte programmireegel. macOS-is on tavaline retsept võtta maha linnuke „Saada kogu liiklus VPN-i kaudu“ ja lisada hostimarsruut: sudo route add -host internal-tuner.example -interface ppp0, mis eemaldatakse uuesti käsuga sudo route delete -host internal-tuner.example -interface ppp0. Lugege esmalt liidese nimi väljundist ifconfig, sest ppp0 on ainult näide. Metamärgid hostimarsruudil ei tööta, seega teenus, mis räägib mitme nimega, vajab ühte kirjet iga nime kohta, ja reegel katab iga protsessi masinas, mitte seda, mida silmas pidasite.
Siduge socket tunneli aadressiga
Kui kontrollite klienti, on sidumine odavaim valija. Tunneli kohaliku aadressiga seotud socket väljub selle liidese kaudu seni, kuni sinna on sihtkoha marsruut olemas, ja kõik muu masinas säilitab oma tavapärase tee. Peensus on selles, et sidumine valib lähteaadressi, samal ajal kui marsruutimistabel valib endiselt väljapääsu. Üksi sidumine ei liiguta liiklust, millel pole tunnelisse marsruuti, ja just see viga on enamiku „sidusin selle ära ja ikka läheb valele poole“ teadete taga.
import socket
s = socket.socket()
s.bind(("10.8.0.2", 0))
s.connect(("build.internal.example", 443))Kõrgema taseme tööriistad pakuvad sama ideed: curl --interface 10.8.0.2, PHP-s CURLOPT_INTERFACE ja argument source_address Pythoni HTTP-klientides. Aadress peab kuuluma tunnelile ja trükiviga siin ebaõnnestub tavalise ühendusveana, mitte marsruutimiskaebusena. Seadme nimele aadressi asemel sidumine on Linuxi eesõigus ega kandu üle Windowsi ega macOS-i, seepärast edastavad kaasaskantavad skriptid aadressi.
Linux: sobitage omanik, mitte programmi nimi
Tuum suudab sobitada socketi omanikku, seega saab spetsiaalne konto valijaks. Pange tunnel oma marsruutimistabelisse ja saatke sinna ainult selle konto liiklus:
ip rule add uidrange 1001-1001 lookup 100
ip route add default dev tun0 table 100See töötab ainult siis, kui tunnel pole juba vaikimisi marsruut. Käivitage klient valikuga --route-nopull või filtreerige lükatud ümbersuunamine valikuga --pull-filter ignore "redirect-gateway" OpenVPN 2.4 ja uuemates, seejärel lisage tabelikirje ise. Muidu on mõlemad vaikimisi marsruudid olemas ja võidab madalama prioriteediga. Selle teadlik versioon on suunata vaikimisi marsruut tunneli lüüsile või teha seda katkestamisskriptist: see hoiab liikluse internetist eemal, kui tunnel kukub, aga see on hädaseiskamislüliti, mitte valija, ja jääb püsima, kuni keegi selle eemaldab.
Tugevam versioon on võrgu nimeruum. Looge see, käivitage klient selle sees ja käivitage rakendus valikuga ip netns exec. Väljaspool nimeruumi ei näe miski tunneli liidest, seega ei saa rakendus kogemata hosti marsruudile tagasi langeda. Hind on tegelik: nimeruum vajab füüsilise võrgu saavutamiseks veth-paari ja oma resolverifaili, sest paigaldusnimeruum ei jaga hosti lahendussätteid.
Kaks rikkerežiimi selgitavad enamikku leketest. Nimede lahendamine toimub endiselt hosti resolveris, seega väljub päring tunnelist välja ka siis, kui TCP-ühendus läheb sisse. Ja IPv6 vajab oma ip -6 rule, sest v4-reegel ei kata seda.
Windows ja macOS: piirake tulemüüri või andke puhverserver
Ka Windowsil pole rakendusepõhist marsruudivalijat, kuid selle tulemüürireegleid saab piirata profiiliga ja VPN-adapteri saab liigitada „avalikuks“, samal ajal kui kodu-LAN jääb „privaatseks“. Looge programmi jaoks väljuvad blokeerimisreeglid profiilides „privaatne“ ja „domeen“, jätke „avalik“ avatuks, ja rakendus pääseb võrku ainult tunneli kaudu. Määrake esmalt ühenduse võrgukategooria ja kinnitage seejärel, et reegel langes tulemüüri jälgimispaneelis kokku. See on blokeering, mitte marsruut: see ebaõnnestub suletult, kui tunnel kukub, ega suuda peatada rakendust, mis tulemüüri eirab.
macOS järgib sama loogikat teiste tööriistadega. SSH kaudu saavutatav SOCKS-kuulaja on kõige vähem sekkuv valik, sest ssh -D 1080 user@host loob ühe kohaliku pordi ja ainult selle kasutamiseks seadistatud rakendused lähevad seda teed. Reegel pf saab blokeerida programmi kasutaja või grupi järgi, kuid ei suuda ikkagi valida tunnelit ainult selle programmi jaoks. Tunnelblick ei suuda domeeni järgi üldse filtreerida, sest marsruudid töötavad aadressidega; OpenConnecti kasutajad pöörduvad vpn-slice poole, kui server lükkab liiga laia eesliiteloendi.
Kaks möödasõitu katavad selle, mida platvormi tööriistad märkamata jätavad. Brauserilaiendid, mis vahetavad puhverserverit domeeni kaupa, on praktiline vastus „ainult see sait“, sest need toimivad rakenduskihil, kus nimed veel eksisteerivad; need katavad ühe brauseri ega midagi muud. Jäme lahendus on käivitada tarnija klient virtuaalmasinas, et külaline omaks marsruudimuudatust, samal ajal kui host hoiab oma teed, kahe hooldatava võrguvirna hinnaga.
SOCKS-hüpe tööriistadele, millel pole sidumisvalikut
Enamikku rakendusi saab suunata HTTP või SOCKS puhverserverile ka siis, kui need ei tea liidestest midagi. SSH-klient pakub ühe ilma serveripoolse muudatuseta:
ssh -N -D 127.0.0.1:9999 [email protected]Kõik, mis on seadistatud seda porti kasutama, väljub bastionil, samal ajal kui ülejäänud töölaud hoiab oma tavalist ühendust. Tunneli aadressiga seotud kohalik 3proxy eksemplar teeb sama ühe pordi jaoks ilma SSH-ta ja stunnel katab ühe TLS-i mähitud pordi. Piirid on praktilised: puhverserver kannab ainult protokolle, mis oskavad seda kasutada, UDP vajab SOCKS5 UDP-assotsiatsiooni, mida paljude klientide „SOCKS5“ säte ei aktiveeri, ja DNS peab lahendama puhverserver (socks5h curl-is), muidu lekib nimi kohalikku resolverisse.
Hoidke kuulaja loopbackil, kui just mõni teine masin seda ei vaja.
Kontrollige teed püüdmisega, mitte olekuteatega
Rakenduse olekuaknad kirjeldavad sätet, mitte paketti. Püüdke mõlemal liidesel ja võrrelge:
tcpdump -i any -n port 443
ss -tnp | grep 443Kui ühendus ilmub füüsilisel liidesel ilma vastava kirjeta tunnelis, ei ole valija jõus, mida iganes klient teatab. Kontrollige IPv6-t ja resolverit eraldi ning kontrollige teist teed, näiteks abiprotsessi või päritud süsteemipuhverserverit.
Seejärel valige piir, mis vastab nõudele: puhverserverist piisab ühe saidi jaoks, UID-reeglist piisab ühe konto jaoks, tulemüüriprofiilist piisab, kui ühendus peab suletult ebaõnnestuma, ja nimeruum on ainus valik, mis peidab tunneli kõige eest väljaspool seda.