SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor · Atualizado 2026-08-24

UFW no IPv6: como fechar portas abertas no VPS

UFW no Ubuntu 24.04 já trata IPv6. O risco costuma estar na firewall cloud ou nos serviços expostos; veja como identificar e fechar portas via IPv6.

A armadilha da firewall IPv6 numa frase

A sua firewall protege o IPv4. O seu VPS quase certamente também tem um endereço IPv6 público, e muitos serviços escutam nele por predefinição. Se a sua firewall abranger apenas o IPv4, ou se depender de uma firewall cloud que filtra apenas IPv4, todos esses serviços ficam acessíveis a partir de toda a Internet através de IPv6, enquanto o lado IPv4 parece bloqueado. Testa uma porta com curl, vê uma ligação recusada e sente-se protegido. Um atacante liga-se à mesma porta através de IPv6 e entra.

Este guia mostra de onde vem essa lacuna num VPS Ubuntu 24.04 normal, como ver exatamente o que está exposto e como fechar essa exposição. O UFW não é o problema aqui. Numa instalação moderna do Ubuntu, o UFW já trata o IPv6. A exposição vem das camadas à volta dele e dos serviços que não sabia que estavam a escutar.

Por que o seu VPS usa IPv6 desde o início

Atualmente, quase todos os VPS são disponibilizados com um endereço IPv6 público, muitas vezes um /64 inteiro, além do endereço IPv4. Verifique o seu:

ip -6 addr show scope global
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
    inet6 2001:db8:2a::1/64 scope global

Esse 2001:db8:2a::1 é roteável a partir de qualquer ponto da Internet, exatamente como o seu endereço IPv4. Agora veja o que está escutando:

sudo ss -tlnp
State   Recv-Q  Local Address:Port   Process
LISTEN  0       0.0.0.0:22           sshd
LISTEN  0       [::]:22              sshd
LISTEN  0       127.0.0.1:5432       postgres
LISTEN  0       [::]:8080            docker-proxy

Leia atentamente a coluna Local Address. 0.0.0.0:22 significa “escutar em todos os endereços IPv4”. [::]:22 significa “escutar em todos os endereços IPv6”. 127.0.0.1:5432 está associado ao loopback e não é público, portanto a linha do Postgres é segura. As duas linhas [::] respondem a toda a Internet por IPv6, e a linha docker-proxy é o tipo de serviço que você se esquece de que iniciou.

A maioria dos daemons é associada a :: por padrão, porque, no Linux, um socket :: normalmente também aceita IPv4. Portanto, a configuração padrão de um servidor recém-instalado é “responder nas duas pilhas, em todos os endereços”. O firewall é a única barreira diante disso. Por esse motivo, um firewall que vê apenas uma das pilhas é um problema real.

De onde vem realmente a lacuna do IPv6

Existem quatro fontes comuns. Num determinado servidor, pode ter uma delas ou várias ao mesmo tempo.

1. Uma firewall da cloud que filtra apenas IPv4. Muitas firewalls de fornecedores e produtos de grupos de segurança foram desenvolvidos para IPv4 e ignoram IPv6 ou exigem regras IPv6 separadas, que têm de ser adicionadas manualmente. Se a única firewall que utiliza é a do painel do fornecedor e ela não abrange IPv6, os seus serviços [::] ficam expostos, independentemente do que o painel indique sobre a porta 22 em IPv4. Consulte a documentação da firewall do fornecedor e procure especificamente o termo IPv6.

2. iptables configurado manualmente sem ip6tables. O comando iptables atua apenas nas tabelas IPv4. O IPv6 tem um comando completamente separado, ip6tables, com regras próprias. Se escreveu um script de firewall cheio de linhas iptables -A INPUT ... e nunca criou as regras ip6tables correspondentes, a firewall IPv6 está vazia, e uma cadeia INPUT vazia com uma política predefinida ACCEPT permite tudo:

sudo ip6tables -L INPUT -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Este resultado mostra toda a armadilha num único ecrã. O IPv4 está filtrado, mas o IPv6 aceita ligações de qualquer origem.

