Wenn Sie einem Standort-zu-Standort-Tunnel ein IPv6-Präfix hinzufügen, verläuft das Paket nicht so, wie es das Diagramm nahelegt. Das lokale Gateway nimmt das gesamte IPv6-Paket, verschlüsselt es und setzt einen äußeren IP-Header davor, dessen Adressfamilie von den Endpunktadressen bestimmt wird, nicht vom Inhalt. Das entfernte Gateway entfernt diesen äußeren Header und leitet das ursprüngliche Paket in sein LAN weiter, wo es wieder ein gewöhnliches IPv6-Paket ist. Äußerer Tunnel und innerer Verkehr sind zwei getrennte Gespräche, die einen Schlüssel, ein Endpunktpaar und sonst nichts gemeinsam haben.

Zwei Header, zwei Adressfamilien

Im IPsec-Tunnelmodus wird das innere IPv6-Paket zur Nutzlast hinter einem ESP-Header. Der äußere Header, der dieses ESP-Paket trägt, kann IPv4 oder IPv6 sein, und er folgt local_addrs und remote_addrs. WireGuard macht dasselbe mit weniger Zeremonie: Das innere Paket ist die Nutzlast eines UDP-Datagramms an den Endpunkt des Peers. Beide lassen den inneren Header unangetastet, weshalb die Gegenseite ihn nach der Entkapselung weiterleiten kann.

Der Pfad zwischen den Standorten sieht nur UDP 4500, wenn IPsec NAT-Traversal verwendet, oder UDP 51820 für einen Standard-WireGuard-Listener. Jeder Router unterwegs kann ausschließlich IPv4 sprechen, und der IPv6-Verkehr kreuzt trotzdem, weil er auf diesem Pfad nie als IPv6-Paket erscheint. Das ergibt eine saubere erste Trennung: tcpdump -ni eth0 udp port 51820 zeigt den verschlüsselten Pfad, tcpdump -ni wg0 ip6 den inneren Verkehr. Ein geschäftiger äußerer Mitschnitt mit stillem inneren bedeutet, dass der Kernel kein IPv6 in den Tunnel legt; das ist Routing oder Policy, nicht Linkzustand.

Das Gateway dekrementiert außerdem das innere Hop Limit, während es weiterleitet, sodass die Endpunkte auf dem IPv6-Pfad als Router zählen. Äußere Hop-Anzahl und inneres Hop Limit bewegen sich unabhängig, und ein Paket, das am entfernten Gateway stirbt, starb bei der Weiterleitung, nicht bei der Verschlüsselung.

Selektoren und AllowedIPs sind die Berechtigungsliste

IKEv2 handelt aus, welche inneren Präfixe eine Child-SA tragen darf. Auf strongSwan 5.9 und später sieht das Ausformulieren in swanctl.conf so aus:

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

Lassen Sie local_ts und remote_ts weg, leitet strongSwan sie aus den Subnetzen der Schnittstelle ab, die es auswählt. Auf einem Dual-Stack-Host ergibt diese Abkürzung oft ein reines IPv4-Paar: Die SA kommt hoch, und IPv6 wird abgelehnt, bevor es den ESP-Code erreicht. Beide Präfixe auszuschreiben macht die SA geeignet, sie zu tragen, und start_action = trap bringt sie beim ersten passenden Paket hoch.

WireGuard hat eine einzige Liste mit zwei Aufgaben. Im Peer-Block ist AllowedIPs = 2001:db8:bb::/48, fd00:bb::/48 sowohl die beim Senden installierte Route als auch der beim Empfang angewandte Filter: Ein entschlüsseltes Paket, dessen innere Quelle außerhalb der Liste dieses Peers liegt, wird still verworfen. wg-quick fügt pro Eintrag eine Route hinzu, daher braucht der Peer-Block unten keinen eigenen ip -6 route-Befehl.

