Czy ruch IPv6 powinien przechodzić przez VPN, czy bezpośrednio?
Zdecyduj, czy ::/0 należy do wnętrza tunelu, według trzech warunków: obsługi wyjścia, osiągalności punktu końcowego i wyłącznie sieci lokalnych.
W zeszłym miesiącu dwie osoby poprosiły mnie o przeciwne wyniki: jedna chciała, aby VPN obejmował IPv6, druga chciała, aby drukarka biurowa nadal działała. Jedna trasa ::/0 nie może sama zapewnić obu. To, czy ta trasa należy do wnętrza tunelu, zależy od trzech warunków, a pierwszy wyklucza ją w większości komercyjnych wyjść. Jeśli wyjście nie niesie IPv6, kierowanie domyślnej trasy do niego ukrywa ruch w tunelu, który nie ma gdzie go wysłać.
Trzy warunki decydują o odpowiedzi
Trasa domyślna to jedna linia, ::/0, i pasuje do każdego celu IPv6 bez bardziej szczegółowej trasy (RFC 4291). Jej instalacja jest łatwa. Decyzja, czy powinieneś, sprowadza się do trzech warunków.
Warunek pierwszy: wyjście, z którym się łączysz, ma działający IPv6 i jest gotowe go przekazywać. Warunek drugi: twój klient może utrzymać ścieżkę do punktu końcowego tunelu, który zwykle znajduje się w zakresie, który zamierzasz trasować. Warunek trzeci: możesz nazwać lokalne cele IPv6, które muszą pozostać poza tunelem.
Każdy warunek zawodzi na swój sposób, dlatego zgadywanie kosztuje cały wieczór. Nieudany pierwszy warunek daje ciszę i tabelę tras, która wygląda poprawnie. Nieudany drugi warunek zabija uścisk dłoni kilka sekund po rozpoczęciu. Nieudany trzeci warunek zostawia działający tunel i niezadowolonego kolegę przy drukarce.
| What you see | Decision |
|---|---|
| Exit answers IPv6 probes, no local IPv6 devices to protect | Route ::/0 into the tunnel |
| Exit answers IPv6 probes, printer or NAS reachable by a global address | Route ::/0, then give those prefixes a route of their own |
| Exit is IPv4-only inside the tunnel | Do not route ::/0; block IPv6 on the client |
Endpoint is reached over IPv6 and sits inside ::/0 | Install a host route for the endpoint first |
Czy wyjście naprawdę niesie IPv6?
Interfejs tunelu z adresem IPv6 niczego nie dowodzi o drugiej stronie. Wiele komercyjnych profili jest w środku tylko IPv4: serwer daje ci adres v4 i wyrzuca wszystko inne. Zainstaluj na tym trasę domyślną z AllowedIPs, a jądro chętnie wyśle IPv6 do interfejsu, którego partner nigdy go nie widzi.
Testuj z klienta, gdy tunel jest podniesiony. ping -6 -c 3 2001:4860:4860::8888 i ip -6 route get 2001:4860:4860::8888 odpowiadają na różne pytania: czy wraca odpowiedź i które urządzenie wybrało jądro. Gdy drugie wskazuje twój tunel, a pierwsze nic nie zwraca, problem jest w wyjściu, nie w trasie.
Jeśli sam prowadzisz wyjście, test klienta może przejść, a ścieżka mimo to skończyć się w ślepym zaułku. Potwierdź net.ipv6.conf.all.forwarding=1 na bramie i że jej firewall akceptuje pakiety przekazywane z tunelu. Poprawnie zatrasowany pakiet do wyjścia, które odmawia przekazywania, wygląda z perspektywy klienta dokładnie jak błąd routingu.
Czy klient może utrzymać ścieżkę do punktu końcowego?
To jest przypadek, który złapał mnie na laptopie z punktem końcowym WireGuard tylko IPv6. Adres punktu końcowego to zwykły adres globalny, więc wpada w ::/0. Zatrasuj cały prefiks do interfejsu, a pakiety uścisku dłoni będą gonić same siebie do tunelu, który wciąż próbują zbudować. Tunel nigdy nie wstaje, a nic w wyjściu klienta nie mówi dlaczego.
wg-quick radzi sobie z tym na Linuksie. Wyprowadza trasy z AllowedIPs, instaluje je we własnej tabeli i dodaje regułę polityki, aby ruch do punktu końcowego był najpierw rozwiązywany przez tabelę główną: reguła suppress_prefixlength 0, którą znajdziesz w ip -6 rule. Dlatego wg-quick up udaje się tam, gdzie ręcznie napisana ip -6 route add default dev wg0 cię odcina.
Sprawdź oba stany za pomocą ip -6 route get <endpoint-v6>, przed podniesieniem tunelu i po nim. Jeśli odpowiedź zmieni się na twoje urządzenie tunelowe, usunąłeś ścieżkę, której tunel potrzebuje. Gdy sam piszesz trasy, dodaj trasę hosta do punktu końcowego przez pierwotną bramę, albo połącz się z punktem końcowym przez IPv4 i zostaw IPv6 ładunkowi.
Co musi pozostać poza tunelem?
Bardziej szczegółowe trasy wygrywają z domyślną, więc prefiks na łączu lub zakres ULA z własną trasą nadal działa bez dodatkowego wysiłku. To jest cichy powód, dla którego tak wiele konfiguracji IPv4 z pełnym tunelem przetrwa: prefiksy LAN są bardziej szczegółowe niż domyślna trasa i nigdy nie wchodzą do tunelu.
Psuje się, gdy lokalne urządzenie jest osiągalne przez adres globalny, co jest normalne dla drukarki, której ten sam router dał publiczny prefiks, NAS-a lub telewizora. Te adresy pasują do ::/0 i do niczego innego, więc przenoszą się do tunelu razem z resztą i znikają.
Decyduj według celu, nie według protokołu. Jeśli liczą się dwa lub trzy lokalne hosty, daj ich prefiksom trasę na zewnątrz przez interfejs fizyczny, albo usuń je z wynegocjowanego zbioru. Jeśli lista nadal rośnie, uczciwą odpowiedzią jest split tunneling dla IPv6 z pisemną listą wyjątków, a nie domyślna trasa, którą ciągle łatasz.
Jeśli odpowiedź brzmi nie, zablokuj to
Pozostawienie IPv6 bez trasy to nie to samo, co pozostawienie go w spokoju. Host z działającą domyślną trasą IPv6 nadal jej używa, gdy tunel niesie IPv4, więc ruch wychodzi obok VPN i każda usługa, która preferuje IPv6, widzi twój prawdziwy adres. To wyciek, nie split tunnel.
Wybierz jedno i zapisz, które wybrałeś. Zatrasuj domyślną i zaakceptuj powyższe kompromisy, albo wyłącz IPv6 na czas trwania tunelu. Pominięcie prefiksu z AllowedIPs samo nie wystarczy, bo system operacyjny trzyma własną trasę domyślną. Na Linuksie brutalna wersja to sysctl -w net.ipv6.conf.all.disable_ipv6=1; subtelniejsza wersja zrzuca IPv6 poza tunel regułą firewalla. Klienci telefoniczni mają wyraźny przełącznik blokowania IPv6, który robi to samo.
Zweryfikuj to jak wyciek
Podnieś tunel i odczytaj stan, zamiast ufać przełącznikowi. ip -6 route show default powinien pokazać jedną trasę domyślną, a ip -6 route get dla celu poza twoją LAN powinien wskazać urządzenie tunelowe. Powtórz oba po rozłączeniu: trasa domyślna, która przeżyje tunel, to błąd, którego szukałeś.
Następnie przetestuj przeciwny kierunek. Z hosta w sieci lokalnej dotrzyj do klienta na jego lokalnym adresie IPv6. Jeśli to przestanie działać, warunek trzeci nigdy nie został spełniony, cokolwiek twierdziła wtedy tabela tras.
Zapisz wynik tam, gdzie znajdzie go następna osoba: które prefiksy pozostają lokalne, dlaczego i co klient robi po rozłączeniu. Dwie linie w runbooku oszczędzają następnemu inżynierowi ponownego odkrywania pętli punktu końcowego o północy.