Насочување на сообраќајот на домаќинот преку VPN во VM: шест проверки
Шест последователни проверки за претворање на VM во VPN порта низ која насочува сообраќајот нејзиниот сопствен домаќин: режим на адаптер, проследување, NAT, рути на домаќинот, DNS, MTU.
Шест проверки, изведени по ред, одлучуваат дали една VM може да биде VPN порта за својот сопствен домаќин. Хипервизорот ништо од ова не го прави за вас: тунелот го поседува гостинот, рутата ја поседува домаќинот, а мрежата меѓу нив е обично насочување. Ја држам оваа листа затоа што прескокнувањето на еден чекор секогаш го дава истиот симптом, тишина, кога домаќинот весело го пингува гостинот и не стигнува до ништо внатрешно.
Почнете со причината. Или корпоративниот клиент се инсталира само внатре во гостинот, или политиката го држи таму, а вам сепак ви треба внатрешниот build сервер од домаќинот. Ако на домаќинот му е дозволен сопствен клиент, направете го тоа наместо тоа: еден тунел на домаќинот секогаш победува две мрежи плус NAT.
Проверка 1: на домаќинот му треба врска на која може да ѝ даде адреса
Домаќинот мора да има интерфејс во истиот префикс како вториот адаптер на гостинот. Host-only во VirtualBox, host-only или прилагоден VMnet во VMware Workstation, внатрешен мост или tap уред во QEMU/KVM и Internal прекинувач во Hyper-V сите се квалификуваат. Гостин 192.168.56.2, домаќин 192.168.56.1, префикс 192.168.56.0/24 е распоредот што го користам во лаборатории.
Мрежата на QEMU во кориснички режим (-netdev user, стандардниот SLIRP backend) и NAT на VirtualBox целосно пропаѓаат на оваа проверка. Пакетите на гостинот стигнуваат до прокси процес на домаќинот, така што домаќинот никогаш не гледа уред што ги носи адресите на гостинот и нема кон што да насочи рута. Default Switch на Hyper-V е истата приказна. Ако ping 192.168.56.2 од домаќинот не успее, запрете: ниту една подоцна додадена рута нема да го поправи тоа.
Проверка 2: гостинот проследува и преведува
Пакетите од домаќинот пристигнуваат со изворна адреса од host-only мрежата и внатрешна дестинација, па гостинот мора да ги проследи и потоа да ги скрие зад адресата на својот тунел. На Linux гостин тоа значи проследување, пар FORWARD accept и source NAT кон тунелот:
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -A FORWARD -i eth1 -o tun0 -j ACCEPT
sudo iptables -A FORWARD -i tun0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o tun0 -j MASQUERADE
Правилото MASQUERADE е делот што луѓето го испуштаат. Корпоративните рутери ретко знаат дека 192.168.56.0/24 постои; со правилото внатрешните сервери ја гледаат адресата на тунелот на гостинот и одговараат на неа, а одговорот го наоѓа патот назад до гостинот.
Windows гостинот е понесмасен. IPEnableRouter=1 под SYSTEM\CurrentControlSet\Services\Tcpip\Parameters вклучува проследување без преведување, па работи само таму каде корпоративното насочување веќе покажува назад кон вашиот host-only префикс. Internet Connection Sharing преведува, но го пренумерира споделениот адаптер на 192.168.137.1, па прочитајте ја адресата што навистина ја зеде пред да пишувате рути на домаќинот.
Проверка 3: рутите на домаќинот го именуваат гостинот, не тунелот
Низ гостинот пуштајте ги само префиксите што му се потребни на домаќинот. На Linux една рута по префикс е доволна и чисто се враќа:
sudo ip route add 10.20.0.0/16 via 192.168.56.2
ip route get 10.20.30.40
На Windows еквивалентот е route add 10.20.0.0 mask 255.255.0.0 192.168.56.2. Оставете го -p надвор додека тестирате, за да умре лошата рута при рестарт, и додајте го кога патеката ќе проработи. Не отстранувајте ја стандардната рута на домаќинот освен ако секоја апликација на домаќинот треба да го користи тунелот; ако целосниот тунел е навистина барање, додајте ги двете /1 рути и задржете ја директната рута кон мрежата на хипервизорот:
sudo ip route add 0.0.0.0/1 via 192.168.56.2
sudo ip route add 128.0.0.0/1 via 192.168.56.2
На Windows домаќин проверете ја и метриката на интерфејсот. Рута додадена додека host-only адаптерот бил оневозможен останува во табелата, но никогаш не носи сообраќај, а втор адаптер со пониска метрика може да го добие пребарувањето за истиот префикс.
Проверка 4: DNS ја следи рутата, не стандардната поставка на тунелот
Рутите движат пакети; резолверот одлучува кои имиња создаваат пакети. Ограничете го корпоративниот резолвер на корпоративната зона наместо да го замените резолверот на домаќинот, и насочете го кон DNS сервер што новата рута веќе го достигнува. Со systemd-resolved на домаќинот:
resolvectl dns eth1 10.20.0.53
resolvectl domain eth1 '~corp.example.com'
На Windows запис во табелата на политика за разрешување имиња го прави истото: Add-DnsClientNrptRule -Namespace ".corp.example.com" -NameServers 10.20.0.53. Ако гостинот го води својот резолвер на host-only адресата, користете ја таа адреса, но само откако ќе потврдите дека одговара на 192.168.56.2, а не на loopback.
Потоа проверете го MTU пред да го обвините DNS за бавни страници. Интерфејсот на тунелот е помал од интерфејсот од 1500 бајти на домаќинот, па домаќин што праќа сегменти со полна големина со поставен DF бит ги гледа како паѓаат некаде внатре во гостинот. Класичен симптом е работен ping и внатрешна веб апликација што застанува по TLS ракувањето. Затегнете го MSS на патеката за проследување на гостинот:
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Проверка 5: проверете од двата краја
Од домаќинот traceroute или tracert кон внатрешна адреса треба да покаже 192.168.56.2 како прв хоп, не физичката порта. Во гостинот гледајте како излегува истиот обид: tcpdump -ni any host 10.20.30.40 го покажува проследеното барање на host-only страната и преведеното на тунелот. Барање што излегува, се враќа и сепак го остава домаќинот нем, покажува кон повратната патека.
Две грешки го објаснуваат најголемиот дел од тоа. Или тунелот на гостинот не носи повратна рута за host-only префиксот затоа што недостига NAT правилото, или рутата на домаќинот покажува кон адреса што гостинот веќе не ја има по рестарт. Прочитајте ги адресите повторно со ip -br addr и ip route get наместо да им верувате на белешките од претходната сесија.
Проверка 6: направете го да преживее рестарт и надградба на хипервизорот
Зачувајте ги двете половини: конфигурација на рути со netplan или NetworkManager на домаќинот, route add ... -p на Windows и net.ipv4.ip_forward=1 во /etc/sysctl.d/ плус збир правила за огнена ѕид што се вчитува повторно во гостинот. Направете snapshot на гостинот штом конфигурацијата се потврди, пред да пристигне следното ажурирање на корпоративниот клиент.
Host-only мрежите се пренумерираат кога хипервизорот ги пресоздава своите адаптери, што тивко ја поништува секоја рута и NAT правило изградено врз 192.168.56.0/24. По надградба, повторете ги првите три проверки по ред; тоа трае една минута и го фаќа случајот кога домаќинот сѐ уште ја има својата рута, а гостинот се преселил на нова подмрежа.
IPv6 бара свој премин. Правилата на ip6tables, AAAA записите и второто семејство рути на домаќинот не го следат поставувањето на IPv4, а корпоративна услуга достапна преку IPv6 ќе изгледа трајно расипана додека IPv4 работи.
Успешно или не, по ред: домаќинот може да го пингува host-only адресата на гостинот; гостинот проследува и прави MASQUERADE кон тунелот; ip route get го враќа гостинот како порта за внатрешниот префикс; корпоративните имиња се разрешуваат преку ограничениот резолвер; traceroute го покажува гостинот прв; и истите шест одговори преживуваат рестарт.