Gdy dodajesz prefiks IPv6 do tunelu między witrynami, pakiet nie podróżuje tak, jak sugeruje diagram. Lokalna brama bierze cały pakiet IPv6, szyfruje go i umieszcza przed nim zewnętrzny nagłówek IP, którego rodzinę adresów wyznaczają adresy punktów końcowych, a nie to, co jest w środku. Zdalna brama zdejmuje ten zewnętrzny nagłówek i przekazuje oryginalny pakiet do swojej sieci LAN, gdzie znów jest zwykłym pakietem IPv6. Zewnętrzny tunel i ruch wewnętrzny to dwie osobne rozmowy, które dzielą klucz, parę punktów końcowych i nic więcej.

Dwa nagłówki, dwie rodziny adresów

W trybie tunelu IPsec wewnętrzny pakiet IPv6 staje się ładunkiem za nagłówkiem ESP. Zewnętrzny nagłówek przenoszący ten pakiet ESP może być IPv4 lub IPv6 i podąża za local_addrs oraz remote_addrs. WireGuard robi to samo z mniejszą ceremonią: wewnętrzny pakiet jest ładunkiem datagramu UDP do punktu końcowego partnera. Oba pozostawiają wewnętrzny nagłówek nietknięty, dlatego strona zdalna może go trasować po dekapssulacji.

Ścieżka między witrynami widzi tylko UDP 4500, gdy IPsec używa przechodzenia NAT, albo UDP 51820 dla domyślnego odbiornika WireGuard. Dowolny router na ścieżce może być tylko IPv4, a ruch IPv6 mimo to przechodzi, ponieważ nigdy nie pojawia się jako pakiet IPv6 na tej ścieżce. Daje to czysty pierwszy podział: tcpdump -ni eth0 udp port 51820 pokazuje ścieżkę szyfrowaną, tcpdump -ni wg0 ip6 pokazuje ruch wewnętrzny. Zajęte przechwytywanie zewnętrzne z cichym wewnętrznym oznacza, że jądro nie wkłada IPv6 do tunelu; to trasowanie lub polityka, a nie stan łącza.

Brama zmniejsza też wewnętrzny Hop Limit podczas przekazywania, więc punkty końcowe liczą się jako routery na ścieżce IPv6. Liczba przeskoków zewnętrznych i wewnętrzny Hop Limit poruszają się niezależnie, a pakiet, który ginie na zdalnej bramie, zginął w przekazywaniu, a nie w szyfrowaniu.

Selektory i AllowedIPs to lista uprawnień

IKEv2 negocjuje, które prefiksy wewnętrzne może przenosić child SA. W strongSwan 5.9 i nowszych wypisanie ich w swanctl.conf wygląda tak:

children {
  net6 {
    local_ts  = 2001:db8:aa::/48
    remote_ts = 2001:db8:bb::/48
    mode = tunnel
    esp_proposals = aes256gcm16-prfsha384-ecp384
    start_action = trap
  }
}

Pominięcie local_ts i remote_ts sprawia, że strongSwan wyprowadza je z podsieci wybranej przez siebie interfejsu. Na hoście dual-stack ten skrót często daje parę tylko IPv4: SA wstaje, a IPv6 jest odrzucane, zanim dotrze do kodu ESP. Wypisanie obu prefiksów czyni SA zdolnym do ich przenoszenia, a start_action = trap podnosi je przy pierwszym pasującym pakiecie.

WireGuard ma jedną listę pełniącą dwie funkcje. W bloku partnera AllowedIPs = 2001:db8:bb::/48, fd00:bb::/48 jest zarówno trasą instalowaną podczas wysyłania, jak i filtrem stosowanym podczas odbioru: odszyfrowany pakiet, którego wewnętrzne źródło wypada poza listę tego partnera, jest po cichu odrzucany. wg-quick dodaje trasę dla każdego wpisu, więc poniższy blok partnera nie wymaga osobnego polecenia ip -6 route.

[Interface]
Address = 2001:db8:aa:ff::1/64, fd00:aa:ff::1/64
ListenPort = 51820

[Peer]
PublicKey = <site-b-public-key>
Endpoint = 203.0.113.20:51820
AllowedIPs = 2001:db8:bb::/48, fd00:bb::/48

Obie listy muszą być lustrzane: witryna B akceptuje prefiks witryny A jako selektor zdalny i trasuje go z powrotem, a tunel działa tylko wtedy, gdy oba kierunki się zgadzają. Asymetryczna lista daje objaw, który pochłania najwięcej czasu — zdrowy uścisk dłoni, liczniki ruszające się po jednej stronie, i ping z A do B, który się udaje, gdy nic z B nie dociera do A.

Przekazywanie, trasy i prefiks zwrotny

