Podnosisz tunel, pingujesz fe80::1 z tunelem jako interfejsem źródłowym i nic nie wraca. To nie jest zapomniana reguła firewalla. Adres link-local ma znaczenie tylko na tym jednym łączu, na którym powstał, a trasowany VPN nie jest tym łączem. fe80::1 zdalnego routera żyje w zdalnym segmencie LAN; ty siedzisz o jeden skok dalej w innym segmencie, a IPv6 w ogóle nie ma mechanizmu, dzięki któremu router przekazywałby pakiety link-local.

Prefiks fe80 opisuje zakres, nie przedział

Link-local unicast to fe80::/10, a cechą definiującą nie jest liczba, lecz zakres. Adres jest ważny tylko na jednym łączu, a każdy interfejs tworzy jeden ze swojego identyfikatora, dlatego dwie niepowiązane maszyny w dwóch niepowiązanych sieciach mogą obie odpowiadać na fe80::1 bez najmniejszego konfliktu. Prefiks w zasadzie mówi „na pewnym łączu”; samo łącze pochodzi z kontekstu.

Na hoście tym kontekstem jest strefa, czyli scope ID, którą dodajesz po znaku procentu: fe80::1%eth0 w Linuksie, fe80::1%3 lub fe80::1%12 w Windows i w narzędziach pokazujących indeksy interfejsów. Jądro rozwiązuje adres razem z indeksem interfejsu i dopiero wtedy wysyła. Jeśli usuniesz strefę, cel staje się niejednoznaczny, więc stos nie ma sposobu wybrać segmentu.

Dlaczego trasowany tunel nie może go dostarczyć

Trasowany VPN to interfejs punkt-punkt niosący własne adresy, zwykle /64 przestrzeni IPv6 unique-local lub prywatnej wewnątrz tunelu. Zdalny LAN to osobne łącze, osiągane przez punkt końcowy tunelu, który trasuje i przekazuje w twoim imieniu. To dwa różne segmenty, więc adres z jednego nie jest prawidłowym celem w drugim.

Reguła przekazywania jest wprost zapisana w standardzie, a nie kaprysem twojego klienta: routery nie przekazują pakietów z link-local źródłem lub celem. Dlatego pakiet ginie nawet wtedy, gdy tabela tras wygląda poprawnie. Dodaj trasę dla fe80::/64 wskazującą tunel, a zgodny stos albo ją odrzuci, albo przyjmie i odrzuci każdy pasujący pakiet: zakres celu mówi „tylko to łącze”, a interfejs wychodzący nie jest tym łączem.

Wykrywanie sąsiadów umacnia tę samą granicę. Hosty rozwiązują link-local następne skoki żądaniem sąsiada wysyłanym do multicastu w zakresie łącza z limitem skoku 255, więc routery mogą odrzucić wszystko, co zostanie przekazane. Doprowadzenie tego do działania przez tunel oznaczałoby proxy wykrywania dla zdalnego segmentu, czyli mostkowanie Layer 2 w innym kapeluszu.

Jest cichsza druga awaria i łapie ludzi, którzy mimo to próbują wymusić trasę: strefa. Każda strefa wpisana lokalnie nazywa interfejs tunelu, podczas gdy adres, którego chcesz, jest związany z interfejsem zdalnego LAN. Te dwa nigdy się nie zgadzają, więc pakietu nie da się skierować na właściwy interfejs na drugim końcu.

Jak awaria wygląda w praktyce

Wyjście narzędzia przy błędzie zakresu czyta się jak błąd trasowania lub firewalla i właśnie dlatego ludzie spędzają popołudnie w niewłaściwej warstwie.

What you runWhat you seeWhat it means
ping fe80::1 with no zoneInvalid argument on Linux, or a transmit failure on WindowsThe stack cannot pick an interface for an ambiguous destination
ping -6 -I tun0 fe80::1Destination unreachable, or a silent timeoutThe address is not on the tunnel link, so there is nothing on-link to answer
ssh user@fe80::1 after the tunnel is upHangs, then no route to hostThe SYN never left the machine in a deliverable form; the server logs nothing
ip -6 neigh show dev tun0Empty tableNo neighbor entry can exist for a link-local host that is not on this link
fe80::/64 inside AllowedIPs or route-ipv6Config accepted, traffic still droppedThe tunnel carried the packet; the receiving stack refused to forward it