3. O Docker publica portas diretamente, contornando a firewall. Quando executa docker run -p 8080:80, o Docker insere as suas próprias regras antes das regras do UFW. Por isso, uma porta publicada fica acessível mesmo quando ufw status indica que essa porta está bloqueada. Nas versões modernas do Docker, o mesmo se aplica através de IPv6. Por que motivo o Docker contorna o UFW e como filtrar corretamente as portas dos contentores explica o mecanismo e as correções. Consulte os conceitos básicos do Docker Compose num VPS para saber como declarar estas portas publicadas.

4. UFW com o IPv6 desativado. O UFW suporta IPv6, mas só quando essa opção está ativada. Verifique a definição:

grep IPV6 /etc/default/ufw

O Ubuntu moderno inclui IPV6=yes, pelo que o UFW aplica cada regra às duas stacks. Se vir IPV6=no, devido a uma imagem antiga ou a um guia antigo, todas as regras UFW que escreveu aplicam-se apenas a IPv4, e o IPv6 fica sem gestão.

Veja exatamente o que está a expor

Não adivinhe. Meça a partir do exterior. Primeiro, liste os sockets em escuta e registe todos os que estão associados a :::

sudo ss -tlnp | grep '::'

Depois, a partir de outra máquina, ligue-se ao endereço IPv6 público do servidor e tente uma porta que considere fechada:

curl -6 -v http://[2001:db8:2a::1]:8080/

Se isso devolver uma página ou um banner, a porta está aberta em IPv6. Uma porta fechada devolve Connection refused ou resulta num timeout. Estas duas falhas não são o mesmo sinal, e a diferença entre ligação recusada e timeout mostra se o host respondeu e rejeitou a ligação ou se uma firewall descartou o pacote silenciosamente. Para obter uma visão completa, faça um scan do endereço IPv6 com nmap a partir de fora do servidor:

nmap -6 2001:db8:2a::1

Todas as portas que o nmap indicar como abertas em IPv6 podem ser alcançadas por toda a Internet, independentemente do resultado do scan IPv4. Compare os scans IPv4 e IPv6 lado a lado. Esta é a forma mais rápida de encontrar a falha: qualquer porta aberta em -6 mas fechada em IPv4 corresponde a um serviço que a sua firewall não está a filtrar.

Elimine a lacuna

Faça o UFW abranger as duas pilhas e defina a política padrão como negar. Confirme a alteração e, em seguida, defina uma política de entrada que negue tudo por padrão e permita apenas o que for necessário:

sudo sed -i 's/^IPV6=no/IPV6=yes/' /etc/default/ufw
sudo ufw default deny incoming
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verbose

Se o UFW já estava ativo quando ativou IPV6=yes, a alteração só entra em vigor depois de executar sudo ufw reload.

ufw status apresenta cada regra duas vezes: uma vez sem sufixo e outra com o sufixo (v6). Quando vir as linhas (v6), o UFW está a filtrar IPv6:

22/tcp                     ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)

Se gerir o iptables manualmente, replique todas as regras no ip6tables ou mude para nftables. As tabelas inet do nftables abrangem IPv4 e IPv6 num único local e eliminam esta classe de erro. Uma única tabela de filtragem inet do nftables é a correção mais simples quando escreve as regras manualmente. Se o seu VPS executar Rocky ou AlmaLinux em vez de Ubuntu, não há UFW para configurar. Nesse caso, o firewalld é o frontend que deve gerir, e aplica as respetivas regras de zona às duas pilhas em simultâneo.

Associe os serviços que não devem ser públicos à interface de loopback. Uma base de dados, um painel de administração ou um endpoint de métricas raramente precisa de um endereço público. Associe-o a 127.0.0.1 e ::1 para que nunca escute num endereço encaminhável. No Postgres, defina listen_addresses = 'localhost'. Num servidor de aplicações, associe-o a 127.0.0.1 e coloque um reverse proxy à frente. Fechar o listener é melhor do que filtrá-lo na firewall, porque deixa de existir algo a que ligar.

Não confie no UFW para proteger as portas publicadas pelo Docker. Publique as portas dos contentores num endereço específico, em vez de todas as interfaces. Por exemplo, use -p 127.0.0.1:8080:80, para que a porta só seja acessível a partir do host e do proxy que configurar explicitamente. Quando um contentor tiver realmente de ser público, coloque-o atrás de um reverse proxy Traefik e publique apenas o proxy, não cada aplicação.

