Шест проверки, изпълнени по ред, решават дали една VM може да служи като VPN шлюз за собствения си хост. Хипервизорът не прави нищо от това вместо вас: гостът притежава тунела, хостът притежава маршрут, а мрежата между тях е обикновено маршрутизиране. Държа списъка, защото пропускането на една стъпка винаги дава един и същ симптом, тишина, при който хостът весело пингва госта и не стига до нищо вътрешно.

Започнете с причината. Или корпоративният клиент се инсталира само вътре в госта, или политиката го държи там, а вие все още ви трябва вътрешният build сървър от хоста. Ако на хоста е разрешен собствен клиент, направете това вместо другото: един тунел на хоста винаги е по-добър от две мрежи плюс NAT.

Проверка 1: хостът се нуждае от връзка, на която може да даде адрес

Хостът трябва да притежава интерфейс в същия префикс, в който е вторият адаптер на госта. Host-only във VirtualBox, host-only или персонализиран VMnet във VMware Workstation, вътрешен бридж или tap устройство в QEMU/KVM и Internal switch в 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 показва госта пръв; и същите шест отговора оцеляват след рестарт.

Подобни статии