Trzeci wiersz marnuje najwięcej czasu, bo klient ssh bez wyjścia wygląda jak problem z usługą nasłuchującą. Jeśli masz jakikolwiek sposób wejścia, sprawdź zdalną stronę i potwierdź, czy sshd jest związany ze wszystkimi adresami, czy tylko z jednym.

Użyj adresu, który był przeznaczony do trasowania

Dla wszystkiego, do czego musisz dotrzeć przez tunel, użyj adresu, który usługa otrzymała właśnie w tym celu: globalnego adresu unicast albo adresu unique-local z fc00::/7, zakresu zarezerwowanego dokładnie dla tego wewnętrznego przypadku. Potwierdź, że nasłuchujący naprawdę go wiąże, i sprawdź ścieżkę powrotną oraz każdą regułę firewalla hosta.

Spójrz na zdalny host zamiast zgadywać. ip -6 addr show wylicza istniejące adresy, a ss -6 -ltn wylicza, czego słucha demon. Usługa związana tylko z fe80:: jest osiągalna wyłącznie z własnego segmentu, co zwykle jest domyślnym ustawieniem, którego nikt nie wybrał celowo i które można zmienić za zgodą administratora.

Gdy usługi naprawdę nie można ponownie związać, przenieś mostek wyżej, do warstwy aplikacji zamiast warstwy sieci. Przekaźnik na zdalnym hoście, który nasłuchuje na adresie trasowalnym i łączy się z link-local, rozwiązuje problem bez rozszerzania żadnego segmentu:

socat TCP6-LISTEN:8080,bind=[fd00:1:2::10] TCP6:[fe80::1%eth0]:80

Tutaj strefa jest po właściwej stronie, na hoście, który naprawdę ma eth0 na tym łączu. Twój klient rozmawia z fd00:1:2::10, który jest trasowany normalnie, a przekaźnik wykonuje skok link-local lokalnie. Ta sama sztuczka działa dla interfejsu webowego urządzenia lub starego BMC, który ogłasza tylko adres link-local.

Kiedy mostkowanie naprawdę jest odpowiedzią, i co sprawdzić

Niektóre wdrożenia naprawdę potrzebują jednego współdzielonego segmentu: urządzenia, które mówi tylko wykrywaniem link-local, sprzętu zależnego od multicastu, laboratorium odtwarzającego płaski LAN. To problem Layer 2 i wymaga odpowiedzi Layer 2, na przykład urządzenia tap mostkowanego do zdalnego interfejsu lub produktu klienckiego z jawnym trybem mostkowania. Kosztuje to ruch broadcast i multicast przechodzący przez tunel oraz wykrywanie sąsiadów, które musi działać od końca do końca.

Nie zbliżaj się do tego, dodając fe80::/64 do profilu trasowanego. To daje najgorszy stan: konfiguracja wygląda na skończoną, tabela tras pokazuje wpis, a każdy pakiet nadal jest odrzucany gdzieś między dwoma stosami, które oba zachowują się poprawnie.

Sprawdzaj interfejsem, a nie pingiem. ip -6 addr show tun0 mówi, czy łącze tunelu utworzyło własny adres link-local, a ip -6 route get fe80::1%tun0 mówi, co jądro naprawdę zrobiłoby z celem o określonym zakresie. Gdy jądro mówi, że cel jest nieosiągalny na tym interfejsie, żadne ustawienie tunelu tego nie zmieni i czas przestać edytować profil.

Krótka sekwencja, która rozstrzyga pytanie:

  • Odczytaj adres na zdalnym hoście i zauważ, czy to fe80::, czy prefiks trasowalny.
  • Jeśli to fe80::, zwiąż usługę ponownie, zrób przekaźnik na tym hoście albo zmostkuj segment; jeśli jest trasowalny, napraw trasę, firewall lub adres bindowania.
  • Sprawdzaj strefę za każdym razem, gdy testujesz ponownie, bo skopiowane polecenie zwykle zachowuje niewłaściwy interfejs.

Źródła: RFC 4291, architektura adresowania IPv6.

Powiązane artykuły