Jedna prywatna podsieć przez tunel, a wszystko inne zwykłą drogą to niewielkie życzenie z bardzo wieloma sposobami, by je zepsuć. O wyniku nie decyduje pole wyboru o nazwie split tunneling, lecz to, gdzie decyzja jest egzekwowana: w tabeli tras samego klienta, w trasie wypychanej przez serwer albo w polityce negocjowanej przez oba końce. Wybierz złą warstwę, a dostaniesz albo pełny tunel, którego nigdy nie chciałeś, albo trasę do tunelu, którego druga strona nie chce zaakceptować. Przed otwarciem jakiejkolwiek konfiguracji stosuję test trzech warunków, a potem wybieram jeden z mechanizmów poniżej.

Trzy warunki, które rozstrzygają projekt

Po pierwsze, potrzebujesz dokładnego prefiksu i maski od właściciela sieci. Sieć 10.x nie jest prefiksem; 10.20.0.0/16 jest. Sprawdź, że nie pokrywa się z twoją domową siecią LAN, mostkiem Docker ani innym VPN, który uruchamiasz, bo nakładanie się sprawia, że trasa jest niejednoznaczna i jądro wybiera wpis, którego nie zamierzałeś.

Po drugie, kto odpowiada na ruch powrotny. Skierowanie pakietu do tunelu doprowadza go tylko do serwera VPN. Jeśli podsieć leży za innym routerem, który nie ma trasy z powrotem do twojej puli klientów, serwer musi maskować ruch albo ten router musi poznać twoją pulę. Żadna trasa po stronie klienta nie naprawi brakującej drogi powrotnej.

Po trzecie, miejsce egzekwowania. Niektóre klienty instalują trasę, a resztę robi system operacyjny. Inne negocjują politykę, a polityka, której brama nie akceptuje, nie daje żadnego tunelu: pakiety są odrzucane bez widocznego błędu. Ustal, który z tych dwóch przypadków jest twój, zanim cokolwiek napiszesz.

WireGuard: AllowedIPs to tabela tras

Na kliencie AllowedIPs wymienia cele, które mogą wejść do tunelu, a wg-quick zamienia każdy wpis w zwykłą trasę. Kliencka połowa tego zadania to więc jedna linia.

[Peer]
PublicKey = ...
Endpoint = vpn.example.net:51820
AllowedIPs = 10.20.0.0/16

Teraz porównaj wpis serwera dla tego samego klienta. Opisuje on, co serwer wyśle do klienta, czyli zwykle adres tunelu klienta, a nie prywatną podsieć.

[Peer]
PublicKey = ...
AllowedIPs = 10.99.0.2/32

Zamiana tych dwóch to błąd, który widzę najczęściej. Umieszczenie 10.20.0.0/16 w sekcji peer serwera deklaruje, że cała podsieć leży za tym klientem, a to roszczenie od witryny do witryny, nie zezwolenie. Pakiety niezgodne z AllowedIPs żadnego peera są po cichu odrzucane, więc błędny wpis wygląda dokładnie jak problem z zaporą ogniową.

Jeśli sam zarządzasz trasami, ustaw Table = off pod [Interface] i dodaj trasę, której chcesz. Wtedy nic nie jest dodawane automatycznie, więc trasa należy do tego, co podnosi interfejs.

OpenVPN: wypchnij trasę, a potem upewnij się, że dotarła

Na zwykłym serwerze zmiana to jedna dyrektywa w konfiguracji serwera, obok puli klientów.

push "route 10.20.0.0 255.255.0.0"

Klient dodaje ją przy połączeniu. Tryb awarii pojawia się, gdy ten sam profil wypycha także redirect-gateway, albo gdy ktoś już dodał route-nopull: pierwsze zamienia sesję w pełny tunel, a drugie odrzuca każdą wypchniętą trasę, także twoją.

Klient, który potrzebuje wąskiego zachowania wobec serwera z pełnym tunelem, powinien ignorować tylko te części, których nie chce. W OpenVPN 2.4 i nowszych istnieje pull-filter właśnie do tego.

pull-filter ignore "redirect-gateway"
route 10.20.0.0 255.255.0.0

Trzymaj rodziny adresów osobno: wypchnięta trasa IPv4 nic nie daje usłudze wewnętrznej, która rozwiązuje się na IPv6, i ta usługa zawodzi przez tunel, podczas gdy wszystko inne wygląda dobrze.

