Instalar e configurar o Nftables com exemplos básicos de configurações

O Nftables é o sucessor do bom e velho Iptables que deixará saudades. O Nftables substitui os populares {ip,ip6,arp,eb}tables. Este software fornece uma nova estrutura de classificação de pacotes no kernel baseada em uma máquina virtual (VM) específica para a rede e uma nova ferramenta de linha de comando (nft) que atua no espaço do usuário.

[ Hits: 6.403 ]

Por: Buckminster em 25/03/2023


Traduzindo regras do Iptables para o Nftables



Você pode gerar uma tradução de um comando iptables/ip6tables para saber o equivalente no Nftables, isso é muito útil.

Depois de instalado o Nftables na sua distribuição, basta jogar no terminal o comando iptables-translate seguido da regra Iptables que se quer traduzir para a sintaxe do Nftables e dar enter que a regra será traduzida automaticamente.

Regra no Iptables:

# iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

Comando para traduzir

# iptables-translate -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

A saída do comando acima será a mesma regra, mas na sintaxe do Nftables:

nft add rule ip filter INPUT tcp dport 22 ct state new counter accept

# iptables-translate -A FORWARD -i eth0 -o eth3 -p udp -m multiport --dports 111,222 -j ACCEPT
nft add rule ip6 filter FORWARD iifname eth0 oifname eth3 meta l4proto udp udp dport { 111,222} counter accept

Bloqueia porta, no caso a porta 20 tcp

# iptables-translate -A INPUT -p tcp --dport=20 -j DROP
nft add rule ip filter INPUT tcp dport 20 counter drop

Libera várias portas

# iptables-translate -A INPUT -p tcp -m multiport --dport 21,22,53,80,443,3128,8080 -j ACCEPT
nft add rule ip filter INPUT ip protocol tcp tcp dport { 21,22,53,80,443,3128,8080 } counter accept

Libera conexões estabelecidas por você:

# iptables-translate -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
nft add rule ip filter INPUT ct state related,established counter accept

# iptables-translate -A FORWARD -m state --state RELATED,ESTABLISHED,NEW -j ACCEPT
nft add rule ip filter FORWARD ct state new,related,established counter accept

# iptables-translate -A OUTPUT -m state --state RELATED,ESTABLISHED,NEW -j ACCEPT
nft add rule ip filter OUTPUT ct state new,related,established counter accept

Libera loopback:

# iptables-translate -A INPUT -i lo -j ACCEPT
nft add rule ip filter INPUT iifname "lo" counter accept

# iptables-translate -A OUTPUT -o lo -j ACCEPT
nft add rule ip filter OUTPUT oifname "lo" counter accept

Redireciona para o Squid:

# iptables-translate -t nat -A PREROUTING -i 192.168.1.0 -p tcp --dport 80 -j REDIRECT --to-port 3128
nft add rule ip nat PREROUTING iifname "192.168.1.0" tcp dport 80 counter redirect to :3128

Ativando o mascaramento:

# iptables-translate -t nat -A POSTROUTING -o 192.168.0.0 -j MASQUERADE
nft add rule ip nat POSTROUTING oifname "192.168.0.0" counter masquerade

Em vez de traduzir comando por comando, você pode também traduzir todo o seu conjunto de regras em uma única execução.

Lembre de tirar do script tudo o que não for regras Iptables.

Primeiro você passa o conteúdo do seu arquivo de configuração do Iptables para outro arquivo:

# iptables-save > nftables.txt

Dá um cat para verificar o conteúdo do novo arquivo:

# cat nftables.txt

# Generated by iptables-save v1.6.0 on Sat Dec 24 14:26:40 2016
*filter
:INPUT ACCEPT [5166:1752111]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [5058:628693]
-A FORWARD -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
COMMIT
# Completed on Sat Dec 24 14:26:40 2016

E traduz em bloco o arquivo inteiro com o seguinte comando:

# iptables-restore-translate -f nftables.txt

# Translated by iptables-restore-translate v1.6.0 on Sat Dec 24 14:26:59 2016
add table ip filter
add chain ip filter INPUT { type filter hook input priority 0; }
add chain ip filter FORWARD { type filter hook forward priority 0; }
add chain ip filter OUTPUT { type filter hook output priority 0; }
add rule ip filter FORWARD tcp dport 22 ct state new counter accept

Talvez depois de traduzir o script inteiro do bom e velho Iptables você tenha que adaptar alguma coisa na sintaxe para as regras do Nftables, mas será pouca coisa.

Até "pegar" o jeito do Nftables você pode e deve usar e abusar dessa ferramenta de tradução, pois ela facilita o trabalho principalmente para quem utilizava Iptables e agora tem de se adaptar ao Nftables.

Para instalar o Nftables basta utilizar o comando da sua distribuição.

Para incrementar podemos instalar alguns pacotes extras antes.

Por exemplo, no Debian e derivados, usei o apt-get, mas pode usar o apt ou o aptitude, à sua escolha.

