TL;DR — Resumo Rápido
nftables substitui iptables no Linux com sintaxe limpa e regras atômicas. Guia de migração com sets, NAT, limitação de taxa e firewall para web.
O nftables é o moderno framework de classificação de pacotes do kernel Linux e o substituto oficial da cadeia de ferramentas legada iptables, ip6tables, arptables e ebtables. Disponível desde o kernel 3.13 e agora o backend padrão no Debian 10+, Ubuntu 20.10+, RHEL 8+ e Fedora 18+, o nftables oferece uma interface de comandos unificada, correspondência nativa baseada em sets e carregamento atômico de conjuntos de regras que elimina as lacunas de segurança inerentes às atualizações regra por regra do iptables. Este guia cobre o caminho completo de migração — desde a instalação do nftables e a compreensão de sua hierarquia de objetos até a construção de um firewall de servidor web pronto para produção com sets, limitação de taxa, NAT e integração persistente com systemd.
Pré-requisitos
Antes de começar, certifique-se de ter:
- Um servidor Linux rodando kernel 3.13 ou posterior (Ubuntu 20.04+, Debian 10+ ou RHEL 8+ recomendados)
- Acesso ao terminal com privilégios
sudo - Acesso SSH ao servidor se configurar remotamente — mantenha uma segunda sessão aberta como rede de segurança
- Familiaridade com portas TCP/UDP e redes IP básicas
- Regras do iptables exportadas se planejar migrá-las (
sudo iptables-save > ~/iptables-backup.txt)
Por Que o nftables Substitui o iptables
A cadeia de ferramentas legada do Netfilter evoluiu organicamente por duas décadas, resultando em quatro utilitários separados (iptables, ip6tables, arptables, ebtables) cada um com sua própria sintaxe, interface de kernel e mecanismo de extensão. O nftables foi projetado desde o início para resolver esses problemas estruturais.
Framework Unificado
Um único comando nft substitui todas as quatro ferramentas legadas. Uma única tabela de família inet lida com IPv4 e IPv6 simultaneamente, eliminando a necessidade de duplicar cada regra para ambas as famílias de endereços.
Sintaxe Melhorada
O nftables usa uma gramática estruturada que se lê de forma mais natural do que as flags do iptables:
# iptables
iptables -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT
# Equivalente em nftables
nft add rule inet filter input tcp dport 443 ct state new accept
Carregamento Atômico de Regras
Com o iptables, adicionar e remover regras acontece uma de cada vez — existe uma condição de corrida entre cada operação individual. O nftables carrega um conjunto de regras inteiro como uma única transação atômica usando nft -f, garantindo que o firewall nunca esteja em um estado parcial.
Sets e Mapas Nativos
O iptables requer a extensão separada ipset para corresponder eficientemente a grandes listas de IPs ou portas. O nftables inclui sets e mapas nativamente, suportando timeouts, chaves concatenadas e mapas de veredicto sem pacotes adicionais.
Fundamentos do Comando nft
O nftables organiza tudo em uma hierarquia de três níveis: as tabelas contêm cadeias, as cadeias contêm regras. Cada tabela pertence a uma família de endereços.
Famílias de Endereços
| Família | Tráfego gerenciado |
|---|---|
ip | Somente IPv4 |
ip6 | Somente IPv6 |
inet | Tanto IPv4 quanto IPv6 (recomendado para servidores) |
arp | Protocolo ARP |
bridge | Nível de bridge/switch |
netdev | Ingresso em uma interface específica |
Gerenciamento de Tabelas
sudo nft add table inet filter # criar uma tabela
sudo nft list tables # listar todas as tabelas
sudo nft delete table inet filter # excluir tabela e conteúdo
sudo nft flush table inet filter # remover todas as regras, manter estrutura
Gerenciamento de Cadeias
Cadeias base são vinculadas a um gancho do Netfilter. Requerem um type, hook e priority:
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
sudo nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
sudo nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }
Gerenciamento de Regras
sudo nft add rule inet filter input tcp dport 22 accept # adicionar ao final
sudo nft insert rule inet filter input tcp dport 22 accept # inserir no início
sudo nft list chain inet filter input # ver com identificadores
sudo nft delete rule inet filter input handle 5 # excluir por identificador
Construindo um Firewall Básico
A sequência a seguir constrói um firewall de referência completo passo a passo.
Passo 1 — Criar a Tabela e as Cadeias
sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
sudo nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
sudo nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }
Passo 2 — Aceitar Conexões Estabelecidas e Loopback
Estas regras devem vir primeiro para que as sessões existentes não sejam interrompidas:
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input ct state invalid drop
sudo nft add rule inet filter input iif lo accept
Passo 3 — Permitir ICMP
sudo nft add rule inet filter input ip protocol icmp limit rate 10/second burst 20 packets accept
sudo nft add rule inet filter input ip6 nexthdr icmpv6 limit rate 10/second burst 20 packets accept
Passo 4 — Permitir Portas de Serviços
sudo nft add rule inet filter input tcp dport 22 accept
sudo nft add rule inet filter input tcp dport { 80, 443 } accept
Passo 5 — Rejeição Final
Envie um erro ICMP para tráfego não correspondido em vez de descartá-lo silenciosamente:
sudo nft add rule inet filter input reject with icmpx type port-unreachable
Sets e Mapas para Gerenciamento Eficiente de Regras
Os sets eliminam a necessidade de escrever uma regra por porta ou endereço IP. Podem ser atualizados dinamicamente sem modificar as regras que os referenciam.
Sets Anônimos (Em Linha)
sudo nft add rule inet filter input tcp dport { 22, 80, 443, 8443 } accept
Sets Nomeados
sudo nft add set inet filter tcp_accepted { type inet_service \; }
sudo nft add element inet filter tcp_accepted { 22, 80, 443 }
sudo nft add rule inet filter input tcp dport @tcp_accepted accept
# Adicionar ou remover portas sem tocar na regra
sudo nft add element inet filter tcp_accepted { 8080 }
sudo nft delete element inet filter tcp_accepted { 8080 }
Lista de Bloqueio de IPs com Expiração Automática
sudo nft add set inet filter blocklist { type ipv4_addr \; timeout 24h \; }
sudo nft add element inet filter blocklist { 203.0.113.10, 198.51.100.5 }
sudo nft add rule inet filter input ip saddr @blocklist drop
Sets Concatenados (Correspondência Multi-campo)
sudo nft add set inet filter db_access { type ipv4_addr . inet_service \; }
sudo nft add element inet filter db_access { 10.0.1.20 . 3306, 10.0.1.21 . 5432 }
sudo nft add rule inet filter input ip saddr . tcp dport @db_access accept
Limitação de Taxa e Rastreamento de Conexões
Limitação Global de SSH
sudo nft add rule inet filter input tcp dport 22 ct state new limit rate 5/minute burst 10 packets accept
sudo nft add rule inet filter input tcp dport 22 ct state new drop
Limitação de Taxa por IP de Origem com Medidores
sudo nft add rule inet filter input tcp dport 22 ct state new \
meter ssh_limit { ip saddr limit rate 3/minute burst 5 packets } accept
Estados de Rastreamento de Conexão
| Estado | Significado |
|---|---|
new | Primeiro pacote de uma nova conexão |
established | Tráfego de retorno para uma conexão aceita |
related | Associado a uma conexão existente |
invalid | Não pode ser identificado — sempre descartar |
untracked | Ignora explicitamente o conntrack |
NAT e Encaminhamento de Portas
Criar a Tabela NAT
sudo nft add table inet nat
sudo nft add chain inet nat prerouting { type nat hook prerouting priority -100 \; }
sudo nft add chain inet nat postrouting { type nat hook postrouting priority 100 \; }
Masquerade (NAT de Origem para Roteadores/VPNs)
sudo nft add rule inet nat postrouting oif "eth0" masquerade
Encaminhamento de Portas (NAT de Destino)
sudo nft add rule inet nat prerouting iif "eth0" tcp dport 8080 dnat to 10.0.0.50:80
sudo nft add rule inet filter forward ip daddr 10.0.0.50 tcp dport 80 ct state new accept
sudo nft add rule inet filter forward ct state established,related accept
Habilitar encaminhamento IP:
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-nftables.conf
sudo sysctl -p /etc/sysctl.d/99-nftables.conf
Registro e Monitoramento
sudo nft add rule inet filter input ct state invalid log prefix "nft_invalid: " level warn drop
sudo journalctl -k --grep="nft_" -f
sudo nft monitor
Salvando e Restaurando Conjuntos de Regras
sudo nft list ruleset | sudo tee /etc/nftables.conf
sudo nft -c -f /etc/nftables.conf # teste seco de sintaxe
sudo nft -f /etc/nftables.conf # aplicar atomicamente
Migrando do iptables
Traduzir Regras Individuais
iptables-translate -A INPUT -p tcp --dport 443 -j ACCEPT
# Saída: nft add rule ip filter INPUT tcp dport 443 counter accept
Traduzir um Conjunto de Regras Completo
sudo iptables-save > /tmp/ipt-backup.txt
iptables-restore-translate -f /tmp/ipt-backup.txt > /tmp/nft-migrated.nft
sudo nft -f /tmp/nft-migrated.nft
Melhores Práticas de Migração
- Faça backup primeiro —
sudo iptables-save > ~/iptables-backup.txt - Traduza e revise — nunca aplique regras auto-traduzidas sem revisão
- Teste em não produção — aplique as regras traduzidas em um servidor de teste primeiro
- Mantenha uma sessão de console — acesso ao console da nuvem ou KVM como fallback
- Limpe o iptables após confirmar —
sudo iptables -F && sudo iptables -X - Desabilite o serviço legado —
sudo systemctl disable iptables
Integração com systemd
sudo systemctl enable nftables
sudo systemctl start nftables
sudo systemctl reload nftables # recarga atômica do conjunto de regras
Comparação: nftables vs iptables vs UFW vs firewalld
| Característica | nftables | iptables | UFW | firewalld |
|---|---|---|---|---|
| Ferramenta única para tudo | Sim | Não (4 ferramentas) | Sim (frontend) | Sim (frontend) |
| IPv4 + IPv6 em uma tabela | Sim (inet) | Não | Sim | Sim |
| Sets/mapas nativos | Sim | Não (precisa ipset) | Não | Não |
| Substituição atômica de regras | Sim (nft -f) | Não | Não | Parcial |
| Interface simplificada | Não | Não | Sim | Sim |
| Flexibilidade de script | Alta | Média | Baixa | Média |
| Desempenho em escala | Excelente | Bom | Bom | Bom |
Cenário Real: Servidor Web e Proxy Reverso
Você tem um servidor de produção rodando Nginx como proxy reverso à frente de dois servidores de aplicação em 10.0.0.10 e 10.0.0.11, com uma interface pública (eth0) e uma interna (eth1). Requisitos: acesso SSH somente do seu CIDR de gerenciamento, HTTP/HTTPS público, tráfego de backend somente da rede interna e proteção contra força bruta SSH.
#!/usr/sbin/nft -f
flush ruleset
define WAN = eth0
define LAN = eth1
define MGMT_CIDR = 10.10.10.0/24
table inet filter {
set mgmt_hosts {
type ipv4_addr
flags interval
elements = { $MGMT_CIDR }
}
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
ct state invalid drop
iif lo accept
ip protocol icmp limit rate 10/second burst 20 packets accept
ip saddr @mgmt_hosts tcp dport 22 ct state new \
meter ssh_mgmt { ip saddr limit rate 5/minute burst 10 packets } accept
tcp dport { 80, 443 } accept
reject with icmpx type port-unreachable
}
chain forward {
type filter hook forward priority 0; policy drop;
ct state established,related accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Armadilhas e Casos Especiais
- A ordem das regras importa — o nftables avalia as regras de cima para baixo. Coloque
ct state established,related acceptantes de qualquer regra de descarte. - Sem tabelas ou cadeias padrão — o nftables começa vazio. Se você esquecer de criar uma cadeia, o tráfego não é filtrado de forma alguma.
- flush ruleset é destrutivo — sempre inclua-o no início dos arquivos de configuração, mas nunca o execute interativamente em um servidor em produção sem um plano de backup.
- Variáveis requerem
define— o nftables usadefine VAR = valueem arquivos de configuração; você não pode usar variáveis de shell diretamente em comandosnft. - iptables e nftables podem conflitar — se ambos estiverem rodando, as regras de ambos os frameworks se aplicam de forma independente.
Solução de Problemas
Regras não persistem após reinicialização: Verifique se o serviço está habilitado com sudo systemctl is-enabled nftables. Verifique se /etc/nftables.conf contém flush ruleset no início e tem sintaxe nft válida.
SSH bloqueado após aplicar regras: Acesse via console da nuvem, depois execute sudo nft flush ruleset. Reconstrua a configuração com SSH permitido antes de definir uma política de descarte.
Módulo de kernel ausente: Execute lsmod | grep nf_tables. Se ausente, carregue com sudo modprobe nf_tables nft_chain_nat nft_ct.
Erro de sintaxe no arquivo de configuração: Use sudo nft -c -f /etc/nftables.conf para um teste seco que relata a linha e o erro exatos sem aplicar alterações.
Resumo
O nftables é o substituto pronto para produção do iptables em qualquer sistema Linux com kernel 3.13 ou posterior. Seu comando nft unificado, sets e mapas nativos, carregamento atômico de regras e sintaxe mais limpa abordam cada fraqueza estrutural principal da cadeia de ferramentas legada.
Pontos principais:
- Use a família de endereços
inetpara gerenciar IPv4 e IPv6 de uma única tabela - Sempre comece com
ct state established,related accepteiif lo accept - Use sets nomeados para gerenciar listas de portas e IPs sem reescrever regras
- Proteja serviços de autenticação com medidores por IP em vez de limites de taxa globais
- Armazene o conjunto de regras em
/etc/nftables.confe carregue atomicamente comnft -f - Habilite o serviço systemd do nftables para que o conjunto de regras persista após reinicializações
- Use
iptables-restore-translatepara converter conjuntos de regras existentes e revise cuidadosamente antes de aplicar