När du lägger till ett IPv6-prefix i en plats-till-plats-tunnel reser packetet inte som diagrammet antyder. Den lokala gatewayen tar hela IPv6-packetet, krypterar det och sätter en yttre IP-header framför vars adressfamilj bestäms av ändpunktsadresserna, inte av vad som finns inuti. Den bortre gatewayen strippar den yttre headern och vidarebefordrar det ursprungliga packetet till sitt LAN, där det åter är ett vanligt IPv6-packet. Yttre tunnel och inre trafik är två separata samtal som delar en nyckel, ett ändpunktspar och inget annat.

Två headers, två adressfamiljer

I IPsec-tunnelmod blir det inre IPv6-packetet nyttolasten bakom en ESP-header. Den yttre headern som bär det ESP-packetet kan vara IPv4 eller IPv6, och den följer local_addrs och remote_addrs. WireGuard gör samma sak med mindre ceremoni: det inre packetet är nyttolasten i ett UDP-datagram till peerns ändpunkt. Båda lämnar den inre headern orörd, vilket är varför den andra sidan kan routa den efter avkapsling.

Vägen mellan platserna ser bara UDP 4500 när IPsec använder NAT-traversering, eller UDP 51820 för en standard WireGuard-lyssnare. Varje router på vägen kan endast hantera IPv4 och IPv6-trafiken passerar ändå, eftersom den aldrig framträder som ett IPv6-packet på den vägen. Det ger en ren första uppdelning: tcpdump -ni eth0 udp port 51820 visar den krypterade vägen, tcpdump -ni wg0 ip6 visar den inre trafiken. En livlig yttre fångst med en tyst inre betyder att kärnan inte lägger IPv6 i tunneln; det är routing eller policy, inte länktillstånd.

Gatewayen minskar också den inre Hop Limit när den vidarebefordrar, så ändpunkterna räknas som routrar på IPv6-vägen. Yttre hoppantal och inre Hop Limit rör sig oberoende av varandra, och ett packet som dör vid den bortre gatewayen dog i vidarebefordran, inte i kryptering.

Selektorer och AllowedIPs är behörighetslistan

IKEv2 förhandlar vilka inre prefix en child-SA får bära. På strongSwan 5.9 och senare ser det ut så här när man skriver ut dem i swanctl.conf:

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

Utelämna local_ts och remote_ts så härleder strongSwan dem från subnäten på det gränssnitt den väljer. På en dual-stack-värd ger den genvägen ofta ett par med bara IPv4: SA:n kommer upp och IPv6 avvisas innan det når ESP-koden. Att skriva ut båda prefixen gör SA:n behörig att bära dem, och start_action = trap startar den vid första matchande packet.

WireGuard har en lista som gör två jobb. I peer-blocket är AllowedIPs = 2001:db8:bb::/48, fd00:bb::/48 både rutten som installeras vid sändning och filtret som tillämpas vid mottagning: ett dekrypterat packet vars inre källa faller utanför peerns lista släpps tyst. wg-quick lägger till en rutt per post, så peer-blocket nedan behöver inget separat ip -6 route-kommando.

[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

Båda listorna måste speglas: plats B accepterar plats A:s prefix som fjärrselektor och routar det tillbaka, och tunneln fungerar bara när de två riktningarna stämmer överens. En asymmetrisk lista ger symptomet som kostar mest tid — en frisk handskakning, räknare som rör sig på ena sidan, och en ping från A till B som lyckas medan inget från B når A.

Vidarebefordran, rutter och returprefixet

Linux vidarebefordrar inte IPv6 förrän du säger till, och inställningen gäller per namespace snarare än per gränssnitt:

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

Den andra raden är den man glömmer i ruttbaserade konstruktioner. Policybaserad IPsec installerar en XFRM-policy som matchar prefixen, men en ruttbaserad uppsättning med vti6 eller WireGuard behöver en verklig IPv6-rutt som pekar på den enheten. Beständiggör sysctl-värdet under /etc/sysctl.d/; annars återställer en omstart vidarebefordran tyst till av.

Vidarebefordran har en bieffekt värd att känna till: kärnan ignorerar då router advertisements med mindre net.ipv6.conf.<wan>.accept_ra är 2, så en gateway vars WAN-adress anländer via SLAAC kan förlora sin standardrutt i samma stund som du aktiverar vidarebefordran. Sätt accept_ra = 2 på det gränssnittet i samma fil så överlever rutten. Plats B:s core måste också lära sig 2001:db8:aa::/48 från tunnelgatewayen, via en statisk rutt eller ett routingprotokoll över tunneln, annars dör svaret inne i B:s eget nätverk.

En fyrastegscheck som lokaliserar brottet

Arbeta i den här ordningen och stoppa vid första steget som misslyckas, eftersom varje senare steg beror på de tidigare.

  1. Selektorer: swanctl --list-sas bör visa IPv6-prefixparet på child-SA:n, eller wg show wg0 allowed-ips fjärrprefixet med en färsk latest-handshakes.
  2. Kärnrutt: ip -6 route get 2001:db8:bb::10 måste svara med tunnel-enheten, inte WAN-gränssnittet.
  3. Inre fångst: tcpdump -ni wg0 ip6 medan du pingar mellan riktiga LAN-värdar. Packet som går ut men inga som kommer tillbaka pekar på B:s rutt eller brandvägg; inga packet alls pekar tillbaka på steg 1 eller 2.
  4. Destination: på B-värden bekräftar ss -6 -ltn att tjänsten lyssnar på IPv6, och de lokala brandväggsräknarna visar om packetet accepterades eller släpptes.

MTU hör till samma genomgång. IPv6-routrar fragmenterar inte, så ett för stort packet släpps och Packet Too Big kommer tillbaka till avsändaren. Om handskakningar och små ping fungerar men en filöverföring stockar, krymp nyttolasten tills den passerar: ping -6 -s 1400 -c 3 2001:db8:bb::10. WireGuard-gränssnitt har som standard 1420 byte MTU och IPsec över IPv4 drar av mer, så att sätta den inre MTU:n slår att hoppas på path-MTU-upptäckt genom en brandvägg som släpper ICMPv6.

Felmoder som ser ut som brandväggsproblem

Den vanligaste är inte en brandvägg alls: tjänsten binder till 0.0.0.0 i stället för ::, AAAA-posten finns, och klienten får ett snabbt avslag över IPv6 som en dual-stack-webbläsare döljer genom att falla tillbaka till IPv4. Om bara vissa program misslyckas, kontrollera den lyssnande familjen innan du rör en regeluppsättning.

Den andra är ICMPv6-filtrering. Neighbor Discovery och Packet Too Big är en del av normal drift, inte diagnostik, och en policy som släpper all ICMPv6 ger en tunnel som ansluter, autentiserar och sedan stockar på allt större än ett litet packet. Tillåt de typer vägen beror på och lämna räknarna på så att ett släpp syns.

Den tredje är ett prefix som läggs till i tunneln men aldrig i adressplanen för platsen som äger det, så ingen router annonserar det och ingen värd kan svara från det. Börja med ett prefix och ett värdpar, bevisa båda riktningarna med de fyra stegen och lägg sedan till resten; ett trasigt prefix blir kvar som en rad i en konfiguration i stället för en omkonstruktion. Den enda officiella referens som är värd att hålla öppen är RFC 8200, som definierar headern som tunneln bär.

Relaterade artiklar