Când adaugi un prefix IPv6 la un tunel sit-la-sit, pachetul nu călătorește cum sugerează diagrama. Gateway-ul local ia întregul pachet IPv6, îl cifrează și pune în față un antet IP exterior a cărui familie de adrese este decisă de adresele capetelor, nu de ce se află în interior. Gateway-ul aflat la distanță scoate acel antet exterior și trimite mai departe pachetul original pe LAN-ul său, unde redevine un pachet IPv6 obișnuit. Tunelul exterior și traficul interior sunt două conversații separate care împart o cheie, o pereche de capete și nimic altceva.

Două antete, două familii de adrese

În modul tunel IPsec, pachetul IPv6 interior devine încărcătura utilă din spatele unui antet ESP. Antetul exterior care transportă acel pachet ESP poate fi IPv4 sau IPv6 și urmează local_addrs și remote_addrs. WireGuard face la fel cu mai puțin ceremonial: pachetul interior este încărcătura utilă a unui datagram UDP către capătul peer-ului. Ambele lasă antetul interior neatins, motiv pentru care partea aflată la distanță îl poate ruta după decapsulare.

Drumul dintre sedii vede doar UDP 4500 când IPsec folosește traversarea NAT, sau UDP 51820 pentru un ascultător WireGuard implicit. Orice router de pe drum poate fi doar IPv4 și traficul IPv6 trece oricum, pentru că nu apare niciodată ca pachet IPv6 pe acel drum. Asta dă o primă separare curată: tcpdump -ni eth0 udp port 51820 arată drumul cifrat, tcpdump -ni wg0 ip6 arată traficul interior. O captură exterioară aglomerată cu una interioară silențioasă înseamnă că nucleul nu pune IPv6 în tunel; este rutare sau politică, nu stare a legăturii.

Gateway-ul decrementează și limita de salt internă când înaintează, astfel încât capetele contează ca routere pe drumul IPv6. Numărul de salturi exterior și limita de salt internă se mișcă independent, iar un pachet care moare la gateway-ul aflat la distanță a murit în înaintare, nu în cifrare.

Selectoarele și AllowedIPs sunt lista de permisiuni

IKEv2 negociază ce prefixe interioare poate transporta o SA copil. Pe strongSwan 5.9 și mai nou, scrierea lor în swanctl.conf arată astfel:

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

Omiterea local_ts și remote_ts face ca strongSwan să le deducă din subneturile interfeței pe care o alege. Pe un host dual-stack acea scurtătură produce adesea o pereche doar IPv4: SA-ul urcă și IPv6 este refuzat înainte de a ajunge la codul ESP. Scrierea ambelor prefixe face SA-ul eligibil să le transporte, iar start_action = trap îl ridică la primul pachet potrivit.

WireGuard are o singură listă care face două treburi. În blocul de peer, AllowedIPs = 2001:db8:bb::/48, fd00:bb::/48 este atât ruta instalată la trimitere, cât și filtrul aplicat la recepție: un pachet decriptat a cărui sursă interioară cade în afara listei acelui peer este aruncat în silențio. wg-quick adaugă o rută pe fiecare intrare, deci blocul de peer de mai jos nu are nevoie de o comandă ip -6 route separată.

