Com encaminar una aplicació per VPN sense tota la màquina
Cap escriptori no gestionat no ofereix un commutador de VPN per procés. Trieu la capa que selecciona el trànsit: un sòcol lligat, una regla d’UID, un perfil de tallafocs o un salt SOCKS.
El client de VPN es connecta, el navegador funciona, i l’única ordre que realment t’importa continua sortint per la teva connexió de casa. O passa el contrari: el túnel agafa la ruta per defecte i el servidor de fitxers local desapareix de l’escriptori. Em va passar amb un agent de compilació que havia d’arribar a un mirall intern d’artefactes mentre la resta de l’amfitrió es quedava a la LAN de l’oficina, i el client oferia exactament dues opcions: tot el trànsit o res. La petició en tots dos sentits és la mateixa, aquest programa i no tota la màquina, i la majoria de clients no tenen cap casella per a això, perquè la taula d’encaminament mai no ha sabut què és un programa.
Per què la taula d’encaminament no pot veure el teu programa
Quan un procés envia un paquet, la pila busca l’adreça de destinació a la taula d’encaminament. Ni el nom de l’executable ni el port no entren en aquesta cerca. Els noms de domini fallen pel mateix motiu: un túnel porta el trànsit a una adreça, i quan un nom es resol en una, l’encaminament és l’única palanca que el nucli encara té. Per això «VPN només per a aquest lloc» acaba volent dir un proxy, i «VPN només per a aquest programa» acaba volent dir un d’un conjunt petit de mecanismes.
| 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 |
Cap d’aquestes coses no és una ruta per procés. Cada una trasllada la decisió a una capa que pot veure el programa, l’usuari o la configuració de la mateixa aplicació.
Una sola destinació continua sent una ruta, no una regla de programa. A macOS la recepta habitual és desmarcar «Envia tot el trànsit per la VPN» i afegir una ruta d’amfitrió: sudo route add -host internal-tuner.example -interface ppp0, que es torna a treure amb sudo route delete -host internal-tuner.example -interface ppp0. Primer llegiu el nom de la interfície a ifconfig, perquè ppp0 només és un exemple. Els comodins no funcionen en una ruta d’amfitrió, així que un servei que parla amb diversos noms necessita una entrada per nom, i la regla cobreix tots els processos de la màquina, no el que teníeu al cap.
Lliga el sòcol a l’adreça del túnel
Quan controles el client, lligar és el selector més barat. Un sòcol lligat a l’adreça local del túnel surt per aquesta interfície sempre que hi hagi una ruta cap a la destinació, i tota la resta de la màquina manté el seu camí normal. La subtilesa és que el lligam tria l’adreça d’origen mentre la taula d’encaminament encara tria la sortida. El lligam tot sol no mou el trànsit que no té ruta cap al túnel, i aquest és l’error darrere de la majoria d’informes de «l’he lligat i encara surt pel costat equivocat».
import socket
s = socket.socket()
s.bind(("10.8.0.2", 0))
s.connect(("build.internal.example", 443))Les eines de nivell superior exposen la mateixa idea: curl --interface 10.8.0.2, CURLOPT_INTERFACE a PHP i l’argument source_address als clients HTTP de Python. L’adreça ha de pertànyer al túnel, i una errata aquí falla com un error de connexió ordinari, no com una queixa d’encaminament. Lligar a un nom de dispositiu en lloc d’una adreça és un privilegi de Linux i no es trasllada a Windows ni a macOS, per això els guions portables passen l’adreça.
Linux: fes coincidir el propietari, no el nom del programa
El nucli pot fer coincidir l’usuari propietari d’un sòcol, així que un compte dedicat es converteix en el selector. Posa el túnel a la seva pròpia taula d’encaminament i envia-hi només el trànsit d’aquest compte:
ip rule add uidrange 1001-1001 lookup 100
ip route add default dev tun0 table 100Això només funciona si el túnel no és ja la ruta per defecte. Inicieu el client amb --route-nopull, o filtreu la redirecció emesa amb --pull-filter ignore "redirect-gateway" a OpenVPN 2.4 i posteriors, i després afegiu vosaltres mateixos l’entrada a la taula. Si no, existeixen les dues rutes per defecte i guanya la de prioritat més baixa. La versió deliberada d’això és apuntar la ruta per defecte a la passarel·la del túnel, o fer-ho des d’un guió de desconnexió: manté el trànsit fora d’Internet quan el túnel cau, però és un interruptor de seguretat, no un selector, i es queda fins que algú el treu.
La versió més forta és un espai de noms de xarxa. Creeu-lo, executeu el client a dins i inicieu l’aplicació amb ip netns exec. Res de fora de l’espai de noms no veu la interfície del túnel, així que l’aplicació no pot tornar per accident a la ruta de l’amfitrió. El cost és real: l’espai de noms necessita una parella veth per arribar a la xarxa física i el seu propi fitxer de resolutor, perquè l’espai de noms de muntatge no comparteix la configuració de resolució de l’amfitrió.
Dos modes de fallada expliquen la majoria de fuites. La resolució de noms encara passa al resolutor de l’amfitrió, així que la consulta surt fora del túnel fins i tot quan la connexió TCP hi entra. I IPv6 necessita el seu propi ip -6 rule, perquè una regla v4 no el cobreix.
Windows i macOS: limita el tallafocs o cedeix un proxy
Windows tampoc no té selector de ruta per aplicació, però les seves regles de tallafocs es poden limitar a un perfil, i un adaptador VPN es pot classificar com a «públic» mentre la LAN de casa continua «privada». Creeu regles de bloqueig de sortida per al programa als perfils «privat» i «domini», deixeu «públic» obert, i l’aplicació només podrà arribar a la xarxa a través del túnel. Primer establiu la categoria de xarxa de la connexió, i després confirmeu que la regla ha coincidit al panell de monitoratge del tallafocs. És un bloqueig, no una ruta: falla tancat quan el túnel cau, i no pot aturar una aplicació que ignora el tallafocs.
macOS segueix la mateixa lògica amb eines diferents. Un oient SOCKS abastat per SSH és l’opció menys invasiva, perquè ssh -D 1080 user@host crea un port local i només les aplicacions configurades per fer-lo servir prenen aquest camí. Una regla pf pot bloquejar un programa per usuari o grup, però encara no pot triar el túnel només per a aquest programa. Tunnelblick no pot filtrar per domini de cap manera, perquè les rutes treballen amb adreces; els usuaris d’OpenConnect recorren a vpn-slice quan el servidor empeny una llista de prefixos massa àmplia.
Dues solucions alternatives cobreixen el que les eines de la plataforma passen per alt. Les extensions de navegador que canvien el proxy per domini són la resposta pràctica per a «només aquest lloc», perquè actuen a la capa d’aplicació on els noms encara existeixen; cobreixen un navegador i res més. La solució grollera és executar el client del proveïdor dins d’una màquina virtual perquè el convidat sigui l’amo del canvi de ruta mentre l’amfitrió manté el seu camí, a costa de dues piles de xarxa per mantenir.
Un salt SOCKS per a eines sense opció de lligam
La majoria d’aplicacions es poden apuntar a un proxy HTTP o SOCKS fins i tot quan no saben res de les interfícies. Un client SSH en forneix un sense cap canvi al costat del servidor:
ssh -N -D 127.0.0.1:9999 [email protected]Tot el que estigui configurat per fer servir aquest port surt a la bastió mentre la resta de l’escriptori manté la connexió normal. Una instància local de 3proxy lligada a l’adreça del túnel fa el mateix per a un port sense SSH, i stunnel cobreix un sol port embolcallat en TLS. Els límits són pràctics: un proxy només transporta protocols que saben fer-lo servir, UDP necessita una associació UDP de SOCKS5 que la configuració «SOCKS5» de molts clients no activa, i el DNS s’ha de resoldre pel proxy (socks5h a curl) o el nom s’escapa al resolutor local.
Manteniu l’oient al loopback tret que una altra màquina el necessiti.
Verifiqueu el camí amb una captura, no amb un missatge d’estat
Les finestres d’estat de l’aplicació descriuen la configuració, no el paquet. Captureu a les dues interfícies i compareu:
tcpdump -i any -n port 443
ss -tnp | grep 443Si la connexió apareix a la interfície física sense cap entrada corresponent al túnel, el selector no està en efecte, faci el que faci el client. Comproveu IPv6 i el resolutor per separat, i mireu si hi ha un segon camí com un procés auxiliar o un proxy de sistema heretat.
Després trieu la frontera que encaixi amb el requisit: un proxy n’hi ha prou per a un lloc, una regla d’UID n’hi ha prou per a un compte, un perfil de tallafocs n’hi ha prou quan la connexió ha de fallar tancada, i un espai de noms és l’única opció que amaga el túnel a tot el que hi ha fora.