Korleis rute éin app gjennom ein VPN utan heile maskinen
Ingen uhandtert skrivebordsmaskin tilbyr ein VPN-brytar per prosess. Vel laget som vel trafikken: ein bunden socket, ein UID-regel, ein brannmurprofil eller eit SOCKS-hopp.
VPN-klienten koplar til, nettlesaren verkar, og den eine kommandoen du faktisk bryr deg om går framleis ut via heimeforbindinga. Eller det motsette skjer: tunnelen tek standardruta og den lokale filserveren forsvinn frå skrivebordet. Eg trefte dette med ein byggjeagent som måtte nå eit internt artifakt-spegel medan resten av verten vart verande på kontor-LAN-et, og klienten tilbaud nøyaktig to val, all trafikk eller ingenting. Førespurnaden er den same begge vegar, dette programmet og ikkje heile maskinen, og dei fleste klientar har ingen avkryssingsboks for han, fordi rutetabellen aldri har visst kva eit program er.
Kvifor rutetabellen ikkje kan sjå programmet ditt
Når ein prosess sender ei pakke, slår stakken opp måladdressa i rutetabellen. Verken namnet på den køyrbare fila eller porten kjem inn i det oppslaget. Domenenamn feilar av same grunn: ein tunnel ber trafikk til ei adresse, og når eit namn er løyst til eitt, er ruting den einaste spaken kjernen framleis har. Det er difor “VPN berre for denne nettstaden” endar med å tyde ein proxy, og “VPN berre for dette programmet” endar med å tyde ein av eit lite sett mekanismar.
| 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 |
Ingen av desse er ei rute per prosess. Kvar av dei flyttar avgjerda til eit lag som kan sjå programmet, brukaren eller appens eiga konfigurasjon.
Ein einaste destinasjon er framleis ei rute, ikkje ein programregel. På macOS er den vanlege oppskrifta å fjerne merket for “Send all trafikk over VPN” og leggje til ei vertsrute: sudo route add -host internal-tuner.example -interface ppp0, fjerna att med sudo route delete -host internal-tuner.example -interface ppp0. Les grensesnittnamnet frå ifconfig fyrst, sidan ppp0 berre er eit døme. Jokerteikn verkar ikkje i ei vertsrute, så ein teneste som snakkar med fleire namn treng éi oppføring per namn, og regelen dekkjer kvar prosess på maskinen, ikkje den du hadde i tankane.
Bind socketen til tunneladressa
Når du kontrollerer klienten, er binding den billegaste veljaren. Ein socket bunden til den lokale adressa til tunnelen går ut gjennom det grensesnittet så lenge ei rute for målet finst der, og alt anna på maskinen held sin normale veg. Det subtile er at bindinga vel kjeldeadressa medan rutetabellen framleis vel utgangen. Ei binding åleine flyttar ikkje trafikk som ikkje har noka rute inn i tunnelen, og det er feilen bak dei fleste rapportane om at “eg batt han og han går framleis feil veg”.
import socket
s = socket.socket()
s.bind(("10.8.0.2", 0))
s.connect(("build.internal.example", 443))Verktøy på høgare nivå viser den same ideen: curl --interface 10.8.0.2, PHPs CURLOPT_INTERFACE, og source_address-argumentet i Pythons HTTP-klientar. Adressa må høyre til tunnelen, og ein skrivefeil her feilar som ein vanleg tilkoplingsfeil, ikkje som ei ruteklage. Å binde til eit einingnamn i staden for ei adresse er eit Linux-privilegium og blir ikkje overført til Windows eller macOS, og difor sender portable skript adressa.
Linux: match eigaren, ikkje programnamnet
Kjernen kan matche den eigde brukaren av ein socket, så ein dedikert konto blir veljaren.
ip rule add uidrange 1001-1001 lookup 100
ip route add default dev tun0 table 100Dette verkar berre om tunnelen ikkje allereie er standardruta. Start klienten med --route-nopull, eller filtrer den dytta omdirigeringa med --pull-filter ignore "redirect-gateway" på OpenVPN 2.4 og nyare, og legg så til tabelloppføringa sjølv. Elles finst båe standardane og den med lågare prioritet vinn. Den medvitne versjonen er å peike standardruta mot tunnelgatewayen, eller gjere det frå eit fråkoplingsskript: det held trafikken borte frå internett når tunnelen fell, men det er ein kill switch, ikkje ein veljar, og han blir til nokon fjernar han.
Den sterkare versjonen er eit nettverksnamnerom. Opprett det, køyr klienten inni det, og start applikasjonen med ip netns exec. Ingenting utanfor namnerommet ser tunnelgrensesnittet, så applikasjonen kan ikkje falle tilbake til vertsruta ved eit uhell. Kostnaden er reell: namnerommet treng eit veth-par for å nå det fysiske nettverket og si eiga resolverfil, fordi mount-namnerommet ikkje deler oppløysingsinnstillingane til verten.
To feilmodusar forklarar dei fleste lekkasjane. Namneoppløysing skjer framleis i resolveren til verten, så spørjinga går utanfor tunnelen sjølv når TCP-tilkoplinga går inn. Og IPv6 treng sin eigen ip -6 rule, fordi ein v4-regel ikkje dekkjer han.
Windows og macOS: avgrens brannmuren eller overlat ein proxy
Windows har heller ingen rutefinnar per applikasjon, men brannmurreglane kan avgrensast til ein profil, og ein VPN-adapter kan klassifiserast som Offentleg medan heime-LAN-et blir verande Privat. Opprett utgåande blokkreglar for programmet på profilane Privat og Domene, la Offentleg vere open, og applikasjonen kan berre nå nettverket gjennom tunnelen. Set nettverkskategorien til tilkoplinga fyrst, og stadfest så at regelen samsvarte i overvakingspanelet til brannmuren. Det er ei blokk, ikkje ei rute: ho feilar lukka når tunnelen fell, og ho kan ikkje stoppe ein applikasjon som ignorerer brannmuren.
macOS følgjer same logikk med andre verktøy. Ein SOCKS-lyttar nådd over SSH er det minst invasive alternativet, sidan ssh -D 1080 user@host opprettar éin lokal port og berre applikasjonar konfigurerte til å bruke han tek den vegen. Ein pf-regel kan blokkere eit program etter brukar eller gruppe, men han kan framleis ikkje velje tunnelen for det programmet åleine. Tunnelblick kan ikkje filtrere etter domene i det heile, fordi ruter verkar på adresser; OpenConnect-brukarar tyr til vpn-slice når serveren dyttar ei for brei prefiksliste.
To arbeidsomvegar dekkjer det plattformverktøya manglar. Nettlesarutvidingar som byter proxy per domene er det praktiske svaret for “berre denne nettstaden”, fordi dei verkar på applikasjonslaget der namn framleis finst; dei dekkjer éin nettlesar og ingenting anna. Den grove er å køyre leverandørklienten inne i ein virtuell maskin slik at gjesten eig ruteendringa medan verten held sin veg, til kostnaden av to nettverksstakkar å vedlikehalde.
Eit SOCKS-hopp for verktøy utan bindingsval
Dei fleste applikasjonar kan peikast mot ein HTTP- eller SOCKS-proxy sjølv når dei ikkje veit noko om grensesnitt. Ein SSH-klient skaffar ein utan endring på serversida:
ssh -N -D 127.0.0.1:9999 [email protected]Alt som er konfigurert til å bruke den porten, går ut ved bastionen medan resten av skrivebordet held si normale tilkopling. Ein lokal 3proxy-instans bunden til tunneladressa gjer det same for éin port utan SSH, og stunnel dekkjer éin einaste TLS-innpakka port. Grensene er praktiske: ein proxy ber berre protokollar som veit korleis dei brukar han, UDP treng SOCKS5 UDP-assosiasjon som “SOCKS5”-innstillinga til mange klientar ikkje aktiverer, og DNS må løysast av proxyen (socks5h i curl) elles lekk namnet til den lokale resolveren.
Hald lyttaren på loopback med mindre ein annan maskin treng han.
Stadfest vegen med ein fangst, ikkje ei statusmelding
Applikasjonsstatusvindauge skildrar innstillinga, ikkje pakka. Fang på båe grensesnitta og samanlikn:
tcpdump -i any -n port 443
ss -tnp | grep 443Om tilkoplinga viser seg på det fysiske grensesnittet utan ei samsvarande oppføring på tunnelen, er ikkje veljaren i kraft, uansett kva klienten rapporterer. Sjekk IPv6 og resolveren separat, og sjekk etter ein annan veg som ein hjelpeprosess eller ein arva systemproxy.
Vel så grensa som passar kravet: ein proxy er nok for éin nettstad, ein UID-regel er nok for éin konto, ein brannmurprofil er nok når tilkoplinga må feile lukka, og eit namnerom er det einaste alternativet som skjuler tunnelen for alt utanfor det.