Configurando um firewall robusto com nftables no Linux
1. Fundamentos do nftables e substituição do iptables
O nftables representa a evolução do firewall no ecossistema Linux, substituindo o antigo sistema iptables/ip6tables/ebtables/arptables. Diferentemente do iptables, que opera com múltiplos módulos no userspace e uma arquitetura fragmentada no kernel, o nftables unifica o processamento de pacotes em uma única infraestrutura. Sua arquitetura é baseada em um interpretador de bytecode no kernel (nft), combinado com expressões genéricas que eliminam a necessidade de módulos específicos para cada tipo de regra.
Os conceitos fundamentais do nftables são: tabelas (containers lógicos), chains (listas ordenadas de regras) e regras (combinações de expressões e ações). O suporte a múltiplas famílias de endereços — ip (IPv4), ip6 (IPv6), inet (IPv4+IPv6), arp e bridge — permite gerenciar todo o tráfego de rede com uma sintaxe unificada.
Para instalar e verificar a versão:
# Debian/Ubuntu
sudo apt install nftables
# CentOS/RHEL/Fedora
sudo dnf install nftables
# Verificar versão
nft --version
2. Estrutura de tabelas e chains no nftables
A criação de tabelas define o escopo do firewall. Cada tabela pertence a uma família de endereços e contém chains que se conectam a hooks específicos do kernel:
# Criar tabela inet (IPv4+IPv6)
nft add table inet meu_firewall
# Criar chain filter para tráfego de entrada
nft add chain inet meu_firewall input { type filter hook input priority 0 \; policy drop \; }
# Criar chain para encaminhamento
nft add chain inet meu_firewall forward { type filter hook forward priority 0 \; policy drop \; }
# Criar chain para saída
nft add chain inet meu_firewall output { type filter hook output priority 0 \; policy accept \; }
Os tipos de chains disponíveis são: filter (filtragem padrão), nat (tradução de endereços) e route (alteração de roteamento). Os hooks definem em qual ponto do processamento de pacotes a chain será executada: prerouting (antes da decisão de roteamento), input (pacotes destinados ao host local), forward (pacotes roteados), output (pacotes originados localmente) e postrouting (após a decisão de roteamento). A prioridade (0 por padrão) determina a ordem de execução entre chains no mesmo hook.
3. Sintaxe básica de regras e expressões
A sintaxe do nftables é mais legível que o iptables, usando expressões encadeadas com operadores lógicos:
# Regra básica: bloquear SSH de um IP específico
nft add rule inet meu_firewall input ip saddr 192.168.1.100 tcp dport 22 drop
# Aceitar tráfego HTTP/HTTPS
nft add rule inet meu_firewall input tcp dport { 80, 443 } accept
# Bloquear ICMP de um intervalo de IPs
nft add rule inet meu_firewall input ip saddr 10.0.0.0/8 icmp type echo-request drop
# Usar expressões meta para interface
nft add rule inet meu_firewall input meta iifname "eth0" tcp dport 22 accept
Os veredictos disponíveis são: accept (permitir), drop (descartar silenciosamente), reject (descartar com resposta ICMP), jump (saltar para outra chain e retornar), goto (saltar sem retorno) e return (retornar da chain atual).
4. Políticas de segurança: estado e conexão
O rastreamento de conexão é essencial para firewalls stateful. O nftables usa a expressão ct state para classificar pacotes:
# Aceitar conexões já estabelecidas e relacionadas
nft add rule inet meu_firewall input ct state established,related accept
# Aceitar novas conexões SSH
nft add rule inet meu_firewall input ct state new tcp dport 22 accept
# Bloquear pacotes inválidos
nft add rule inet meu_firewall input ct state invalid drop
# Regra completa para forward chain (roteamento)
nft add rule inet meu_firewall forward ct state established,related accept
nft add rule inet meu_firewall forward ct state new tcp dport 80 accept
A política de segurança deve sempre começar com drop nas chains de entrada e encaminhamento, permitindo apenas o tráfego explicitamente autorizado. Isso evita vazamentos de pacotes não solicitados.
5. Criação de conjuntos (sets) e mapas para escalabilidade
Conjuntos permitem agrupar múltiplos endereços ou portas em uma única regra, melhorando performance e legibilidade:
# Conjunto nomeado de IPs bloqueados
nft add set inet meu_firewall ip_bloqueados { type ipv4_addr \; }
# Adicionar IPs ao conjunto
nft add element inet meu_firewall ip_bloqueados { 10.0.0.5, 192.168.1.200 }
# Usar o conjunto em uma regra
nft add rule inet meu_firewall input ip saddr @ip_bloqueados drop
# Conjunto de portas permitidas
nft add set inet meu_firewall portas_permitidas { type inet_service \; }
nft add element inet meu_firewall portas_permitidas { ssh, http, https }
nft add rule inet meu_firewall input tcp dport @portas_permitidas accept
Mapas associam chaves a valores, úteis para NAT dinâmico:
# Mapa para DNAT condicional
nft add map inet meu_firewall nat_map { type ipv4_addr : ipv4_addr \; }
nft add element inet meu_firewall nat_map { 203.0.113.10 : 192.168.1.100 }
nft add rule nat prerouting ip daddr map @nat_map dnat to $map_value
6. Configuração de NAT (masquerade, DNAT, SNAT)
O NAT no nftables usa chains do tipo nat:
# Criar tabela e chain para NAT
nft add table ip nat
nft add chain ip nat prerouting { type nat hook prerouting priority -100 \; }
nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
# Masquerading (para interfaces dinâmicas como PPPoE)
nft add rule ip nat postrouting meta oifname "ppp0" masquerade
# SNAT com IP fixo
nft add rule ip nat postrouting ip saddr 192.168.1.0/24 oif eth0 snat to 203.0.113.1
# DNAT (port forwarding)
nft add rule ip nat prerouting tcp dport 8080 dnat to 192.168.1.100:80
O masquerading é ideal para conexões com IP dinâmico, enquanto SNAT/DNAT são usados em cenários com IPs fixos.
7. Logging, depuração e monitoramento do firewall
Para registrar pacotes sem sobrecarregar o sistema, use limites:
# Log com limite de 3 mensagens por minuto
nft add rule inet meu_firewall input tcp dport 22 limit rate 3/minute log prefix "SSH_ATTEMPT: " drop
# Log de pacotes rejeitados
nft add rule inet meu_firewall input reject with icmp type admin-prohibited log prefix "REJEITADO: "
Comandos de monitoramento:
# Listar todo o ruleset
nft list ruleset
# Monitorar eventos em tempo real
nft monitor
# Adicionar contadores para auditoria
nft add rule inet meu_firewall input tcp dport 443 counter accept
Os contadores mostram o número de pacotes e bytes processados por cada regra, facilitando a análise de tráfego.
8. Boas práticas, persistência e automação
Para tornar as regras persistentes:
# Salvar ruleset atual
nft list ruleset > /etc/nftables.conf
# Restaurar ruleset
nft -f /etc/nftables.conf
# Ativar serviço systemd (Debian/Ubuntu)
sudo systemctl enable nftables
sudo systemctl start nftables
Estratégias de teste seguras:
# Criar chain de staging para testar regras
nft add chain inet meu_firewall staging
# Adicionar regras de teste
nft add rule inet meu_firewall staging tcp dport 22 accept
# Antes de aplicar, fazer backup
cp /etc/nftables.conf /etc/nftables.conf.bak
# Rollback rápido
nft -f /etc/nftables.conf.bak
Sempre teste regras em um ambiente não crítico antes de aplicar em produção. Use chains separadas para diferentes funcionalidades (ex: input_web, input_admin, forward_lan) para facilitar manutenção e depuração.
Referências
- Documentação oficial do nftables (Netfilter) — Guia completo com sintaxe, exemplos e referência de todas as expressões e tipos de dados do nftables.
- How to Use nftables: A Beginner's Guide (Linuxize) — Tutorial prático para iniciantes cobrindo instalação, regras básicas e configuração de NAT.
- nftables vs iptables: What's the Difference? (Red Hat Blog) — Comparação técnica entre as duas soluções de firewall, com ênfase nas vantagens arquiteturais do nftables.
- nftables: The Modern Linux Firewall (DigitalOcean) — Artigo detalhado sobre conceitos, criação de tabelas, chains e regras com exemplos reais de configuração.
- Advanced nftables Usage: Sets, Maps, and Stateful Rules (Arch Linux Wiki) — Documentação avançada cobrindo conjuntos nomeados, mapas para NAT dinâmico e rastreamento de conexão.