nftables: Estrutura de Firewall Linux

há 3 dias 12

Saudações. Nesse artigo e tutorial vou apresentar a vocês o nftables (nft), a nova estrutura de firewall do Kernel Linux.

Pré-requisitos (constam em outros artigos aqui do blog):

  • Instalação do Linux (Debian);
  • Internet no servidor;

Cuidados:

  • Não execute este tutorial em servidores que ja tenham:
    • Firewall UFW
    • Docker ou Podman

1 – Sobre o nftables

O Kernel Linux passa por 3 sistemas de firewall:

  • ipchains: o primeiro framework para firewall e NAT, descontinuado;
  • iptables netfilter: framework legado e mais utilizado;
  • nftables: versão nova do framework, com mais performance e compatibilidade extrema (eBPF e afins);

O Firewall do Linux é feito a nivel de kernel por módulos da camada netfilter. O iptables era o comando usado para gerir os módulos e regras na camada netfilter.

Recentemente as distribuições migraram para o nftables. A compatibilidade é mantida por meio do iptables-nft, que traduz os argumentos de iptables para nft e aplica as regras.

Vamos configurar nosso Debian para que ele seja 100% guiado por regras de nftables.

Instalando

Bash

# Instalar NFTABLES: apt -y install iptables; apt -y install nftables; # Instalar ferramentas relacionadas: apt -y install conntrack; # Ativar execução do nftables durante o boot: systemctl enable nftables;

Preparativos

Bash

# Desativar firewall para reestruturacao: systemctl stop nftables; # Backup da configuração original: [ -f /etc/nftables.conf.orig ] || cp /etc/nftables.conf /etc/nftables.conf.orig; # Criar configuracao baseada nos arquivos ordenados # da pasta /etc/nftables.d/ mkdir -p /etc/nftables.d; ( echo '#!/usr/sbin/nft -f' echo echo 'flush ruleset' echo 'include "/etc/nftables.d/*.conf"' echo 'include "/etc/nftables.d/*.nft"' echo ) > /etc/nftables.conf;

Com a configuração acima, nosso firewall se baseará na existencia de arquivos no diretório /etc/nftables.d

Vamos criar arquivos com 2 extensões diferentes:

  • *.conf: arquivos que definirão tabelas principais padronizadas;
  • *.nft: arquivos que criarão estruturas personalizadas de firewall, tabelas, listas, etc…;

2 – Estrutura de firewall

Com essas configurações, vou recriar no nftables os mesmos nomes da estrutura legada do iptables, com isso poderemos usar regras de nftables (nft) e tornar nosso firewall compatível com iptables-nft.

Estruturas:

  • RAW: pre-processamento bruto de pacotes;
  • NAT: permite redirecionar pacotes e fazer NAT/CGNAT;
  • MANGLE: permite marcações especiais de pacotes e conexões;
  • FILTER: permite a filtragem (DROP e REJECT) de pacotes;

Criando arquivos das estruturas

Bash

# Arquivos de boot das tabelas echo "create table ip raw" > /etc/nftables.d/0001-table-ipv4-raw.conf; echo "create table ip mangle" > /etc/nftables.d/0002-table-ipv4-mangle.conf; echo "create table ip filter" > /etc/nftables.d/0003-table-ipv4-filter.conf; echo "create table ip nat" > /etc/nftables.d/0004-table-ipv4-nat.conf; echo "create table ip6 raw" > /etc/nftables.d/0011-table-ipv6-raw.conf; echo "create table ip6 mangle" > /etc/nftables.d/0012-table-ipv6-mangle.conf; echo "create table ip6 filter" > /etc/nftables.d/0013-table-ipv6-filter.conf; echo "create table ip6 nat" > /etc/nftables.d/0014-table-ipv6-nat.conf; #======================================================== IPv4 #------------ RAW ( echo "create chain ip raw PREROUTING {"; echo " type filter hook prerouting priority raw;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0021-chain-ipv4-raw-prerouting.conf; ( echo "create chain ip raw OUTPUT {"; echo " type filter hook output priority raw;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0022-chain-ipv4-raw-output.conf; #------------ MANGLE ( echo "create chain ip mangle PREROUTING {"; echo " type filter hook prerouting priority mangle;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0023-chain-ipv4-mangle-prerouting.conf; ( echo "create chain ip mangle POSTROUTING {"; echo " type filter hook postrouting priority mangle;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0024-chain-ipv4-mangle-postrouting.conf; ( echo "create chain ip mangle FORWARD {"; echo " type filter hook forward priority mangle;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0025-chain-ipv4-mangle-forward.conf; ( echo "create chain ip mangle INPUT {"; echo " type filter hook input priority mangle;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0026-chain-ipv4-mangle-forward.conf; ( echo "create chain ip mangle OUTPUT {"; echo " type route hook output priority mangle;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0027-chain-ipv4-mangle-output.conf; #------------ FILTER ( echo "create chain ip filter FORWARD {"; echo " type filter hook forward priority filter;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0028-chain-ipv4-filter-forward.conf; ( echo "create chain ip filter INPUT {"; echo " type filter hook input priority filter;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0029-chain-ipv4-filter-input.conf; ( echo "create chain ip filter OUTPUT {"; echo " type filter hook output priority filter;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0030-chain-ipv4-filter-output.conf; #------------ NAT ( echo "create chain ip nat PREROUTING {"; echo " type nat hook prerouting priority dstnat;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0031-chain-ipv4-nat-prerouting.conf; ( echo "create chain ip nat INPUT {"; echo " type nat hook input priority 100;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0032-chain-ipv4-nat-input.conf; ( echo "create chain ip nat OUTPUT {"; echo " type nat hook output priority -100;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0033-chain-ipv4-nat-output.conf; ( echo "create chain ip nat POSTROUTING {"; echo " type nat hook postrouting priority srcnat;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0034-chain-ipv4-nat-postrouting.conf; #======================================================== IPv6 #------------ RAW ( echo "create chain ip6 raw PREROUTING {"; echo " type filter hook prerouting priority raw;"; echo " policy accept"; echo "}"; ) > /etc/nftables.d/0041-chain-ipv6-raw-prerouting.conf; ( echo "create chain ip6 raw OUTPUT {"; echo " type filter hook output priority raw;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0042-chain-ipv6-raw-postrouting.conf; #------------ MANGLE ( echo "create chain ip6 mangle PREROUTING {"; echo " type filter hook prerouting priority mangle;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0043-chain-ipv6-mangle-prerouting.conf; ( echo "create chain ip6 mangle POSTROUTING {"; echo " type filter hook postrouting priority mangle;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0044-chain-ipv6-mangle-postrouting.conf; ( echo "create chain ip6 mangle FORWARD {"; echo " type filter hook forward priority mangle;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0045-chain-ipv6-mangle-forward.conf; ( echo "create chain ip6 mangle INPUT {"; echo " type filter hook input priority mangle;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0046-chain-ipv6-mangle-input.conf; ( echo "create chain ip6 mangle OUTPUT {"; echo " type route hook output priority mangle;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0047-chain-ipv6-mangle-output.conf; #------------ FILTER ( echo "create chain ip6 filter FORWARD {"; echo " type filter hook forward priority filter;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0048-chain-ipv6-filter-forward.conf; ( echo "create chain ip6 filter INPUT {"; echo " type filter hook input priority filter;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0049-chain-ipv6-filter-input.conf; ( echo "create chain ip6 filter OUTPUT {"; echo " type filter hook output priority filter;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0050-chain-ipv6-filter-output.conf; #------------ NAT ( echo "create chain ip6 nat PREROUTING {"; echo " type nat hook prerouting priority dstnat;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0051-chain-ipv6-filter-prerouting.conf; ( echo "create chain ip6 nat POSTROUTING {"; echo " type nat hook postrouting priority srcnat;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0051-chain-ipv6-filter-postrouting.conf; ( echo "create chain ip6 nat OUTPUT {"; echo " type nat hook output priority -100;"; echo " policy accept;"; echo "}"; ) > /etc/nftables.d/0052-chain-ipv6-filter-output.conf;