# apt-get install automake bison debhelper dh-autoreconf dh-systemd docbook2x flex libgmp-dev libmnl-dev libnftnl-dev libreadline-dev libxtables-dev libtool asciidoc
# apt-get install nftables

Para habilitar o Nftables e inicializá-lo com o sistema:

# systemctl enable nftables.service

Para iniciar o serviço:

# systemctl start nftables.service

Para listar as regras existentes:

# nft list ruleset

Para remover:

# apt-get remove nftables

O arquivo de configuração do Nftables é o nftables.conf que é criado durante a instalação, geralmente em /etc/nftables.conf, mas como já foi dito, o caminho do arquivo depende da distribuição.

Tabelas (tables) e correntes (ou cadeias, chains) são totalmente configuráveis

Com o Nftables não há tabelas (tables) ou correntes (chains) pré-definidas. Cada tabela é explicitamente definida e contém apenas os objetos (chains, sets, maps, flowtables e stateful objects) que você adiciona explicitamente a ela, ou seja, cada tabela terá somente os objetos (chains, sets, maps, flowtables e stateful objects) que você criar nela.

As tabelas são contêineres para cadeias (ou correntes), conjuntos (sets) e objetos com estado (stateful objects). As chains, por sua vez, são contêineres para regras (rules).

Os maps armazenam dados com base em alguma chave específica usada como entrada. Eles são identificados exclusivamente por um nome definido pelo usuário e anexados às tabelas. Map (mapa), no caso, não devemos racionar com a palavra "mapa" em Português no sentido de carta geográfica, devemos racionar no sentido de mapear, traçar e armazenar dados.

O vmap (mapa de veredictos) funciona de forma análoga à instrução map, mas contém veredictos como valores. Veredictos aqui devemos racionar no sentido de decisão, no vmap colocamos uma tomada de decisão para o Nftables, ou seja, dizemos o que queremos que ele faça numa determinada situação.

O Nftables trabalha com tables, chains, rules, sets, objects, map, vmap, etc, basicamente.

A estrutura básica a ser utilizada quase sempre é a seguinte:

1. Criamos uma tabela:

# nft add table inet example_table

Criamos a tabela de nome example_table, o nome você escolhe de acordo com o que você quer, inet significa Internet (IPv4/IPv6) address family, é o endereço da família IPv4/IPv6.

Para cada família de endereços, o kernel contém os hooks em estágios específicos dos caminhos de processamento de pacotes que invocam o Nftables se existirem regras para esses ganchos (hooks).
  • ip - IPv4 address family.
  • ip6 - IPv6 address family.
  • inet - Internet (IPv4/IPv6) address family.
  • arp - ARP address family, handling IPv4 ARP packets (Família de endereços ARP, manipulando pacotes IPv4 ARP).
  • bridge - Bridge address family, handling packets which traverse a bridge device (Família de endereços de ponte [bridge], manipulando pacotes que atravessam um dispositivo de ponte).
  • netdev - Netdev address family, handling packets from ingress (Família de endereços Netdev, manipulando pacotes na entrada e na saída).

Na regra acima criamos a tabela de nome example_table na família inet para filtrar pacotes IPv4 e IPv6.

2. Criamos a chain tcp_packets dentro da tabela example_table:

# nft add chain inet example_table tcp_packets

O nome da tabela vem antes do nome da chain porque segue a estrutura table > chain, etc, ou seja, a tabela é um contêiner para chains, sets, etc e assim por diante.

3. Adicionamos uma regra (rule) a tcp_packets de acordo com o que queremos filtrar, no caso a regra conta o tráfego na chain:

# nft add rule inet example_table tcp_packets counter

Aqui utilizamos o counter (contador) anônimo já visto anteriormente

4. Criamos a chain udp_packets em example_table:

# nft add chain inet example_table udp_packets

5. Adicionamos uma regra na chain udp_packets que conta o tráfego nesta chain:

# nft add rule inet example_table udp_packets counter

6. Agora criamos uma chain para o tráfego de entrada chamada incoming_traffic que filtra o tráfego de entrada:

# nft add chain inet example_table incoming_traffic { type filter hook input priority 0 ; }

Primeiro vem o nome da tabela e depois o nome da chain.

O filtro é no gancho (hook) input com prioridade 0. Os hooks da família de endereços IPv4/IPv6/Inet no Nftables são cinco: prerouting, input, forward, output, postrouting e ingress.

No Iptables os hooks eram/são chains: input, output, forward, etc.

Alguém poderá pensar que simplesmente mudaram o nome de chain para hook no Nftables, mas não foi o que aconteceu, a mudança foi estrutural, não somente de nome.

7. Adicionamos uma regra com um mapa anônimo na chain incoming_traffic:

# nft add rule inet example_table incoming_traffic ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }

O vmap anônimo mapeia, traça e distingue os pacotes e os envia para as diferentes cadeias de contadores com base em seu protocolo.