Linux nie przekazuje IPv6, dopóki nie powiesz, a ustawienie dotyczy przestrzeni nazw, a nie interfejsu:

sysctl -w net.ipv6.conf.all.forwarding=1
ip -6 route add 2001:db8:bb::/48 dev wg0
ip -6 route get 2001:db8:bb::10 from 2001:db8:aa::10

Druga linia to ta, o której ludzie zapominają w projektach opartych na trasach. IPsec oparty na polityce instaluje politykę XFRM pasującą do prefiksów, ale konfiguracja oparta na trasach z vti6 lub WireGuard wymaga prawdziwej trasy IPv6 wskazującej na to urządzenie. Utrwal sysctl w /etc/sysctl.d/; w przeciwnym razie restart po cichu przywraca przekazywanie do wyłączonego.

Przekazywanie ma efekt uboczny, który warto znać: jądro ignoruje wtedy ogłoszenia routerów, chyba że net.ipv6.conf.<wan>.accept_ra wynosi 2, więc brama, której adres WAN przychodzi przez SLAAC, może stracić domyślną trasę w momencie włączenia przekazywania. Ustaw accept_ra = 2 na tym interfejsie w tym samym pliku, a trasa przetrwa. Rdzeń witryny B musi też nauczyć się 2001:db8:aa::/48 od bramy tunelu, przez trasę statyczną lub protokół trasowania nad tunelem, inaczej odpowiedź ginie we własnej sieci B.

Czterostopniowa kontrola, która lokalizuje przerwanie

Pracuj w tej kolejności i zatrzymaj się na pierwszym kroku, który zawiedzie, bo każdy kolejny zależy od poprzednich.

  1. Selektory: swanctl --list-sas powinien pokazać parę prefiksów IPv6 na child SA, albo wg show wg0 allowed-ips zdalny prefiks ze świeżym latest-handshakes.
  2. Trasa jądra: ip -6 route get 2001:db8:bb::10 musi odpowiedzieć urządzeniem tunelu, a nie interfejsem WAN.
  3. Przechwytywanie wewnętrzne: tcpdump -ni wg0 ip6 podczas pingowania między prawdziwymi hostami LAN. Pakiety, które wychodzą, ale żaden nie wraca, wskazują na trasę lub zaporę B; zupełnie brak pakietów wskazuje z powrotem na krok 1 lub 2.
  4. Cel: na hoście B ss -6 -ltn potwierdza, że usługa nasłuchuje na IPv6, a lokalne liczniki zapory pokazują, czy pakiet został przyjęty, czy odrzucony.

MTU należy do tej samej rundy. Routery IPv6 nie fragmentują, więc zbyt duży pakiet jest odrzucany, a Packet Too Big wraca do nadawcy. Jeśli uściski dłoni i małe pingi działają, ale transfer pliku staje, zmniejsz ładunek, aż przejdzie: ping -6 -s 1400 -c 3 2001:db8:bb::10. Interfejsy WireGuard mają domyślnie MTU 1420 bajtów, a IPsec nad IPv4 odejmuje więcej, więc ustawienie wewnętrznego MTU jest lepsze niż liczenie na wykrycie MTU ścieżki przez zaporę, która odrzuca ICMPv6.

Tryby awarii, które wyglądają jak problemy z zaporą

Najczęstszy wcale nie jest zaporą: usługa wiąże się z 0.0.0.0 zamiast ::, rekord AAAA istnieje, a klient dostaje szybką odmowę przez IPv6, którą przeglądarka dual-stack ukrywa, cofając się do IPv4. Jeśli zawodzą tylko niektóre aplikacje, sprawdź rodzinę nasłuchu, zanim dotkniesz zestawu reguł.

Drugi to filtrowanie ICMPv6. Neighbor Discovery i Packet Too Big są częścią normalnej pracy, a nie diagnostyki, a polityka odrzucająca cały ICMPv6 tworzy tunel, który się łączy, uwierzytelnia, a potem staje na wszystkim większym niż mały pakiet. Zezwól na typy, od których zależy ścieżka, i zostaw liczniki włączone, aby odrzucenie było widoczne.

Trzeci to prefiks dodany do tunelu, ale nigdy do planu adresowania witryny, która go posiada, więc żaden router go nie rozgłasza i żaden host nie może z niego odpowiedzieć. Zacznij od jednego prefiksu i jednej pary hostów, udowodnij oba kierunki czterema krokami, a potem dodaj resztę; zepsuty prefiks zostaje jedną linią w konfiguracji zamiast przebudowy. Jedynym oficjalnym źródłem, które warto trzymać otwarte, jest RFC 8200, który definiuje nagłówek przenoszony przez tunel.

Powiązane artykuły