Adicione regras IPv6 à firewall do seu fornecedor ou aceite que ela não protege o IPv6 e deixe o UFW ou o nftables no host assumir essa função.

Verifique se a porta está realmente fechada

Execute novamente o mesmo teste externo depois das alterações:

curl -6 -v http://[2001:db8:2a::1]:8080/
nmap -6 2001:db8:2a::1

A porta que respondeu antes deve agora recusar a ligação ou exceder o tempo limite, e o nmap deve indicá-la como filtrada ou fechada. Se uma porta continuar aberta, reveja as quatro fontes anteriores: um serviço ainda associado a :: sem nenhuma regra à frente, uma regra do Docker colocada antes do UFW ou uma firewall do provedor que nunca recebeu tráfego IPv6.

Manter os serviços sensíveis totalmente fora da Internet pública é uma medida ainda mais forte. Coloque o SSH e os painéis de administração atrás de uma VPN WireGuard e configure a firewall para que as respetivas portas respondam apenas através do túnel; assim, a questão da exposição IPv6 deixa de se aplicar a esses serviços. Para abrandar os scans de força bruta que atingem o que permanece público, coloque o Fail2ban à frente do SSH sobre uma firewall com política de negação por predefinição.

Se as portas ainda forem um conceito novo para si, leia primeiro o que são portas e como os serviços escutam.

FAQ

O UFW bloqueia o IPv6 por predefinição?

Numa instalação moderna do Ubuntu 24.04, sim. O UFW lê IPV6=yes de /etc/default/ufw e aplica cada regra a IPv4 e IPv6, e ufw status mostra as regras IPv6 com um sufixo (v6). O problema surge quando IPV6=no (de uma imagem antiga ou de um tutorial antigo), quando depende de uma firewall do fornecedor que filtra apenas IPv4 ou quando o Docker publica uma porta contornando o UFW. Verifique esta opção com grep IPV6 /etc/default/ufw.

Como verifico o que o meu VPS está a expor em IPv6?

Execute sudo ss -tlnp e observe todos os listeners cujo endereço local começa por [::], o que significa que respondem em todas as interfaces IPv6. Depois, a partir de outra máquina, teste diretamente o endereço IPv6 público do servidor com curl -6 -v http://[YOUR:IPV6::ADDR]:PORT/ ou faça uma verificação com nmap -6 YOUR:IPV6::ADDR. Qualquer porta aberta na verificação IPv6, mas fechada em IPv4, é uma lacuna.

Porque consigo aceder à porta do meu contentor Docker quando o UFW indica que está bloqueada?

Quando publica uma porta com -p, o Docker insere as próprias regras de firewall antes das regras do UFW. Por isso, a porta publicada fica acessível, embora ufw status a liste como negada. Isto acontece em IPv4 e também em IPv6 quando o suporte IPv6 do Docker está ativo. Publique a porta num endereço específico, como -p 127.0.0.1:8080:80, ou coloque o contentor atrás de um reverse proxy e publique apenas o proxy.

Ainda preciso de uma firewall IPv6 se a minha firewall IPv4 for sólida?

Sim. IPv4 e IPv6 são pilhas de rede separadas, com regras de firewall separadas. Um conjunto perfeito de regras IPv4 não afeta o tráfego IPv6. Se o seu VPS tiver um endereço IPv6 público, como acontece com quase todos, qualquer serviço que escute em :: continuará acessível por IPv6 até que uma regra de firewall IPv6 ou uma ligação a loopback o impeça.

Como faço um serviço escutar apenas em IPv4 ou apenas em localhost?

Defina o endereço de binding do serviço na respetiva configuração. Use 127.0.0.1 para aceitar ligações apenas no loopback IPv4 ou 0.0.0.0 para aceitar ligações em todos os endereços IPv4 sem listener IPv6. O Postgres usa listen_addresses, o SSH usa ListenAddress e a maioria dos servidores de aplicações disponibiliza uma opção de host ou de binding. Confirme o resultado com sudo ss -tlnp e verifique se Local Address já não mostra [::].