Како да насочите една апликација низ VPN без целиот компјутер
Ниту една неадминистрирана работна површина не нуди VPN прекинувач по процес. Изберете го слојот што го избира сообраќајот: врзан сокет, UID правило, профил на огнен ѕид или SOCKS скок.
VPN клиентот се поврзува, прелистувачот работи, а таа една команда што навистина ви е важна сѐ уште излегува преку вашата домашна врска. Или се случува спротивното: тунелот ја зафаќа стандардната рута и локалниот датотечен сервер исчезнува од работната површина. На ова наидов со агент за изградба што требаше да стигне до внатрешно огледало на артефакти, додека остатокот од домаќинот остана на канцелариската LAN, а клиентот нудеше точно две можности: целиот сообраќај или ништо. Барањето во двете насоки е исто, оваа програма а не целиот компјутер, и повеќето клиенти немаат полиња за тоа, зашто табелата со рути никогаш не знаела што е програма.
Зошто табелата со рути не може да ја види вашата програма
Кога процесот испраќа пакет, стекот ја бара адресата на одредиштето во табелата со рути. Ниту името на извршната датотека, ниту портата не влегуваат во тоа пребарување. Доменските имиња паѓаат од истата причина: тунелот носи сообраќај до адреса, и штом името се разреши во адреса, рутирањето е единствената лост што јадрото сѐ уште ја има. Затоа „VPN само за овој сајт“ на крајот значи прокси, а „VPN само за оваа програма“ значи еден од мал сет механизми.
| 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 |
Ништо од ова не е рута по процес. Секое ја преместува одлуката на слој што ја гледа програмата, корисникот или сопствената конфигурација на апликацијата.
Едно одредиште е сѐ уште рута, а не правило за програма. На macOS вообичаениот рецепт е да се отстрани ознаката „Испрати го целиот сообраќај преку VPN“ и да се додаде рута до домаќин: sudo route add -host internal-tuner.example -interface ppp0, која повторно се отстранува со sudo route delete -host internal-tuner.example -interface ppp0. Прво прочитајте го името на интерфејсот од ifconfig, зашто ppp0 е само пример. Џокерите не работат во рута до домаќин, така што услуга што разговара со неколку имиња бара еден запис по име, а правилото ги покрива сите процеси на машината, не само тој што го имавте на ум.
Врзете го сокетот со адресата на тунелот
Кога го контролирате клиентот, врзувањето е најевтиниот избирач. Сокет врзан со локалната адреса на тунелот излегува преку тој интерфејс додека таму постои рута до одредиштето, а сѐ друго на машината го задржува својот вообичаен пат. Танкоста е што врзувањето ја избира изворната адреса додека табелата со рути сѐ уште го избира излезот. Самото врзување не го преместува сообраќајот што нема рута во тунелот, и токму тоа е грешката зад повеќето пријави „го врзав и сѐ уште излегува на погрешната страна“.
import socket
s = socket.socket()
s.bind(("10.8.0.2", 0))
s.connect(("build.internal.example", 443))Алатките од повисоко ниво ја нудат истата идеја: curl --interface 10.8.0.2, CURLOPT_INTERFACE во PHP и аргументот source_address во HTTP клиентите на Python. Адресата мора да му припаѓа на тунелот, а печатна грешка тука паѓа како обична грешка при поврзување, не како жалба за рутирање. Врзување со име на уред наместо со адреса е привилегија на Linux и не се пренесува на Windows или macOS, затоа преносливите скрипти ја предаваат адресата.
Linux: совпаѓајте го сопственикот, не името на програмата
Јадрото може да го совпадне сопственикот на сокетот, затоа посветена сметка станува избирач. Ставете го тунелот во сопствена табела со рути и испратете таму само сообраќајот на таа сметка:
ip rule add uidrange 1001-1001 lookup 100
ip route add default dev tun0 table 100Ова работи само ако тунелот не е веќе стандардната рута. Стартувајте го клиентот со --route-nopull, или филтрирајте го турнатото пренасочување со --pull-filter ignore "redirect-gateway" на OpenVPN 2.4 и поново, потоа сами додајте го записот во табелата. Инаку постојат двете стандардни рути и победува онаа со понизок приоритет. Намерната верзија на тоа е да ја насочите стандардната рута кон порталот на тунелот, или да го направите тоа од скрипта за исклучување: го држи сообраќајот надвор од интернет кога тунелот паѓа, но тоа е прекинувач, а не избирач, и останува додека некој не го отстрани.
Посилната верзија е мрежен именски простор. Создадете го, стартувајте го клиентот внатре и стартувајте ја апликацијата со ip netns exec. Ништо надвор од именскиот простор не го гледа интерфејсот на тунелот, така што апликацијата не може случајно да се врати на рутата на домаќинот. Цената е реална: именскиот простор бара veth пар за да стигне до физичката мрежа и своја датотека за разрешувач, зашто просторот за монтирање не ги дели поставките за разрешување на домаќинот.
Два режима на отказ објаснуваат повеќето истекувања. Разрешувањето имиња сѐ уште се случува во разрешувачот на домаќинот, па барањето излегува надвор од тунелот дури и кога TCP врската влегува внатре. А IPv6 бара свое ip -6 rule, зашто правило за v4 не го покрива.
Windows и macOS: ограничете го огнениот ѕид или предадете прокси
Ни Windows нема избирач на рута по апликација, но неговите правила на огнениот ѕид можат да се ограничат на профил, а VPN адаптерот може да се класифицира како „јавен“ додека домашната LAN останува „приватна“. Создадете излезни правила за блокирање за програмата во профилите „приватен“ и „домен“, оставете „јавен“ отворен, и апликацијата ќе стигне до мрежата само преку тунелот. Прво поставете ја мрежната категорија на врската, потоа потврдете дека правилото се совпаднало во панелот за надзор на огнениот ѕид. Тоа е блокирање, а не рута: паѓа затворено кога тунелот ќе падне, и не може да запре апликација што го игнорира огнениот ѕид.
macOS ја следи истата логика со други алатки. SOCKS слушач достапен преку SSH е најмалку инвазивната опција, зашто ssh -D 1080 user@host создава една локална порта и само апликациите конфигурирани да ја користат одат по тој пат. Правило pf може да блокира програма по корисник или група, но сѐ уште не може да го избере тунелот само за таа програма. Tunnelblick воопшто не може да филтрира по домен, зашто рутите работат со адреси; корисниците на OpenConnect посегнуваат по vpn-slice кога серверот турка премногу широк список префикси.
Два заобиколни патишта го покриваат тоа што алатките на платформата го пропуштаат. Проширувањата на прелистувачот што го менуваат проксито по домен се практичниот одговор за „само овој сајт“, зашто дејствуваат на слојот на апликацијата каде имињата сѐ уште постојат; тие покриваат еден прелистувач и ништо друго. Грубиот начин е да го стартувате клиентот на добавувачот во виртуелна машина, така што гостинот ја поседува промената на рутата додека домаќинот го задржува својот пат, по цена на два мрежни стека за одржување.
SOCKS скок за алатки без можност за врзување
Повеќето апликации можат да се насочат кон HTTP или SOCKS прокси дури и кога не знаат ништо за интерфејсите. SSH клиент обезбедува едно без никаква промена на страната на серверот:
ssh -N -D 127.0.0.1:9999 [email protected]Сѐ што е конфигурирано да ја користи таа порта излегува кај бастионот додека остатокот од работната површина ја задржува вообичаената врска. Локална инстанца на 3proxy врзана со адресата на тунелот го прави истото за една порта без SSH, а stunnel покрива една порта завиткана во TLS. Ограничувањата се практични: проксито носи само протоколи што знаат да го користат, UDP бара SOCKS5 UDP здружување што поставката „SOCKS5“ на многу клиенти не ја вклучува, и DNS мора да го разреши проксито (socks5h во curl), инаку името истекува до локалниот разрешувач.
Држете го слушачот на локалната јамка, освен ако друга машина не го бара.
Проверете го патот со снимање, а не со порака за состојба
Прозорците за состојба на апликацијата ја опишуваат поставката, не пакетот. Снимете на двата интерфејси и споредете:
tcpdump -i any -n port 443
ss -tnp | grep 443Ако врската се појави на физичкиот интерфејс без соодветен запис на тунелот, избирачот не е во сила, што и да извести клиентот. Проверете ги IPv6 и разрешувачот одделно, и проверете дали има втор пат, на пример помошен процес или наследено системско прокси.
Потоа изберете ја границата што одговара на барањето: прокси е доволно за еден сајт, UID правило е доволно за една сметка, профил на огнен ѕид е доволен кога врската мора да падне затворена, а именски простор е единствената опција што го крие тунелот од сѐ надвор.