Testando se arquivos estruturais estão sintaticamente corretos:

Bash

# Localizar bugs nos arquivos de firewall # - Entrar na pasta: cd /etc/nftables.d; # - Limpar firewall: nft flush ruleset; # - Testar arquivo por arquivo: for i in *; do echo; echo $i; nft -f $i || { echo "Falhou em $i"; break; }; done; # Reiniciar para aplicar systemctl restart nftables;

Se encontrou algum erro no script acima, revise o arquivo afetado e arrume-o.

Visualizando estrutura:

Visualizando configurações na ordem de execução:

Bash

( cat /etc/nftables.d/*.conf 2>/dev/null; cat /etc/nftables.d/*.nft 2>/dev/null; );

3 – Regras

Para criar regras, tabelas personalizadas e demais recursos do nftables, faço-o criando arquivos que sejam executados em ordem e após a configuração inicial.

Formato:

  • /etc/nftables.d/NNNN-NOME-DESCRICAO.nft

Onde NNNN deve manter a coerência da ordem, 4 dígitos numéricos.

4 – Exemplos de NAT

Exemplos de regras para fazer redirecionamento de portas, NAT e CGNAT.

NAT Masquerade:

Bash

# Criar SET (lista) de prefixos privados: ( echo "set ip nat PRIVNETS_IPV4 {"; echo " type ipv4_addr;"; echo " flags interval;"; echo "}"; ) > /etc/nftables.d/1001-ipv4-nat-set-privnets.nft; ( echo "set ip6 nat PRIVNETS_IPV6 {"; echo " type ipv6_addr;"; echo " flags interval;"; echo "}"; ) > /etc/nftables.d/1002-ipv6-nat-set-privnets.nft; # - Preencher SET com IPs privados IPv4 ( echo "add element ip nat PRIVNETS_IPV4 {"; echo " 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12"; echo "}"; ) > /etc/nftables.d/1011-ipv4-nat-add-privnets.nft; # - Preencher SET com IPs privados IPv6 ( echo "add element ip6 nat PRIVNETS_IPV6 {"; echo " ::/3, 2001:db8::/32, 4000::/2, 8000::/1"; echo "}"; ) > /etc/nftables.d/1012-ipv6-nat-add-privnets.nft; # NAT MASQUERADE na interface de saida # - IPv4 echo 'add rule ip nat POSTROUTING ip saddr @PRIVNETS_IPV4 oifname "eth0" counter masquerade' > /etc/nftables.d/1901-ipv4-nat-masquerade.nft; # ou SNAT: #echo 'add rule ip nat POSTROUTING ip saddr @PRIVNETS_IPV4 oifname "eth0" counter snat ip to 45.255.128.2' > /etc/nftables.d/1901-ipv4-nat-snat.nft; # - IPv6 echo 'add rule ip6 nat POSTROUTING ip6 saddr @PRIVNETS_IPV6 oifname "eth0" counter masquerade' > /etc/nftables.d/1902-ipv6-nat-masquerade.nft; # ou SNAT: #echo 'add rule ip6 nat POSTROUTING ip6 saddr @PRIVNETS_IPV4 oifname "eth0" counter snat ip6 to 2804:cafe::2' > /etc/nftables.d/1902-ipv6-nat-masquerade.nft;

(parei aqui, falta adicionar mais exemplos)

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com

Ler artigo completo