O tráfego IPv6 deve passar pela VPN ou direto?
Decida se ::/0 pertence dentro do túnel, com três condições: suporte da saída, alcance do extremo e redes apenas locais.
No mês passado, duas pessoas pediram-me resultados opostos: uma queria que a VPN cobrisse IPv6, a outra queria que a impressora do escritório continuasse a funcionar. Uma única rota ::/0 não consegue entregar as duas por si só. Se essa rota pertence dentro do túnel depende de três condições, e a primeira exclui-a para a maioria das saídas comerciais. Se a saída não transporta IPv6, encaminhar a rota predefinida para lá esconde o seu tráfego num túnel que não tem para onde o enviar.
Três condições decidem a resposta
A rota predefinida é uma linha, ::/0, e corresponde a qualquer destino IPv6 sem uma rota mais específica (RFC 4291). Instalá-la é fácil. Decidir se deve fazê-lo resume-se a três condições.
Condição um: a saída a que se liga tem IPv6 a funcionar e está disposta a reencaminhá-lo. Condição dois: o seu cliente consegue manter um caminho até ao extremo do túnel, que normalmente fica dentro do intervalo que vai encaminhar. Condição três: consegue nomear os destinos IPv6 locais que devem ficar fora do túnel.
Cada condição falha à sua maneira, e por isso adivinhar custa uma noite inteira. Uma condição um falhada dá-lhe silêncio e uma tabela de rotas que parece correta. Uma condição dois falhada mata o handshake poucos segundos depois de começar. Uma condição três falhada deixa um túnel a funcionar e um colega insatisfeito na impressora.
| What you see | Decision |
|---|---|
| Exit answers IPv6 probes, no local IPv6 devices to protect | Route ::/0 into the tunnel |
| Exit answers IPv6 probes, printer or NAS reachable by a global address | Route ::/0, then give those prefixes a route of their own |
| Exit is IPv4-only inside the tunnel | Do not route ::/0; block IPv6 on the client |
Endpoint is reached over IPv6 and sits inside ::/0 | Install a host route for the endpoint first |
A saída transporta mesmo IPv6?
Uma interface de túnel com um endereço IPv6 não prova nada sobre o outro lado. Muitos perfis comerciais são apenas IPv4 por dentro: o servidor dá-lhe um endereço v4 e descarta tudo o resto. Instale por cima uma rota predefinida a partir de AllowedIPs e o kernel enviará de bom grado IPv6 para uma interface cujo par nunca o vê.
Teste a partir do cliente enquanto o túnel está ativo. ping -6 -c 3 2001:4860:4860::8888 e ip -6 route get 2001:4860:4860::8888 respondem a perguntas diferentes: se volta uma resposta e que dispositivo o kernel escolheu. Quando o segundo nomeia o seu túnel e o primeiro não devolve nada, o problema está na saída, não na rota.
Se gere a saída sozinho, o teste do cliente pode passar e o caminho terminar na mesma num beco sem saída. Confirme net.ipv6.conf.all.forwarding=1 no gateway e que a firewall aceita pacotes reencaminhados para fora do túnel. Um pacote corretamente encaminhado para uma saída que recusa retransmitir parece exatamente um erro de encaminhamento do lado do cliente.
O cliente consegue manter o caminho até ao extremo?
Este é o caso que me apanhou num portátil com um extremo WireGuard apenas IPv6. O endereço do extremo é um endereço global comum, por isso cai dentro de ::/0. Encaminhe todo o prefixo para a interface e os pacotes do handshake perseguem-se a si próprios para dentro do túnel que ainda tentam construir. O túnel nunca sobe, e nada na saída do cliente diz porquê.
wg-quick trata disto no Linux. Deriva rotas de AllowedIPs, instala-as na sua própria tabela e acrescenta uma regra de política para que o tráfego para o extremo seja resolvido primeiro pela tabela principal: a regra suppress_prefixlength 0 que encontra em ip -6 rule. Por isso wg-quick up tem sucesso onde uma ip -6 route add default dev wg0 escrita à mão o corta.
Verifique os dois estados com ip -6 route get <endpoint-v6>, antes e depois de levantar o túnel. Se a resposta mudar para o seu dispositivo de túnel, removeu o caminho de que o túnel precisa. Quando escreve as rotas sozinho, acrescente uma rota de host até ao extremo pelo gateway original, ou ligue-se ao extremo por IPv4 e deixe IPv6 para a carga útil.
O que deve ficar fora do túnel?
Rotas mais específicas vencem a predefinida, por isso um prefixo on-link ou um intervalo ULA com rota própria continua a funcionar sem esforço extra. Esta é a razão silenciosa pela qual tantas configurações IPv4 de túnel completo sobrevivem: os prefixos da LAN são mais específicos do que a predefinida e nunca entram no túnel.
Quebra quando um dispositivo local é alcançável por um endereço global, o que é normal numa impressora a que o mesmo router deu um prefixo público, num NAS ou numa televisão. Esses endereços correspondem a ::/0 e a mais nada, por isso mudam-se para o túnel com tudo o resto e desaparecem.
Decida por destino, não por protocolo. Se dois ou três hosts locais importam, dê aos seus prefixos uma rota para fora pela interface física, ou retire-os do conjunto negociado. Se a lista continuar a crescer, a resposta honesta é split tunneling para IPv6 com uma lista de exceções escrita, não uma rota predefinida que continua a remendar.
Se a resposta for não, bloqueie-o
Deixar IPv6 sem rota não é o mesmo que deixá-lo em paz. Um host com uma rota predefinida IPv6 a funcionar continua a usá-la enquanto o túnel transporta IPv4, por isso o tráfego sai ao lado da VPN e cada serviço que prefere IPv6 vê o seu endereço real. Isso é uma fuga, não um túnel dividido.
Escolha um e anote qual escolheu. Encaminhe a predefinida e aceite os compromissos acima, ou desative IPv6 enquanto o túnel durar. Omitir o prefixo de AllowedIPs não basta por si só, porque o sistema operativo mantém a sua própria predefinida. No Linux a versão bruta é sysctl -w net.ipv6.conf.all.disable_ipv6=1; a versão mais fina deixa cair IPv6 fora do túnel com uma regra de firewall. Os clientes de telemóvel têm um interruptor explícito de bloquear IPv6 que faz o mesmo trabalho.
Verifique-o como uma fuga
Levante o túnel e leia o estado em vez de confiar no interruptor. ip -6 route show default deve mostrar uma única predefinida, e ip -6 route get para um destino fora da sua LAN deve nomear o dispositivo de túnel. Repita ambos após uma desconexão: uma predefinida que sobrevive ao túnel é o erro que procurava.
Depois teste a outra direção. A partir de um host na rede local, chegue ao cliente no seu endereço IPv6 local. Se isso deixar de funcionar, a condição três nunca foi cumprida, diga o que disser a tabela de rotas na altura.
Escreva o resultado onde a próxima pessoa o encontrar: que prefixos ficam locais, porquê e o que o cliente faz após uma desconexão. Duas linhas num runbook poupam ao próximo engenheiro redescobrir o ciclo do extremo à meia-noite.