Jak kierować jedną aplikację przez VPN bez całej maszyny
Żaden niezarządzany pulpit nie oferuje przełącznika VPN na proces. Wybierz warstwę, która wybiera ruch: gniazdo związane z adresem, reguła UID, profil zapory lub przeskok SOCKS.
Klient VPN się łączy, przeglądarka działa, a to jedno polecenie, na którym naprawdę ci zależy, nadal wychodzi przez domowe łącze. Albo dzieje się odwrotnie: tunel przechwytuje trasę domyślną i lokalny serwer plików znika z pulpitu. Spotkałem to z agentem budowania, który musiał dotrzeć do wewnętrznego lustra artefaktów, podczas gdy reszta hosta zostawała w biurowej sieci LAN, a klient oferował dokładnie dwie opcje, cały ruch albo nic. Prośba w obu stronach jest ta sama, ten program, a nie cała maszyna, i większość klientów nie ma na to pola wyboru, bo tablica tras nigdy nie wiedziała, czym jest program.
Dlaczego tablica tras nie widzi twojego programu
Gdy proces wysyła pakiet, stos sprawdza adres docelowy w tablicy tras. Ani nazwa pliku wykonywalnego, ani port nie wchodzą do tego wyszukiwania. Nazwy domenowe zawodzą z tego samego powodu: tunel przenosi ruch do adresu, a gdy nazwa zostanie rozwiązana do adresu, routing jest jedyną dźwignią, jaką jądro jeszcze ma. Dlatego „VPN tylko dla tej witryny” oznacza ostatecznie proxy, a „VPN tylko dla tego programu” jedną z niewielkiego zestawu mechanizmów.
| 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 |
Żaden z nich nie jest trasą na proces. Każdy przenosi decyzję do warstwy, która widzi program, użytkownika lub własną konfigurację aplikacji.
Jedno miejsce docelowe wciąż jest trasą, a nie regułą programu. W macOS typowy przepis to odznaczenie „Wyślij cały ruch przez VPN” i dodanie trasy do hosta: sudo route add -host internal-tuner.example -interface ppp0, usuwanej ponownie przez sudo route delete -host internal-tuner.example -interface ppp0. Najpierw odczytaj nazwę interfejsu z ifconfig, ponieważ ppp0 jest tylko przykładem. W trasie do hosta nie działają symbole wieloznaczne, więc usługa rozmawiająca z kilkoma nazwami potrzebuje jednego wpisu na nazwę, a reguła obejmuje każdy proces na maszynie, nie tylko ten, o którym myślałeś.
Zwiąż gniazdo z adresem tunelu
Kiedy kontrolujesz klienta, powiązanie jest najtańszym selektorem. Gniazdo powiązane z lokalnym adresem tunelu wychodzi przez ten interfejs, dopóki istnieje tam trasa do celu, a wszystko inne na maszynie zachowuje normalną ścieżkę. Subtelność polega na tym, że powiązanie wybiera adres źródłowy, podczas gdy tablica tras nadal wybiera wyjście. Samo powiązanie nie przenosi ruchu, który nie ma trasy do tunelu, i to jest błąd kryjący się za większością zgłoszeń „powiązałem to, a nadal wychodzi w złą stronę”.
import socket
s = socket.socket()
s.bind(("10.8.0.2", 0))
s.connect(("build.internal.example", 443))Narzędzia wyższego poziomu pokazują ten sam pomysł: curl --interface 10.8.0.2, CURLOPT_INTERFACE PHP oraz argument source_address w klientach HTTP Pythona. Adres musi należeć do tunelu, a literówka tutaj zawodzi jako zwykły błąd połączenia, a nie skarga na routing. Powiązanie z nazwą urządzenia zamiast adresem to przywilej Linuksa i nie przenosi się do Windowsa ani macOS, dlatego przenośne skrypty przekazują adres.
Linux: dopasuj właściciela, nie nazwę programu
Jądro potrafi dopasować właściciela-użytkownika gniazda, więc dedykowane konto staje się selektorem.
ip rule add uidrange 1001-1001 lookup 100
ip route add default dev tun0 table 100Działa to tylko wtedy, gdy tunel nie jest już trasą domyślną. Uruchom klienta z --route-nopull albo odfiltruj wypychane przekierowanie przez --pull-filter ignore "redirect-gateway" na OpenVPN 2.4 i nowszym, a następnie sam dodaj wpis tablicy. Inaczej istnieją obie trasy domyślne i wygrywa ta o niższym priorytecie. Jej zamierzona wersja to skierowanie trasy domyślnej do bramy tunelu albo zrobienie tego ze skryptu rozłączenia: trzyma ruch z dala od internetu, gdy tunel padnie, ale to wyłącznik bezpieczeństwa, nie selektor, i zostaje, dopóki ktoś go nie usunie.
Mocniejsza wersja to przestrzeń nazw sieci. Utwórz ją, uruchom klienta w niej i wystartuj aplikację przez ip netns exec. Nic poza przestrzenią nazw nie widzi interfejsu tunelu, więc aplikacja nie może przypadkiem cofnąć się do trasy hosta. Koszt jest realny: przestrzeń nazw potrzebuje pary veth, aby dotrzeć do sieci fizycznej, oraz własnego pliku resolvera, ponieważ przestrzeń nazw montowania nie dzieli ustawień rozwiązywania nazw hosta.
Dwa tryby awarii wyjaśniają większość wycieków. Rozwiązywanie nazw wciąż odbywa się w resolverze hosta, więc zapytanie wychodzi poza tunel, nawet gdy połączenie TCP idzie do środka. A IPv6 wymaga własnego ip -6 rule, ponieważ reguła v4 go nie obejmuje.
Windows i macOS: ogranicz zaporę lub oddaj proxy
Windows też nie ma selektora trasy na aplikację, ale jego reguły zapory można ograniczyć do profilu, a adapter VPN można sklasyfikować jako Publiczny, podczas gdy domowa sieć LAN pozostaje Prywatna. Utwórz reguły blokowania ruchu wychodzącego dla programu w profilach Prywatny i Domena, zostaw Publiczny otwarty, a aplikacja będzie mogła dotrzeć do sieci tylko przez tunel. Najpierw ustaw kategorię sieci połączenia, potem potwierdź, że reguła pasowała w panelu monitora zapory. To blokada, a nie trasa: zawodzi bezpiecznie, gdy tunel padnie, i nie zatrzyma aplikacji, która ignoruje zaporę.
macOS stosuje tę samą logikę innymi narzędziami. Odbiornik SOCKS osiągany przez SSH to najmniej inwazyjna opcja, bo ssh -D 1080 user@host tworzy jeden lokalny port i tylko aplikacje skonfigurowane do jego używania idą tą ścieżką. Reguła pf może blokować program według użytkownika lub grupy, ale nadal nie wybierze tunelu dla samego tego programu. Tunnelblick nie potrafi filtrować według domeny, bo trasy działają na adresach; użytkownicy OpenConnect sięgają po vpn-slice, gdy serwer wypycha zbyt szeroką listę prefiksów.
Dwie obejścia pokrywają to, czego brakuje narzędziom platformy. Rozszerzenia przeglądarki przełączające proxy według domeny to praktyczna odpowiedź na „tylko ta witryna”, bo działają w warstwie aplikacji, gdzie nazwy wciąż istnieją; obejmują jedną przeglądarkę i nic więcej. Tępe rozwiązanie to uruchomienie klienta dostawcy w maszynie wirtualnej, aby gość posiadał zmianę trasy, a host zachował swoją ścieżkę, kosztem dwóch stosów sieciowych do utrzymania.
Przeskok SOCKS dla narzędzi bez opcji powiązania
Większość aplikacji można skierować do proxy HTTP lub SOCKS, nawet gdy nie wiedzą nic o interfejsach. Klient SSH dostarcza jedno bez żadnej zmiany po stronie serwera:
ssh -N -D 127.0.0.1:9999 [email protected]Wszystko skonfigurowane do używania tego portu wychodzi na bastionie, podczas gdy reszta pulpitu zachowuje normalne połączenie. Lokalna instancja 3proxy powiązana z adresem tunelu robi to samo dla jednego portu bez SSH, a stunnel obejmuje jeden pojedynczy port opakowany w TLS. Limity są praktyczne: proxy przenosi tylko protokoły, które wiedzą, jak go używać, UDP wymaga skojarzenia UDP SOCKS5, którego ustawienie „SOCKS5” w wielu klientach nie włącza, a DNS musi być rozwiązany przez proxy (socks5h w curl) albo nazwa wycieknie do lokalnego resolvera.
Trzymaj odbiornik na loopbacku, chyba że potrzebuje go inna maszyna.
Sprawdź ścieżkę przechwytem, nie komunikatem statusu
Okna statusu aplikacji opisują ustawienie, a nie pakiet. Przechwyć na obu interfejsach i porównaj:
tcpdump -i any -n port 443
ss -tnp | grep 443Jeśli połączenie pojawia się na interfejsie fizycznym bez pasującego wpisu w tunelu, selektor nie działa, cokolwiek zgłasza klient. Sprawdź IPv6 i resolver osobno oraz sprawdź drugą ścieżkę, taką jak proces pomocniczy albo odziedziczone proxy systemowe.
Następnie wybierz granicę pasującą do wymagania: proxy wystarczy dla jednej witryny, reguła UID wystarczy dla jednego konta, profil zapory wystarczy, gdy połączenie musi zawieść bezpiecznie, a przestrzeń nazw jest jedyną opcją, która ukrywa tunel przed wszystkim na zewnątrz.