Jedno urządzenie przez VPN na routerze wymaga trzech reguł, nie przełącznika
Jedno urządzenie przez VPN na routerze to routing polityki, nie pole wyboru: oznaczona tabela, ograniczona reguła NAT oraz ścieżki DNS, IPv6 i LAN, które poradniki pomijają.
Na VPN na routerze nie ma przełącznika dla każdego urządzenia; przełącznik, którego szukasz, to skrót, który w twoim imieniu zapisuje reguły routingu polityki. W momencie, gdy jeden laptop, jeden zakres portów, jedna lista adresów albo jeden segment LAN musi korzystać z tunelu, a wszystko inne zostaje w WAN, budujesz trasę polityki, a nie włączasz funkcję. Zadanie ma trzy ruchome części i każda zawodzi inaczej: oznaczona tabela bez trasy wygląda jak cisza, znacznik założony w niewłaściwym łańcuchu wygląda, jakby nic się nie stało, a brakująca reguła NAT wygląda jak tunel, który się łączy i nic nie przenosi. Brakuje jeszcze dwóch części, bo nigdy nie pojawiają się w regule mangle, i są to DNS oraz IPv6.
Mit: tunel to ustawienie klienta
Klient VPN po stronie routera dobrze robi jedną toporną rzecz: wstawia 0.0.0.0/0 do głównej tabeli routingu i kieruje ją na tunel. WireGuard wyprowadza to z AllowedIPs, OpenVPN a z redirect-gateway wysyłanego przez serwer, i oba zmieniają ścieżkę każdego hosta za routerem. Zawężenie AllowedIPs albo dodanie route-nopull zmienia to, co instaluje klient. Nie zmienia tego, kogo dotyczy instalacja, bo klient nigdy nie widzi urządzeń. Widzi tylko pakiety.
Wybór po źródle lub celu jest decyzją routingu, więc należy do warstwy polityki routera: reguła mangle plus druga tabela na RouterOS, MARK plus ip rule na OpenWrt albo DD-WRT, lub reguła firewalla, której bramą jest tunel, na pfSense. Przepis Netgate na klienta WireGuard to ten, który trzeba przeczytać, zanim zacznie się zgadywać, bo na tej platformie brama reguły, przypisanie interfejsu i wpis NAT dla ruchu wychodzącego muszą się zgodzić, zanim choćby jeden klient użyje tunelu.
Druga połowa mitu to drugi router. Kupno kolejnego pudełka albo przeniesienie urządzenia do SSID dla gości często działa, a powód nie leży w sprzęcie: umieszcza urządzenie w jego własnej podsieci, co daje selektor źródła, który firmware już rozumie. Jeśli potrafisz zdefiniować ten segment na własnym routerze, dodatkowe pudełko rozwiązuje problem, którego nie miałeś.
Część pierwsza: tunel, który nie jest trasą domyślną
Na RouterOS dodaj klienta bez trasy domyślnej i daj tunelowi własną tabelę. Pierwsza trasa to oznaczona domyślna; druga to połowa awarii.
/ip route add dst-address=0.0.0.0/0 gateway=VPN_GATEWAY_IP routing-mark=vpn distance=1
/ip route add dst-address=0.0.0.0/0 type=unreachable routing-mark=vpn distance=2
Trasa unreachable jest powodem, dla którego oznaczona tabela bije listę wyjątków w tabeli głównej. Gdy tunel padnie, oznaczone pakiety dostają natychmiast unreachable zamiast po cichu wracać do WAN, więc awaria pojawia się w komunikacie błędu aplikacji, a nie na stronie geolokalizacji, którą sprawdzasz godzinę później.
RouterOS 7 rozdziela to, co 6.x trzymał razem: tabelę deklarujesz przez /routing table add name=vpn fib, a potem odwołujesz się do niej po nazwie na trasie i w regule mangle. Fragment 6.x, który zapisuje routing-mark bez zdefiniowania tabeli, ładuje się czysto i do niczego nie pasuje. Inny klasyk to dwie połówki 0.0.0.0/1 albo dwie trasy domyślne w tej samej odległości w jednej tabeli: jądro wybiera jedną, a zachowanie może się zmienić po restarcie.
Część druga: oznacz przed wyszukaniem trasy
Selektor decyduje, które pakiety wejdą do tej tabeli. RouterOS zwykle zaczyna od listy adresów dla polityki celu albo adresu źródłowego dla polityki urządzenia:
/ip firewall mangle add chain=prerouting src-address=192.168.88.50 action=mark-routing new-routing-mark=vpn
/ip firewall mangle add chain=prerouting dst-address-list=via-vpn action=mark-routing new-routing-mark=vpn
/ip firewall address-list add list=via-vpn address=203.0.113.10
Firmware Linuksa robi to samo ze znacznikiem netfilter i regułą, która kieruje oznaczone pakiety do tabeli, którą wypełniłeś:
iptables -t mangle -A PREROUTING -p tcp --dport 27000:27050 -j MARK --set-mark 0x200
ip route add default dev tun0 table 100
ip rule add fwmark 0x200 table 100
Łańcuch nie jest wyborem stylu. Gdy pakiet dotrze do FORWARD, wyszukanie trasy już się odbyło, więc MARK albo DROP może tam tylko przepisać lub odrzucić. Znacznik musi trafić do PREROUTING dla ruchu przekazywanego i do OUTPUT dla ruchu, który tworzy sam router, gdzie żyją DNS, NTP i sprawdzanie aktualizacji routera. Ta ścieżka wyjściowa to zwykły powód, dla którego w pełni tunelowana konfiguracja nadal odpowiada z resolvera ISP w teście wycieku.
Polityka urządzenia potrzebuje dopasowania, które nie dryfuje. Zarezerwuj adres w DHCP albo dopasuj interfejs dla dedykowanego segmentu; adres, który później przejdzie na inne urządzenie, po cichu stosuje tunel do niewłaściwego klienta. Mostek na SSID z własną podsiecią to trwalsza wersja tego samego pomysłu i daje też miejsce regułom IPv6.
Część trzecia: NAT, DNS i wyjątek LAN
Ruch wychodzący przez tunel potrzebuje adresu źródłowego, na który odpowie druga strona. Ogranicz tłumaczenie do interfejsu tunelu: out-interface=VPN_NAME na RouterOS, -o tun0 na Linuksie, pasujący wpis NAT dla ruchu wychodzącego na pfSense. Reguła masquerade bez tego ograniczenia przepisuje ruch, który chciałeś zostawić, a objawem jest to, że urządzenie poza tunelem traci publiczny adres.
Wyjątek LAN powoduje więcej wątków wsparcia niż sam tunel. Jeśli oznaczona tabela zawiera tylko trasę domyślną, cel drukarki lub NAS z wybranego urządzenia pasuje do tej trasy domyślnej i znika w tunelu. Dodaj trasę LAN do tej samej tabeli albo wyklucz lokalną podsieć w selektorze; oba działają, a wykluczenie łatwiej utrzymać poprawnie, gdy później dodasz VLAN-y.
DNS idzie osobną ścieżką. Zapytania, które router przekazuje, pochodzą od routera i podążają za OUTPUT, a nie za przekazanym znacznikiem, więc w pełni tunelowany laptop nadal może rozwiązywać nazwy przez ISP. Skieruj klientów na resolver osiągalny przez tunel albo oznacz ruch port-53 samego routera, a potem sprawdź rozwiązany adres, zamiast zakładać, że odpowiedź podróżowała razem z żądaniem sieciowym.
Gdy reguła pasuje, ale aplikacja nadal korzysta z WAN
Listy celów szybko się starzeją. Nazwa rozwiązuje się na adres, którego nie ma na liście, więc żądanie idzie przez WAN, podczas gdy każdy test wykonany na wymienionym adresie działał. Odświeżaj listę z tego samego resolvera, którego używa klient, i preferuj selektor oparty na źródle, gdy naprawdę chcesz całego ruchu z jednego urządzenia.
IPv6 to cicha obejście. Urządzenie ma drugą rodzinę adresów z własną trasą domyślną i własnym zestawem reguł, a dopasowanie tylko adresu IPv4 to połowa polityki. Zastosuj ten sam selektor do ip6tables lub odpowiednika nftables albo świadomie wyłącz IPv6 w tym segmencie, a nie przez przypadek.
Ustanowione połączenia też mają znaczenie. Wpis conntrack utworzony przed zmianą nadal podąża starą ścieżką, dopóki nie wygaśnie, więc przeglądarka pozostawiona otwarta podczas edycji wygląda dokładnie jak reguła, która nigdy nie została zastosowana. Otwórz nowe połączenie albo wyczyść stan, zanim ocenisz politykę.
Sprawdź na dwóch urządzeniach i po restarcie
Przetestuj urządzenie, które powinno być w tunelu, i to, które nie powinno, i porównaj drugi skok, a nie liczbę prędkości. Traceroute z każdego pokazuje bramę tunelu albo bramę ISP na drugim skoku; jeśli oba wyglądają tak samo, znacznik albo tabela nie robią tego, co mówi reguła. Do testu używaj nowych połączeń.
Potem zrestartuj. Kolejność startu to miejsce, w którym działająca polityka się psuje, bo klient musi być uruchomiony, zanim zostanie zainstalowana trasa unreachable, a zapisany snapshot, który przywraca stary zestaw reguł, nadpisze twoją tabelę. Sprawdź, czy każda reguła jest w zapisanej konfiguracji i czy oznaczona domyślna istnieje po starcie, nie tylko po tym, jak ją wpisałeś.
Jeśli coś zawiedzie, najpierw zdejmij znacznik i zobacz, czy normalny ruch wraca, a potem zdejmij tabelę. Ta kolejność mówi, czy gonisz problem routingu, czy firewalla, i zostawia domownikom działającą drukarkę, gdy kończysz pracę.