Gdy prywatna podsieć nie jest na serwerze VPN, lecz za innym klientem, serwer trzeba o tym poinformować. Dodaj plik dla każdego klienta przez client-config-dir zawierający iroute 10.20.0.0 255.255.0.0, plus pasujący route, aby inni klienci poznali drogę. Bez iroute serwer nie ma powodu wysyłać tego prefiksu właśnie tym tunelem.

IPsec: selektory ruchu muszą się zgodzić

Przy IPsec nie ma trasy do wypchnięcia. Oba końce negocjują, które adresy żyją w tunelu, a ruch poza uzgodnionymi selektorami nie jest ani szyfrowany, ani przez niego wysyłany. Na kliencie strongSwan selektory są jawne.

leftsubnet=192.168.1.0/24
rightsubnet=10.20.0.0/16

Jeśli brama jest skonfigurowana z 0.0.0.0/0 po obu stronach, zwężenie IKEv2 zwykle redukuje SA potomne do przecięcia obu propozycji, co jest pożądanym wynikiem. Niektóre bramy zamiast tego odrzucają propozycję, która nie pasuje do ich skonfigurowanych selektorów, a log pokazuje wtedy nieudane SA potomne, a nie skargę na routing. Gdy tak się dzieje, zmiana należy do bramy, bo trasa po stronie klienta nie może utworzyć tunelu dla selektora, którego druga strona nie zaakceptuje.

W Windows wbudowany klient ukrywa tę samą decyzję za dwoma ustawieniami. Podział tunelu musi być włączony, a prefiks musi być zarejestrowany w profilu.

Set-VpnConnection -Name Office -SplitTunneling $true
Add-VpnConnectionRoute -ConnectionName Office -DestinationPrefix 10.20.0.0/16

To właśnie rejestracja prefiksu sprawia, że przetrwa on ponowne połączenie, czego nie robi trasa dodana ręcznie.

Trzymaj punkt końcowy i DNS poza decyzją

Punkt końcowy VPN musi pozostać osiągalny bez tunelu, inaczej tunel zapada się w sobie. Gdy routing obejmuje tylko 10.20.0.0/16, dzieje się to automatycznie, bo punkt końcowy jest adresem publicznym. W profilu pełnego tunelu tak nie jest, a klient potrzebuje jawnej trasy do hosta punktu końcowego, zanim tunel się podniesie.

DNS to druga decyzja, której wypchnięcie trasy nie podejmuje za ciebie. Nazwy wewnętrzne rozwiązują się zwykle przez resolver osiągalny tylko z sieci prywatnej. Jeśli serwer wypycha serwer DNS, każda nazwa przechodzi przez niego; jeśli nie, nazwy wewnętrzne albo zawodzą, albo rozwiązują się publicznie na coś, czego nie zamierzałeś. Podzielony DNS trzyma jedną domenę wyszukiwania na wewnętrznym resolverze, ale zależy to od wsparcia klienta, więc traktuj to jako osobne zadanie, a nie skutek uboczny routingu.

Sprawdź, potem uruchom ponownie i sprawdź jeszcze raz

Trzy próby pokrywają kwestię routingu. Zapytaj jądro, dokąd trafiłby adres zdalny, pobierz coś z wnętrza podsieci, a następnie potwierdź, że zwykłe publiczne żądanie nadal wychodzi przez twoje normalne połączenie.

ip route get 10.20.5.7
curl -sS http://10.20.5.7/health
curl -sS https://ifconfig.me

Pierwsza linia nazywa interfejs. Jeśli nazywa twój interfejs fizyczny, trasa nigdy nie dotarła. W Windows Find-NetRoute -RemoteIPAddress 10.20.5.7 odpowiada na to samo pytanie, a ostatnia próba nadal powinna pokazywać twój zwykły adres, a nie adres serwera VPN.

Potem uruchom ponownie. Trasy dodane ręcznie znikają, a trasy z profilu, z wypchniętej konfiguracji lub z AllowedIPs wracają. Jeśli wąski dostęp działa przed restartem i zawodzi po nim, wina leży w sposobie startu tunelu, nie w samej trasie.

Zanim uznasz to za skończone, potwierdź cztery rzeczy: prefiks pochodzi od właściciela sieci i nie pokrywa się z niczym lokalnym, droga powrotna istnieje albo zastępuje ją reguła maskowania, skonfigurowany mechanizm to ten, który egzekwuje routing na twojej platformie, a te same próby przechodzą po czystym restarcie. notatki strongSwan o przekazywaniu są warte przeczytania, jeśli droga powrotna to ta część, która ciągle zawodzi.

Powiązane artykuły