Notícias7 min de leitura
IPv6 na prática: como testar, ativar dual-stack e parar de pagar por IPv4
IPv4 virou item de fatura na nuvem e CGNAT esconde o custo no acesso. Um roteiro com comandos para testar IPv6, configurar servidor e firewall, e corrigir os bugs de aplicação que aparecem.
- ipv6
- ipv4
- cgnat
- redes
- cloud
- linux
- brasil
O IPv6 foi especificado nos anos 1990 e revisado no RFC 8200 em 2017. Por muito tempo, a desculpa para não usar foi "ninguém usa". Essa desculpa acabou: as estatísticas do Google mostram algo perto de metade dos acessos chegando por IPv6, e o Brasil aparece de forma consistente entre os países com maior adoção, puxado pelas operadoras móveis e pelos provedores regionais.
Enquanto isso, o IPv4 ganhou preço. Os registros regionais esgotaram os estoques, e desde fevereiro de 2024 a AWS cobra por hora cada IPv4 público, inclusive os que estão em uso. São cerca de US$ 3,65 por endereço por mês. Parece pouco até alguém somar load balancers, NAT gateways e instâncias com IP público numa conta grande.
Este texto é o roteiro que eu seguiria para colocar um serviço em IPv6 sem surpresa: testar, ativar, filtrar direito e corrigir os bugs de aplicação que só aparecem quando o endereço tem dois-pontos.
Primeiro, descubra se você já tem IPv6
Na sua máquina:
ip -6 addr show scope global
ip -6 route show default
curl -6 -s https://ifconfig.co
Se o primeiro comando mostra um endereço começando com 2 ou 3 (espaço global unicast 2000::/3), e o curl -6 responde, você tem IPv6 de ponta a ponta. Endereços fe80:: são link-local e não contam. Endereços fd.. são locais únicos (ULA), equivalentes a uma rede privada.
Para o seu domínio:
dig +short A exemplo.com.br
dig +short AAAA exemplo.com.br
curl -6 -sI https://exemplo.com.br | head -1
Sem registro AAAA, nenhum cliente vai tentar IPv6, mesmo que o servidor esteja pronto.
Como o cliente escolhe entre IPv4 e IPv6
Clientes modernos usam Happy Eyeballs (RFC 8305): resolvem A e AAAA, tentam IPv6 primeiro e, se ele demora algumas centenas de milissegundos, abrem IPv4 em paralelo. Quem conectar primeiro vence.
Isso tem um efeito colateral importante: IPv6 quebrado não aparece como erro. Aparece como lentidão leve, porque o cliente cai no IPv4 em silêncio. Já vi AAAA apontando para um endereço sem firewall liberado passar meses despercebido. Por isso o teste precisa forçar o protocolo (curl -6, curl -4) em vez de confiar no navegador.
Servidor: o mínimo para dual-stack
Nginx
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name exemplo.com.br;
# ...
}
O listen [::]:443 é o que faltava na maioria das configurações antigas. Depois, confira quem está escutando:
ss -ltnp | grep ':443'
Docker
O Docker não habilita IPv6 nas redes por padrão. Em /etc/docker/daemon.json:
{
"ipv6": true,
"fixed-cidr-v6": "fd00:cafe::/64"
}
Com um prefixo ULA, os containers saem para a internet via NAT66 feito pelo Docker, espelhando o que já acontece no IPv4. Se o provedor delegou um prefixo roteável para o host, dá para usar esse prefixo e dispensar o NAT, mas aí o firewall precisa proteger cada container diretamente.
Nuvem
Na AWS, os blocos para sair do IPv4 são: sub-redes dual-stack ou IPv6-only, egress-only internet gateway para saída IPv6 sem permitir entrada, e NAT64 no NAT Gateway junto com DNS64 no Route 53 Resolver, para que instâncias só IPv6 alcancem destinos que ainda são só IPv4. Load balancers em modo dual-stack aceitam clientes nos dois protocolos e falam IPv4 com o alvo, o que permite migrar a borda antes do resto.
Firewall: não bloqueie ICMPv6
Esse é o erro mais comum e mais caro. No IPv4, muita gente bloqueia ICMP inteiro e quase nada quebra. No IPv6, isso quebra a rede:
- Neighbor Discovery (tipos 133 a 137) substitui o ARP. Sem ele, o host não acha nem o roteador.
- Packet Too Big (tipo 2) é como o IPv6 descobre o MTU do caminho. Roteadores IPv6 não fragmentam pacotes; eles descartam e avisam. Bloquear esse aviso gera conexões que abrem, trocam alguns bytes e travam quando o primeiro pacote grande passa.
O RFC 4890 lista o que filtrar e o que deixar passar. Em nftables, o mínimo razoável fica assim:
table inet filtro {
chain entrada {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
icmpv6 type { destination-unreachable, packet-too-big, time-exceeded,
parameter-problem, echo-request, nd-router-advert,
nd-neighbor-solicit, nd-neighbor-advert } accept
tcp dport { 22, 80, 443 } accept
}
}
A família inet aplica a mesma regra a IPv4 e IPv6. Evita o clássico "liberei a porta no iptables e esqueci o ip6tables".
Os bugs que aparecem na aplicação
A rede costuma ser a parte fácil. O que quebra é código que assumiu que endereço IP tem quatro números e três pontos.
Coluna pequena demais. VARCHAR(15) corta um IPv6, que pode ter até 39 caracteres na forma textual (e mais com zona ou IPv4 embutido). No PostgreSQL, use o tipo inet: valida, compara, e aceita consultas de rede como ip << '2001:db8::/32'.
Separar host e porta pelo :. split(":") em 2001:db8::1:8080 não funciona. Em URL, o IPv6 vai entre colchetes: https://[2001:db8::1]:8080/. Use a função de parsing da linguagem, não split manual.
Rate limit e bloqueio por IP. No IPv4, um IP costuma ser uma casa ou um CGNAT inteiro. No IPv6, um único cliente recebe um prefixo /64 inteiro, 18 quintilhões de endereços, e pode trocar de endereço à vontade (as extensões de privacidade do RFC 8981 fazem isso sozinhas). Rate limit por endereço individual é inútil. Agrupe por /64, e considere /56 ou /48 para bloqueios mais agressivos.
Listas de permissão. Allowlist de IP de parceiro, painel administrativo liberado para "o IP do escritório": se o escritório ganhou IPv6 e o cliente preferiu IPv6, o acesso cai. Toda allowlist precisa das duas famílias.
Logs e geolocalização. Parsers de log com regex de IPv4, bases de GeoIP antigas e dashboards que agrupam por "IP" tratam cada endereço IPv6 temporário como um visitante diferente.
CGNAT: o custo que o usuário não vê
Do lado do acesso, o provedor sem IPv4 para todos coloca clientes atrás de CGNAT, no bloco 100.64.0.0/10 reservado pelo RFC 6598. Se o seu roteador recebe um IP nessa faixa, você está atrás de CGNAT. Funciona para navegar, mas:
- impede conexões de entrada: câmera, servidor caseiro, alguns jogos, acesso remoto;
- concentra muitos clientes num mesmo IPv4 público, então um bloqueio por reputação atinge todos;
- obriga o provedor a guardar porta e horário de cada sessão para identificar um usuário, como o RFC 6888 já antecipava.
Com IPv6, cada cliente volta a ter endereço global próprio. É o motivo prático pelo qual serviços de acesso remoto e jogos vêm adotando IPv6: é o único caminho direto até o usuário atrás de CGNAT.
No celular, o 464XLAT (RFC 6877) permite que a rede interna da operadora seja só IPv6 e ainda entregue IPv4 aos apps que precisam, traduzindo nas pontas. Muitas redes móveis brasileiras já funcionam assim, e você nem percebe.
Checklist
- Registro
AAAApublicado para cada nome que temA. -
curl -6ecurl -4testados separadamente, de fora da sua rede. - Servidor escutando em
[::]nas mesmas portas que em0.0.0.0. - Firewall em família
inet(ou regras IPv6 equivalentes) com ICMPv6 essencial liberado. - Colunas de IP como
inetou texto com 45+ caracteres; parsing de host/porta com colchetes. - Rate limit e bloqueios agregados por prefixo
/64. - Allowlists, logs e alertas revisados para as duas famílias.
- Na nuvem: inventário de IPv4 públicos e plano para trocar o que for só saída por IPv6 + NAT64.
Em resumo
IPv6 deixou de ser projeto de futuro: é o caminho padrão de boa parte do tráfego móvel e residencial, inclusive no Brasil. O IPv4 continua existindo, mas agora tem preço explícito na fatura e custo operacional no CGNAT. A migração em si é curta. O que dá trabalho é o código e o firewall que assumiram, sem dizer, que só existia IPv4.
Para quem quiser o contexto de como chegamos aqui, a história da internet cobre de onde vieram o endereçamento de 32 bits e o NAT que o IPv6 tenta aposentar.
Fontes
- Google IPv6 Statistics
- RFC 8200 — IPv6 Specification
- RFC 8305 — Happy Eyeballs v2
- RFC 4890 — Recomendações de filtragem de ICMPv6
- RFC 8981 — Endereços temporários (privacy extensions)
- RFC 6598 — Shared Address Space (100.64.0.0/10)
- RFC 6888 — Requisitos para CGN
- RFC 6877 — 464XLAT
- AWS — cobrança de IPv4 público
- Docker — IPv6 networking
- IPv6.br (NIC.br)