Enrutar IPv6 entre dos sedes sobre una VPN existente
Una WAN solo IPv4 puede seguir transportando IPv6 interno. Sigue los selectores, las rutas del kernel, el reenvío y el prefijo de retorno que descarta respuestas en silencio.
Cuando añades un prefijo IPv6 a un túnel de sede a sede, el paquete no viaja como sugiere el diagrama. La pasarela local toma el paquete IPv6 completo, lo cifra y coloca delante una cabecera IP externa cuya familia de direcciones la deciden las direcciones de los extremos, no lo que hay dentro. La pasarela remota quita esa cabecera externa y reenvía el paquete original a su LAN, donde vuelve a ser un paquete IPv6 normal. Túnel externo y tráfico interno son dos conversaciones distintas que comparten una clave, un par de extremos y nada más.
Dos cabeceras, dos familias de direcciones
En modo túnel IPsec, el paquete IPv6 interno se convierte en la carga útil detrás de una cabecera ESP. La cabecera externa que transporta ese paquete ESP puede ser IPv4 o IPv6, y sigue local_addrs y remote_addrs. WireGuard hace lo mismo con menos ceremonia: el paquete interno es la carga útil de un datagrama UDP al extremo del par. Ambos dejan intacta la cabecera interna, y por eso el lado remoto puede enrutarla tras la desencapsulación.
El camino entre las sedes solo ve UDP 4500 cuando IPsec usa la travesía NAT, o UDP 51820 para un escucha WireGuard predeterminado. Cualquier router del trayecto puede ser solo IPv4 y el tráfico IPv6 cruza igualmente, porque nunca aparece como paquete IPv6 en ese camino. Eso da una primera separación limpia: tcpdump -ni eth0 udp port 51820 muestra el camino cifrado, tcpdump -ni wg0 ip6 muestra el tráfico interno. Una captura externa con mucho tráfico y una interna silenciosa significa que el kernel no está metiendo IPv6 en el túnel; es enrutamiento o política, no estado del enlace.
La pasarela también decrementa el límite de saltos interno al reenviar, así que los extremos cuentan como routers en la ruta IPv6. El número de saltos externo y el límite de saltos interno se mueven de forma independiente, y un paquete que muere en la pasarela remota murió en el reenvío, no en el cifrado.
Los selectores y AllowedIPs son la lista de permisos
IKEv2 negocia qué prefijos internos puede transportar una SA hija. En strongSwan 5.9 y posteriores, escribirlos en swanctl.conf se ve así:
children {
net6 {
local_ts = 2001:db8:aa::/48
remote_ts = 2001:db8:bb::/48
mode = tunnel
esp_proposals = aes256gcm16-prfsha384-ecp384
start_action = trap
}
}
Omite local_ts y remote_ts y strongSwan los deriva de las subredes de la interfaz que selecciona. En un host de doble pila ese atajo suele producir un par solo IPv4: la SA se levanta y IPv6 se rechaza antes de llegar al código ESP. Escribir ambos prefijos hace que la SA sea apta para transportarlos, y start_action = trap la levanta con el primer paquete que coincide.
WireGuard tiene una sola lista que cumple dos funciones. En el bloque de par, AllowedIPs = 2001:db8:bb::/48, fd00:bb::/48 es tanto la ruta instalada al enviar como el filtro aplicado al recibir: un paquete descifrado cuya origen interna queda fuera de esa lista se descarta en silencio. wg-quick añade una ruta por entrada, así que el bloque de par de abajo no necesita un comando ip -6 route aparte.
[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
Ambas listas deben estar espejadas: la sede B acepta el prefijo de la sede A como selector remoto y lo enruta de vuelta, y el túnel solo funciona cuando las dos direcciones coinciden. Una lista asimétrica produce el síntoma que más tiempo cuesta: un apretón de manos sano, contadores que se mueven en un lado, y un ping de A a B que funciona mientras nada de B llega a A.
Reenvío, rutas y el prefijo de retorno
Linux no reenvía IPv6 hasta que se lo dices, y el ajuste es por espacio de nombres y no por interfaz:
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
La segunda línea es la que se olvida en los diseños basados en rutas. IPsec basado en políticas instala una política XFRM que coincide con los prefijos, pero una configuración basada en rutas con vti6 o WireGuard necesita una ruta IPv6 real que apunte a ese dispositivo. Haz persistente el sysctl en /etc/sysctl.d/; de lo contrario, un reinicio devuelve el reenvío a desactivado en silencio.
El reenvío tiene un efecto secundario que conviene conocer: el kernel ignora entonces los anuncios de router salvo que net.ipv6.conf.<wan>.accept_ra sea 2, así que una pasarela cuya dirección WAN llega por SLAAC puede perder su ruta predeterminada en el momento en que activas el reenvío. Ajusta accept_ra = 2 en esa interfaz en el mismo archivo y la ruta sobrevive. El núcleo de la sede B también debe aprender 2001:db8:aa::/48 desde la pasarela del túnel, mediante ruta estática o un protocolo de enrutamiento sobre el túnel, o la respuesta muere dentro de la propia red de B.
Una comprobación en cuatro pasos que localiza la avería
Trabaja en este orden y detente en el primer paso que falle, porque cada paso posterior depende de los anteriores.
- Selectores:
swanctl --list-sasdebería mostrar el par de prefijos IPv6 en la SA hija, owg show wg0 allowed-ipsel prefijo remoto con unlatest-handshakesreciente. - Ruta del kernel:
ip -6 route get 2001:db8:bb::10debe responder con el dispositivo del túnel, no con la interfaz WAN. - Captura interna:
tcpdump -ni wg0 ip6mientras haces ping entre hosts reales de la LAN. Paquetes que salen pero ninguno que vuelve apuntan a la ruta o al cortafuegos de B; ningún paquete apunta de vuelta a los pasos 1 o 2. - Destino: en el host B,
ss -6 -ltnconfirma que el servicio escucha en IPv6, y los contadores locales del cortafuegos muestran si el paquete se aceptó o se descartó.
La MTU entra en la misma pasada. Los routers IPv6 no fragmentan, así que un paquete demasiado grande se descarta y Packet Too Big vuelve al emisor. Si los apretones de manos y los pings pequeños funcionan pero una transferencia de archivos se atasca, reduce la carga útil hasta que pase: ping -6 -s 1400 -c 3 2001:db8:bb::10. Las interfaces WireGuard tienen por defecto una MTU de 1420 bytes e IPsec sobre IPv4 resta más, así que fijar la MTU interna vence a esperar descubrimiento de MTU de ruta a través de un cortafuegos que descarta ICMPv6.
Modos de fallo que parecen problemas de cortafuegos
El más común no es un cortafuegos en absoluto: el servicio se enlaza a 0.0.0.0 en lugar de ::, el registro AAAA existe, y el cliente recibe un rechazo rápido por IPv6 que un navegador de doble pila oculta volviendo a IPv4. Si solo fallan algunas aplicaciones, comprueba la familia de escucha antes de tocar un conjunto de reglas.
El segundo es el filtrado ICMPv6. Neighbor Discovery y Packet Too Big forman parte del funcionamiento normal, no del diagnóstico, y una política que descarta todo ICMPv6 produce un túnel que conecta, se autentica y luego se atasca con cualquier cosa mayor que un paquete pequeño. Permite los tipos de los que depende el camino y deja los contadores activos para que un descarte sea visible.
El tercero es un prefijo añadido al túnel pero nunca al plan de direcciones de la sede que lo posee, de modo que ningún router lo anuncia y ningún host puede responder desde él. Empieza con un prefijo y un par de hosts, demuestra ambas direcciones con los cuatro pasos y luego añade el resto; un prefijo roto se queda como una línea en una configuración en lugar de un rediseño. La única referencia oficial que merece la pena mantener abierta es RFC 8200, que define la cabecera que transporta el túnel.