[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

Beide Listen müssen gespiegelt sein: Standort B akzeptiert das Präfix von Standort A als entfernten Selektor und leitet es zurück, und der Tunnel funktioniert nur, wenn beide Richtungen übereinstimmen. Eine asymmetrische Liste erzeugt das Symptom, das die meiste Zeit kostet — einen gesunden Handshake, Zähler, die auf einer Seite laufen, und einen Ping von A nach B, der gelingt, während nichts von B den A erreicht.

Weiterleitung, Routen und das Rückpräfix

Linux leitet IPv6 erst weiter, wenn Sie es ihm sagen, und die Einstellung gilt pro Namespace statt pro Schnittstelle:

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

Die zweite Zeile ist die, die man bei routenbasierten Designs vergisst. Richtlinienbasiertes IPsec installiert eine XFRM-Policy, die auf die Präfixe passt, aber ein routenbasiertes Setup mit vti6 oder WireGuard braucht eine echte IPv6-Route, die auf dieses Gerät zeigt. Persistieren Sie das sysctl unter /etc/sysctl.d/; ein Neustart stellt die Weiterleitung sonst still auf aus zurück.

Die Weiterleitung hat einen wissenswerten Nebeneffekt: Der Kernel ignoriert dann Router Advertisements, solange net.ipv6.conf.<wan>.accept_ra nicht 2 ist, sodass ein Gateway, dessen WAN-Adresse per SLAAC ankommt, seine Standardroute verlieren kann, sobald Sie die Weiterleitung aktivieren. Setzen Sie accept_ra = 2 auf dieser Schnittstelle in derselben Datei, und die Route überlebt. Der Kern von Standort B muss 2001:db8:aa::/48 außerdem vom Tunnel-Gateway lernen, per statischer Route oder einem Routing-Protokoll über den Tunnel, sonst stirbt die Antwort im eigenen Netz von B.

Eine Vier-Schritt-Prüfung, die den Bruch lokalisiert

Arbeiten Sie in dieser Reihenfolge und stoppen Sie beim ersten Schritt, der scheitert, denn jeder spätere Schritt hängt von den früheren ab.

  1. Selektoren: swanctl --list-sas sollte das IPv6-Präfixpaar auf der Child-SA zeigen, oder wg show wg0 allowed-ips das entfernte Präfix mit einem aktuellen latest-handshakes.
  2. Kernel-Route: ip -6 route get 2001:db8:bb::10 muss mit dem Tunnelgerät antworten, nicht mit der WAN-Schnittstelle.
  3. Innerer Mitschnitt: tcpdump -ni wg0 ip6 während Sie zwischen echten LAN-Hosts pingen. Pakete, die hinausgehen, aber keine zurückkommen, deuten auf die Route oder Firewall von B; gar keine Pakete deuten auf Schritt 1 oder 2 zurück.
  4. Ziel: Auf dem B-Host bestätigt ss -6 -ltn, dass der Dienst auf IPv6 lauscht, und die lokalen Firewall-Zähler zeigen, ob das Paket akzeptiert oder verworfen wurde.

Die MTU gehört in denselben Durchgang. IPv6-Router fragmentieren nicht, daher wird ein übermäßig großes Paket verworfen und Packet Too Big kommt zum Absender zurück. Wenn Handshakes und kleine Pings funktionieren, aber eine Dateiübertragung stockt, verkleinern Sie die Nutzlast, bis sie durchgeht: ping -6 -s 1400 -c 3 2001:db8:bb::10. WireGuard-Schnittstellen haben standardmäßig 1420 Bytes MTU, und IPsec über IPv4 zieht mehr ab, daher ist es besser, die innere MTU zu setzen, als auf Pfad-MTU-Erkennung durch eine Firewall zu hoffen, die ICMPv6 verwirft.

Fehlermodi, die wie Firewall-Probleme aussehen

Der häufigste ist gar keine Firewall: Der Dienst bindet an 0.0.0.0 statt an ::, der AAAA-Eintrag existiert, und der Client erhält eine schnelle Ablehnung über IPv6, die ein Dual-Stack-Browser verbirgt, indem er auf IPv4 zurückfällt. Wenn nur einige Anwendungen scheitern, prüfen Sie die lauschende Familie, bevor Sie eine Regelsammlung anfassen.

Zweitens ist die ICMPv6-Filterung. Neighbor Discovery und Packet Too Big gehören zum Normalbetrieb, nicht zur Diagnose, und eine Policy, die sämtliches ICMPv6 verwirft, erzeugt einen Tunnel, der sich verbindet, authentifiziert und dann bei allem stockt, was größer als ein kleines Paket ist. Erlauben Sie die Typen, von denen der Pfad abhängt, und lassen Sie Zähler an, damit ein Verwerfen sichtbar wird.

Drittens ein Präfix, das dem Tunnel hinzugefügt, aber nie in den Adressplan des Standorts aufgenommen wird, dem es gehört, sodass kein Router es ankündigt und kein Host daraus antworten kann. Beginnen Sie mit einem Präfix und einem Host-Paar, beweisen Sie beide Richtungen mit den vier Schritten und fügen Sie dann den Rest hinzu; ein defektes Präfix bleibt eine Zeile in einer Konfiguration statt eines Umbaus. Die eine offizielle Referenz, die es sich lohnt offen zu halten, ist RFC 8200, der den Header definiert, den der Tunnel trägt.

Ähnliche Artikel