Рутирање саобраћаја домаћина кроз 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 приказује госта првог; и истих шест одговора преживљава рестарт.