No caso, "jump" salta o tráfego do protocolo tcp para a chain tcp_packets criada por nós e nesta chain adicionamos as regras que queremos para esse tráfego em específico no protocolo tcp.

E assim vamos colocando filtros nos pacotes que queremos, pois o Nftables é um filtro de pacotes e as tables, chains, vmaps, etc, grosso modo, são filtros que vamos encadeando dentro dessa estrutura de: table > chain > rule > map, vmap, stateful object, etc.

8. E listamos o que fizemos na tabela example_table:

# nft list table inet example_table

table inet example_table {
  chain tcp_packets {
    counter packets 36379 bytes 2103816
  }

  chain udp_packets {
    counter packets 10 bytes 1559
  }

  chain incoming_traffic {
    type filter hook input priority filter; policy accept;
    ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }
  }
}

Os contadores (counters) nas chains tcp_packets e udp_packets das regras acima exibem tanto o número de pacotes recebidos quanto o número de bytes.

Então o que fizemos foi simples e quase sempre terá essa estrutura: criamos a table, as chains, as rules, os counters e vmap, etc, e direcionamos o tráfego do protocolo tcp para as chains e filtramos com as regras. Isso é o básico, mas é importante.

Vimos que o vmap (mapa de veredictos) é uma decisão que damos ao Nftables para que salte o tráfego do protocolo tcp para as chains que criamos com a finalidade de filtrar esse tráfego.

Os nomes das tables, chains, vmap, etc, é você mesmo quem escolhe de acordo com o que você quer. É como dar nome aos arquivos em programação. O nome deve especificar de forma resumida o que a table, chain, etc, faz.

Agora vamos criar um vmap nomeado, com um nome.

1. Criamos uma table chamada tabela_exemplo para processar pacotes IPv4:

# nft add table ip tabela_exemplo

Criamos na família ip que é o que nos interessa

2. Criamos a chain com o nome chain_exemplo:

# nft add chain ip tabela_exemplo chain_exemplo { type filter hook input priority 0 ; }

A barra invertida serve para escapar o ponto e a vírgula; em alguns casos não é necessária, por exemplo, se você executar nft -i no terminal abrirá o modo interativo para a ferramenta nft e não precisará da barra invertida. Para sair do modo interativo basta digitar quit.

3. Criamos um map vazio, também na família ip:

# nft add map ip tabela_exemplo map_exemplo { type ipv4_addr : verdict ; }

4. E criamos uma regra para esse map:

# nft add rule tabela_exemplo chain_exemplo ip saddr vmap @map_exemplo

Nesta regra aplicamos ações para os endereços IPv4 que definiremos em map_exemplo.
  • saddr significa source address (endereço de origem).
  • daddr é endereço de destino, quando tiver.

5. Adicionamos endereços IPv4 e suas ações correspondentes em map_exemplo:

# nft add element ip tabela_exemplo map_exemplo { 192.0.2.1 : accept, 192.0.2.2 : drop }

Adicionamos um elemento (element, ver o man do Nftables) com a regra que faz o Nftables aceitar pacotes oriundos de 192.0.2.1 e dropar (rejeitar) pacotes oriundos de 192.0.2.2.

6. E podemos acrescentar endereços:

# nft add element ip tabela_exemplo map_exemplo { 192.0.2.3 : accept }

e remover:

# nft delete element ip tabela_exemplo map_exemplo { 192.0.2.1 }

7. Listando:

# nft list ruleset

table ip tabela_exemplo {
  map map_exemplo {
    type ipv4_addr : verdict
    elements = { 192.0.2.2 : drop, 192.0.2.3 : accept }
  }

  chain chain_exemplo {
    type filter hook input priority filter; policy accept;
    ip saddr vmap @map_exemplo
  }
}

Óbvio é que você pode listar as tables, chains, etc, diretamente como está acima e colocar dentro do arquivo nftables.conf, mas observe que a sintaxe dos comandos no terminal é diferente da sintaxe dentro do arquivo.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Traduzindo regras do Iptables para o Nftables
   3. Exemplos básicos de arquivos de configuração
   4. Conclusão
Outros artigos deste autor

VMD no Debian - Instalação e configuração

O Kernel Linux

Manual do IPtables - Comentários e sugestões de regras

Encapsulando BIND 9 e Apache 2 para obter maior segurança

Manual traduzido do Squid - Parte 3

Leitura recomendada

Configurando firewall Shorewall no CentOS

IpCop - Um firewall personalizado

Firewall e NAT em FreeBSD com controle de banda e redirecionamento de portas e IPs

Controlando 2 links de internet (roteados) em um gateway Linux com SQUID

Conexões de entrada e saída com 2 links em um servidor

  
Comentários
[1] Comentário enviado por fabio em 25/03/2023 - 12:12h

Ótimo artigo, parabéns!

[2] Comentário enviado por maurixnovatrento em 25/03/2023 - 15:58h


Muito bom. Ótimo artigo.

___________________________________________________________
Conhecimento não se Leva para o Túmulo.
https://github.com/mxnt10


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts