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íliaTráfego gerenciado
ipSomente IPv4
ip6Somente IPv6
inetTanto IPv4 quanto IPv6 (recomendado para servidores)
arpProtocolo ARP
bridgeNível de bridge/switch
netdevIngresso 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

EstadoSignificado
newPrimeiro pacote de uma nova conexão
establishedTráfego de retorno para uma conexão aceita
relatedAssociado a uma conexão existente
invalidNão pode ser identificado — sempre descartar
untrackedIgnora 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

  1. Faça backup primeirosudo iptables-save > ~/iptables-backup.txt
  2. Traduza e revise — nunca aplique regras auto-traduzidas sem revisão
  3. Teste em não produção — aplique as regras traduzidas em um servidor de teste primeiro
  4. Mantenha uma sessão de console — acesso ao console da nuvem ou KVM como fallback
  5. Limpe o iptables após confirmarsudo iptables -F && sudo iptables -X
  6. Desabilite o serviço legadosudo 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ísticanftablesiptablesUFWfirewalld
Ferramenta única para tudoSimNão (4 ferramentas)Sim (frontend)Sim (frontend)
IPv4 + IPv6 em uma tabelaSim (inet)NãoSimSim
Sets/mapas nativosSimNão (precisa ipset)NãoNão
Substituição atômica de regrasSim (nft -f)NãoNãoParcial
Interface simplificadaNãoNãoSimSim
Flexibilidade de scriptAltaMédiaBaixaMédia
Desempenho em escalaExcelenteBomBomBom

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 accept antes 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 usa define VAR = value em arquivos de configuração; você não pode usar variáveis de shell diretamente em comandos nft.
  • 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 inet para gerenciar IPv4 e IPv6 de uma única tabela
  • Sempre comece com ct state established,related accept e iif 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.conf e carregue atomicamente com nft -f
  • Habilite o serviço systemd do nftables para que o conjunto de regras persista após reinicializações
  • Use iptables-restore-translate para converter conjuntos de regras existentes e revise cuidadosamente antes de aplicar

Artigos Relacionados