Ubuntu nftables
O nftables é o firewall que vive dentro do kernel Linux. Ele decide, pacote por pacote, o que entra, o que sai e o que passa pela máquina. O ufw, que você viu em Firewall (ufw), é uma camada simples por cima dele. Nesta aula você vai falar direto com o nftables usando o comando nft.
- Como ufw, iptables e nftables se relacionam no Ubuntu 26.04.
- O que são tabelas, cadeias (chains) e regras, e como ler um
nft list ruleset. - Como escrever um
/etc/nftables.confque libera SSH, HTTP e HTTPS e bloqueia o resto. - Como testar regras num servidor remoto sem ficar trancado do lado de fora.
Os exemplos acontecem na máquina fictícia servidor, com a usuária ana. Todos os comandos do nft exigem sudo.
Antes do comando: quem é quem
No Linux existem várias ferramentas de firewall, e isso confunde. Na verdade há um só motor no kernel, chamado netfilter. As ferramentas são formas diferentes de dar ordens a ele:
| Ferramenta | O que é | No Ubuntu 26.04 |
|---|---|---|
nft (nftables) | A interface moderna do netfilter | Instalado. O serviço nftables vem desativado. |
iptables | A interface antiga | É um "tradutor": grava as regras no nftables (iptables v1.8.11 (nf_tables)). |
ufw | Firewall simplificado (Uncomplicated Firewall) | Usa o iptables, que por sua vez escreve no nftables. |
Você confere isso na sua máquina:
$ iptables --version iptables v1.8.11 (nf_tables) « o iptables grava no nftables $ readlink -f /usr/sbin/iptables /usr/sbin/xtables-nft-multi $ systemctl is-active ufw nftables active « ufw ligado inactive « serviço nftables desligado
Não use o ufw e um /etc/nftables.conf próprio ao mesmo tempo. Os dois criam regras no mesmo motor, e um pode bloquear o que o outro liberou. Para seguir com o nftables puro, desative o ufw antes: sudo ufw disable.
Tabelas, cadeias e regras
O nftables organiza tudo em três níveis, como pastas dentro de pastas:
- Tabela (table): uma caixa com nome e família. A família diz que tipo de tráfego ela vê:
ip(IPv4),ip6(IPv6) ouinet(os dois). Useinetquase sempre. - Cadeia (chain): uma lista de regras ligada a um ponto do caminho do pacote, o hook.
input= pacotes chegando para esta máquina;output= saindo dela;forward= passando por ela rumo a outra. - Regra (rule): uma condição e uma ação. "Se for TCP na porta 22, aceite."
Cada cadeia tem uma política (policy): o que fazer com um pacote que não bateu em nenhuma regra. accept deixa passar; drop descarta em silêncio.
Ler as regras atuais: nft list ruleset
- sudo
- O nftables só responde ao administrador.
- nft
- O programa que conversa com o nftables.
- list ruleset
- "Liste o conjunto de regras": mostra todas as tabelas, cadeias e regras ativas.
$ sudo nft list ruleset
[sudo: authenticate] Senha:
table inet filter { « tabela "filter", família inet
chain input { « cadeia ligada à entrada
type filter hook input priority filter; policy accept;
}
chain forward {
type filter hook forward priority filter; policy accept;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
Essa é a tabela vazia de exemplo que o Ubuntu traz em /etc/nftables.conf. Nenhuma cadeia tem regra e todas as políticas são accept: nada é bloqueado. Com o ufw ativo, a saída é bem maior e cheia de cadeias chamadas ufw-….
O que o comando devolve
Sem sudo, o nft não consegue nem ler as regras e devolve código 1:
$ nft list ruleset Operation not permitted (you must be root) netlink: Error: cache initialization failed: Operation not permitted $ echo $? 1
Uma regra, parte por parte
Vamos adicionar uma regra à cadeia input que aceita conexões SSH (porta 22):
- sudo nft
- O programa, como administrador.
- add rule
- Adiciona uma regra no fim da cadeia.
insert rulepõe no começo. - inet filter input
- Onde: família
inet, tabelafilter, cadeiainput. - tcp dport 22
- A condição: protocolo TCP com porta de destino (destination port) 22.
- accept
- A ação: deixar passar.
$ sudo nft add rule inet filter input tcp dport 22 accept
$ sudo nft list chain inet filter input
table inet filter {
chain input {
type filter hook input priority filter; policy accept;
tcp dport 22 accept « a regra nova
}
}
De novo, silêncio é sucesso. O list chain mostra só uma cadeia, o que é mais fácil de ler que o list ruleset inteiro.
Apagar uma regra: o número handle
Para apagar uma regra, você precisa do número dela, o handle ("alça"). A opção -a mostra esses números:
$ sudo nft -a list chain inet filter input
table inet filter {
chain input { # handle 1
type filter hook input priority filter; policy accept;
tcp dport 22 accept # handle 4 « o número da regra
}
}
$ sudo nft delete rule inet filter input handle 4
Tudo o que você adiciona com nft add vale só até reiniciar. Para regras permanentes, escreva o arquivo /etc/nftables.conf e ative o serviço, como na próxima seção.
Um firewall completo em /etc/nftables.conf
O jeito profissional é descrever todas as regras num arquivo e carregar o arquivo inteiro de uma vez. Este exemplo libera SSH, HTTP e HTTPS, aceita respostas de conexões que o próprio servidor abriu e descarta todo o resto:
#!/usr/sbin/nft -f
# Apaga todas as regras antigas antes de carregar as novas
flush ruleset
table inet filter {
chain input {
# Tudo o que não for aceito abaixo é descartado
type filter hook input priority filter; policy drop;
# Respostas de conexões já abertas (ex.: o apt baixando pacotes)
ct state established,related accept
# Pacotes sem sentido
ct state invalid drop
# A interface "lo" é a própria máquina conversando com ela mesma
iif "lo" accept
# ping e mensagens de controle do IPv4 e IPv6
meta l4proto { icmp, ipv6-icmp } accept
# SSH, com limite contra tentativas em massa
tcp dport 22 ct state new limit rate 15/minute accept
# Site: HTTP e HTTPS
tcp dport { 80, 443 } accept
}
chain forward {
# Este servidor não é roteador: não repassa nada
type filter hook forward priority filter; policy drop;
}
chain output {
# O servidor pode iniciar qualquer conexão de saída
type filter hook output priority filter; policy accept;
}
}
Os pontos que mais confundem:
| Trecho | Significado |
|---|---|
policy drop | Padrão "negar tudo". Só passa o que uma regra aceitar. |
ct state established,related | ct = connection tracking, o rastreio de conexões. Aceita as respostas do que o servidor pediu. Sem isso, o apt update para de funcionar. |
iif "lo" | Input interface = loopback. Muitos programas conversam consigo mesmos por 127.0.0.1. |
{ 80, 443 } | Um conjunto (set): vale para qualquer valor da lista. |
limit rate 15/minute | Aceita até 15 conexões SSH novas por minuto; o excedente cai na política drop. |
Verificar, carregar e tornar permanente
- sudo nft
- O programa, como administrador.
- -c
- Check: só confere a sintaxe, sem aplicar nada.
- -f /etc/nftables.conf
- File: lê as regras deste arquivo.
$ sudo nft -c -f /etc/nftables.conf $ echo $? 0 « sintaxe correta $ sudo nft -f /etc/nftables.conf « aplica agora $ sudo systemctl enable nftables « carrega o arquivo em todo boot Created symlink '/etc/systemd/system/sysinit.target.wants/nftables.service' → '/usr/lib/systemd/system/nftables.service'.
Com policy drop, um erro na regra do SSH derruba a sua conexão na hora, e você não consegue mais entrar. Num servidor que você só acessa por SSH, sempre use a técnica de segurança da próxima seção.
Testar sem medo: a "rede de segurança"
A ideia é agendar a volta das regras antigas para daqui a 5 minutos, aplicar as novas e, se tudo estiver bem, cancelar a volta. Se você perder o acesso, basta esperar: as regras antigas voltam sozinhas.
- Guarde as regras atuais num arquivo:
$ sudo nft list ruleset | sudo tee /root/regras-antigas.nft > /dev/null
- Agende a restauração para daqui a 5 minutos com um timer temporário do systemd:
$ sudo systemd-run --on-active=5min /usr/sbin/nft -f /root/regras-antigas.nft Running timer as unit: run-r3f1c2b9a.timer Will run service as unit: run-r3f1c2b9a.service
- Aplique as regras novas:
$ sudo nft -f /etc/nftables.conf
- Abra uma segunda janela e faça um SSH novo para o servidor. Se entrar, as regras estão boas. Cancele a restauração:
$ sudo systemctl stop run-r3f1c2b9a.timer
Se a nova conexão não entrar, não faça nada: em 5 minutos o timer recarrega as regras antigas.
Formas diferentes de fazer
| Forma | Exemplo | Melhor quando… |
|---|---|---|
| ufw | sudo ufw allow 443/tcp | Regras simples de portas, que é o caso da maioria dos servidores. |
nft add rule | sudo nft add rule inet filter input tcp dport 8080 accept | Testar uma regra rapidamente (some no reboot). |
Arquivo /etc/nftables.conf | sudo nft -f /etc/nftables.conf | Firewall completo, revisável e versionado no Git. |
| Modo interativo | sudo nft -i | Explorar comandos sem repetir sudo nft. |
Quando não funciona
$ sudo nft -c -f /etc/nftables.conf
/etc/nftables.conf:21:31-31: Error: syntax error, unexpected newline
tcp dport 22 acept
^
O que aconteceu: a palavra acept está escrita errado. O nft diz o arquivo, a linha (21) e a coluna, e aponta com ^ onde se perdeu.
Como resolver: corrija a linha e rode nft -c de novo antes de aplicar. Um arquivo com erro não é carregado pela metade: o nftables aplica tudo ou nada.
O que aconteceu: a cadeia input tem policy drop, mas falta a regra ct state established,related accept. O servidor pede os pacotes, e as respostas são descartadas na volta.
Como resolver: coloque a regra de ct state logo no início da cadeia input.
$ sudo nft list ruleset | grep -c ufw 84 « o ufw também está ativo
O que aconteceu: o ufw continua ativo e as cadeias dele descartam o pacote antes. Também pode ser que o serviço nem esteja escutando na porta.
Como resolver: escolha uma ferramenta só (sudo ufw disable) e confira se há programa escutando com sudo ss -tlnp (veja ip, ping, ss).
O que aconteceu: regras criadas com nft add só existem na memória.
Como resolver: escreva-as em /etc/nftables.conf e ative o serviço com sudo systemctl enable nftables. Para salvar o que está ativo agora: sudo nft list ruleset, conferir e colar no arquivo.
Referência
| Comando | O que faz |
|---|---|
nft list ruleset | Mostra todas as regras ativas |
nft list tables | Lista só os nomes das tabelas |
nft list chain inet filter input | Mostra uma cadeia |
nft -a list … | Inclui os números handle |
nft add rule FAMÍLIA TABELA CADEIA … | Adiciona regra no fim |
nft insert rule … | Adiciona regra no começo |
nft delete rule … handle N | Apaga a regra N |
nft add table inet nome | Cria uma tabela |
nft flush ruleset | Apaga todas as regras (tudo fica liberado) |
nft -c -f arquivo | Confere a sintaxe sem aplicar |
nft -f arquivo | Aplica um arquivo de regras |
nft -i | Modo interativo |
Condições mais usadas
| Condição | Significa |
|---|---|
tcp dport 22 / udp dport 53 | Porta de destino |
tcp dport { 80, 443 } | Qualquer porta da lista |
ip saddr 192.168.0.0/24 | Endereço de origem (source address) IPv4 |
iif "eth0" | Interface de entrada |
ct state established,related | Respostas de conexões existentes |
limit rate 10/minute | Limite de frequência |
Ações: accept (aceita), drop (descarta em silêncio), reject (recusa avisando o remetente), log prefix "texto " (registra no log e segue para a próxima regra).
Exercícios
1. Ler as regras
Complete o comando que mostra todas as regras ativas:
2. Liberar uma porta
Complete para aceitar conexões TCP na porta 8080 na cadeia input da tabela inet filter:
3. Conferir antes de aplicar
Complete para só verificar a sintaxe do arquivo, sem aplicar:
4. A cadeia input tem policy drop e nenhuma regra. O que acontece com uma conexão SSH nova?
5. No Ubuntu 26.04, o ufw…
Resumo
- Há um só motor de firewall no kernel;
ufw,iptablesenftsão formas de configurá-lo. Use um só. - Tabela (família
inet) → cadeia (input,forward,output) → regras (condição + ação). policy drop+ct state established,related accept+ portas liberadas = firewall "negar por padrão".- Regras permanentes vão em
/etc/nftables.conf; confira comnft -c -fe ative comsystemctl enable nftables. - Em servidor remoto, agende a volta das regras antigas antes de aplicar as novas.