Encaminhar IPv6 entre dois sites por uma VPN existente
Uma WAN só com IPv4 ainda pode transportar IPv6 interno. Acompanhe seletores, rotas do kernel, encaminhamento e o prefixo de retorno que descarta respostas em silêncio.
Quando você adiciona um prefixo IPv6 a um túnel site a site, o pacote não viaja como o diagrama sugere. O gateway local pega o pacote IPv6 inteiro, cifra-o e coloca na frente um cabeçalho IP externo cuja família de endereços é decidida pelos endereços das extremidades, não pelo que está dentro. O gateway distante remove esse cabeçalho externo e encaminha o pacote original para sua LAN, onde ele volta a ser um pacote IPv6 comum. Túnel externo e tráfego interno são duas conversas separadas que compartilham uma chave, um par de extremidades e nada mais.
Dois cabeçalhos, duas famílias de endereços
No modo túnel do IPsec, o pacote IPv6 interno vira a carga útil atrás de um cabeçalho ESP. O cabeçalho externo que transporta esse pacote ESP pode ser IPv4 ou IPv6, e segue local_addrs e remote_addrs. O WireGuard faz o mesmo com menos cerimônia: o pacote interno é a carga útil de um datagrama UDP para a extremidade do par. Ambos deixam o cabeçalho interno intacto, e é por isso que o lado remoto consegue encaminhá-lo após a desencapsulação.
O caminho entre os sites só vê UDP 4500 quando o IPsec usa NAT traversal, ou UDP 51820 para um listener WireGuard padrão. Qualquer roteador no caminho pode ser só IPv4 e o tráfego IPv6 atravessa mesmo assim, porque ele nunca aparece como pacote IPv6 nesse caminho. Isso dá uma primeira separação limpa: tcpdump -ni eth0 udp port 51820 mostra o caminho cifrado, tcpdump -ni wg0 ip6 mostra o tráfego interno. Uma captura externa movimentada com uma interna silenciosa significa que o kernel não está colocando IPv6 no túnel; é roteamento ou política, não estado do link.
O gateway também decrementa o limite de saltos interno ao encaminhar, então as extremidades contam como roteadores no caminho IPv6. A contagem de saltos externa e o limite de saltos interno se movem de forma independente, e um pacote que morre no gateway distante morreu no encaminhamento, não na cifra.
Seletores e AllowedIPs são a lista de permissões
O IKEv2 negocia quais prefixos internos uma child SA pode transportar. No strongSwan 5.9 e posterior, escrevê-los em swanctl.conf fica assim:
children {
net6 {
local_ts = 2001:db8:aa::/48
remote_ts = 2001:db8:bb::/48
mode = tunnel
esp_proposals = aes256gcm16-prfsha384-ecp384
start_action = trap
}
}
Omita local_ts e remote_ts e o strongSwan os deriva das sub-redes da interface que ele seleciona. Em um host dual-stack esse atalho costuma produzir um par só IPv4: a SA sobe e o IPv6 é recusado antes de chegar ao código ESP. Escrever os dois prefixos torna a SA elegível para transportá-los, e start_action = trap a levanta no primeiro pacote correspondente.
O WireGuard tem uma única lista cumprindo duas funções. No bloco de par, AllowedIPs = 2001:db8:bb::/48, fd00:bb::/48 é tanto a rota instalada no envio quanto o filtro aplicado na recepção: um pacote decifrado cuja origem interna fica fora dessa lista é descartado em silêncio. wg-quick adiciona uma rota por entrada, então o bloco de par abaixo não precisa de um comando ip -6 route separado.
[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
As duas listas precisam ser espelhadas: o site B aceita o prefixo do site A como seletor remoto e o encaminha de volta, e o túnel só funciona quando as duas direções concordam. Uma lista assimétrica gera o sintoma que mais consome tempo — um aperto de mão saudável, contadores avançando de um lado, e um ping de A para B que funciona enquanto nada de B chega a A.
Encaminhamento, rotas e o prefixo de retorno
O Linux não encaminha IPv6 até você mandar, e o ajuste é por namespace e não por interface:
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 segunda linha é a que as pessoas esquecem em projetos baseados em rotas. O IPsec baseado em políticas instala uma política XFRM que corresponde aos prefixos, mas uma configuração baseada em rotas com vti6 ou WireGuard precisa de uma rota IPv6 real apontando para esse dispositivo. Torne o sysctl persistente em /etc/sysctl.d/; caso contrário, uma reinicialização devolve o encaminhamento ao desligado em silêncio.
O encaminhamento tem um efeito colateral que vale conhecer: o kernel então ignora os anúncios de roteador a menos que net.ipv6.conf.<wan>.accept_ra seja 2, então um gateway cujo endereço WAN chega por SLAAC pode perder sua rota padrão no momento em que você habilita o encaminhamento. Ajuste accept_ra = 2 nessa interface no mesmo arquivo e a rota sobrevive. O núcleo do site B também precisa aprender 2001:db8:aa::/48 a partir do gateway do túnel, por rota estática ou por um protocolo de roteamento sobre o túnel, senão a resposta morre dentro da própria rede de B.
Uma verificação em quatro passos que localiza a quebra
Trabalhe nesta ordem e pare no primeiro passo que falhar, porque cada passo seguinte depende dos anteriores.
- Seletores:
swanctl --list-sasdeve mostrar o par de prefixos IPv6 na child SA, ouwg show wg0 allowed-ipso prefixo remoto com umlatest-handshakesrecente. - Rota do kernel:
ip -6 route get 2001:db8:bb::10deve responder com o dispositivo do túnel, não com a interface WAN. - Captura interna:
tcpdump -ni wg0 ip6enquanto faz ping entre hosts reais da LAN. Pacotes que saem mas nenhum que volta apontam para a rota ou o firewall de B; nenhum pacote aponta de volta para os passos 1 ou 2. - Destino: no host B,
ss -6 -ltnconfirma que o serviço escuta em IPv6, e os contadores locais do firewall mostram se o pacote foi aceito ou descartado.
A MTU entra na mesma passagem. Roteadores IPv6 não fragmentam, então um pacote grande demais é descartado e o Packet Too Big volta ao emissor. Se os apertos de mão e os pings pequenos funcionam mas uma transferência de arquivo trava, reduza a carga útil até ela passar: ping -6 -s 1400 -c 3 2001:db8:bb::10. As interfaces WireGuard têm por padrão uma MTU de 1420 bytes e o IPsec sobre IPv4 subtrai mais, então definir a MTU interna vence esperar pela descoberta de MTU de caminho através de um firewall que descarta ICMPv6.
Modos de falha que parecem problemas de firewall
O mais comum não é firewall nenhum: o serviço se liga a 0.0.0.0 em vez de ::, o registro AAAA existe, e o cliente recebe uma recusa rápida por IPv6 que um navegador dual-stack esconde voltando para IPv4. Se apenas alguns aplicativos falham, verifique a família de escuta antes de tocar em um conjunto de regras.
O segundo é a filtragem de ICMPv6. Neighbor Discovery e Packet Too Big fazem parte da operação normal, não do diagnóstico, e uma política que descarta todo ICMPv6 produz um túnel que conecta, autentica e depois trava em qualquer coisa maior que um pacote pequeno. Permita os tipos dos quais o caminho depende e deixe os contadores ligados para que um descarte fique visível.
O terceiro é um prefixo adicionado ao túnel mas nunca ao plano de endereçamento do site que o possui, de modo que nenhum roteador o anuncia e nenhum host consegue responder a partir dele. Comece com um prefixo e um par de hosts, prove as duas direções com os quatro passos e depois adicione o resto; um prefixo quebrado fica como uma linha em uma configuração em vez de uma reformulação. A única referência oficial que vale manter aberta é RFC 8200, que define o cabeçalho que o túnel transporta.