[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

Ambele liste trebuie să fie în oglindă: sediul B acceptă prefixul sediului A ca selector la distanță și îl rutează înapoi, iar tunelul funcționează doar când cele două direcții sunt de acord. O listă asimetrică produce simptomul care consumă cel mai mult timp — o strângere de mână sănătoasă, contoare care se mișcă pe o parte, și un ping de la A la B care reușește în timp ce nimic din B nu ajunge la A.

Înaintare, rute și prefixul de retur

Linux nu înaintează IPv6 până nu îi spui, iar setarea este pe namespace și nu pe interfață:

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

A doua linie este cea pe care oamenii o uită în designurile bazate pe rute. IPsec bazat pe politici instalează o politică XFRM care se potrivește cu prefixele, dar o configurare bazată pe rute cu vti6 sau WireGuard are nevoie de o rută IPv6 reală care să indice acel dispozitiv. Persistă sysctl-ul în /etc/sysctl.d/; altfel o repornire readuce în silențio înaintarea la dezactivat.

Înaintarea are un efect secundar care merită știut: nucleul ignoră atunci anunțurile de router dacă net.ipv6.conf.<wan>.accept_ra nu este 2, astfel încât un gateway al cărui adresă WAN sosește prin SLAAC poate pierde ruta implicită în momentul în care activezi înaintarea. Setează accept_ra = 2 pe acea interfață în același fișier și ruta supraviețuiește. Nucleul sediului B trebuie să învețe și 2001:db8:aa::/48 de la gateway-ul tunelului, prin rută statică sau un protocol de rutare peste tunel, altfel răspunsul moare în propria rețea a lui B.

O verificare în patru pași care localizează ruptura

Lucrează în această ordine și oprește-te la primul pas care eșuează, pentru că fiecare pas ulterior depinde de cele anterioare.

  1. Selectoare: swanctl --list-sas ar trebui să arate perechea de prefixe IPv6 pe SA-ul copil, sau wg show wg0 allowed-ips prefixul de la distanță cu un latest-handshakes recent.
  2. Rută kernel: ip -6 route get 2001:db8:bb::10 trebuie să răspundă cu dispozitivul tunelului, nu cu interfața WAN.
  3. Captură interioară: tcpdump -ni wg0 ip6 în timp ce dai ping între hosturi LAN reale. Pachete care ies dar niciunul care se întoarce indică ruta sau firewall-ul lui B; niciun pachet nu indică înapoi la pasul 1 sau 2.
  4. Destinație: pe hostul B, ss -6 -ltn confirmă că serviciul ascultă pe IPv6, iar contoarele locale ale firewall-ului arată dacă pachetul a fost acceptat sau eliminat.

MTU-ul intră în aceeași trecere. Routerele IPv6 nu fragmentează, deci un pachet supradimensionat este eliminat și Packet Too Big se întoarce la expeditor. Dacă strângerile de mână și ping-urile mici funcționează dar un transfer de fișier se blochează, redu încărcătura utilă până trece: ping -6 -s 1400 -c 3 2001:db8:bb::10. Interfețele WireGuard au implicit o MTU de 1420 bytes, iar IPsec peste IPv4 scade mai mult, deci a seta MTU-ul interior bate speranța într-o descoperire a MTU-ului de cale printr-un firewall care elimina ICMPv6.

Moduri de eșec care par probleme de firewall

Cel mai comun nu este deloc un firewall: serviciul se leagă la 0.0.0.0 în loc de ::, înregistrarea AAAA există, și clientul primește un refuz rapid pe IPv6 pe care un browser dual-stack îl ascunde revenind la IPv4. Dacă doar unele aplicații eșuează, verifică familia de ascultare înainte de a atinge un set de reguli.

Al doilea este filtrarea ICMPv6. Neighbor Discovery și Packet Too Big fac parte din funcționarea normală, nu din diagnosticare, iar o politică ce elimină tot ICMPv6 produce un tunel care se conectează, se autentifică și apoi se blochează pe orice mai mare decât un pachet mic. Permite tipurile de care depinde drumul și lasă contoarele pornite ca o eliminare să fie vizibilă.

Al treilea este un prefix adăugat la tunel dar niciodată la planul de adresare al sediului care îl deține, astfel încât niciun router nu îl anunță și niciun host nu poate răspunde din el. Începe cu un prefix și o pereche de hosturi, dovedește ambele direcții cu cei patru pași, apoi adaugă restul; un prefix stricat rămâne o linie într-o configurare în loc de o reproiectare. Singura referință oficială care merită ținută deschisă este RFC 8200, care definește antetul pe care tunelul îl transportă.

Articole similare