A máquina virtual Gateway é o coração da infraestrutura de rede do laboratório. Como as redes internas (infra, auth, db, dhcp, kube) são do tipo Host-Only (isoladas), o Gateway atua como roteador central, firewall e provedor de acesso à internet (NAT) para todo o ambiente.
Este documento detalha a configuração do firewall utilizando o nftables, o substituto moderno do iptables no Linux. A configuração foi estruturada de forma declarativa, utilizando conjuntos (sets) para facilitar a manutenção e leitura das regras.
Por padrão, o firewall vem desabilitado em instalações limpas do Debian. O primeiro passo é garantir que o serviço esteja ativo e rodando.
# Verifica o status atual do serviço
sudo systemctl status nftables
# Habilita a inicialização automática no boot e inicia o serviço imediatamente
sudo systemctl enable --now nftables
Para visualizar o conjunto de regras (ruleset) atual carregado na memória:
sudo nft list ruleset
Para que o Gateway possa receber pacotes de uma rede interna (ex: 10.48.1.x) e encaminhá-los para a rede externa (Internet) ou para outra rede interna, o recurso de encaminhamento de pacotes do kernel Linux deve ser ativado.
# Habilita o forwarding para IPv4
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-forwarding.conf
# Habilita o forwarding para IPv6
echo "net.ipv6.conf.all.forwarding=1" | sudo tee -a /etc/sysctl.d/99-forwarding.conf
# Aplica as configurações imediatamente sem necessidade de reboot
sudo sysctl -p /etc/sysctl.d/99-forwarding.conf
A grande vantagem do nftables é a capacidade de agrupar IPs, portas e interfaces em conjuntos (sets). Isso elimina a necessidade de criar dezenas de regras repetitivas, resultando em um firewall muito mais limpo e performático.
O NAT (Network Address Translation) é necessário para mascarar os IPs internos quando eles acessam a internet, fazendo com que o tráfego pareça originar do IP externo do Gateway.
# Tabela e chain para NAT IPv4
sudo nft add table nat
sudo nft add chain nat postrouting { type nat hook postrouting priority 100\; }
# Tabela e chain para NAT IPv6
sudo nft add table ip6 nat
sudo nft add chain ip6 nat postrouting { type nat hook postrouting priority 100\; }
Em vez de referenciar as interfaces diretamente nas regras, criamos grupos lógicos que representam "de onde o tráfego pode vir".
# Agrupa todas as interfaces internas (LANs). A interface enp1s0 (WAN) é propositalmente excluída.
sudo nft add set inet filter internal_ifaces { type ifname\; }
sudo nft add element inet filter internal_ifaces { enp2s0, enp3s0, enp4s0, enp5s0, enp6s0 }
# Define quais redes têm permissão para acessar a rede do Kubernetes (kube-net)
sudo nft add set inet filter kube_src { type ifname\; }
sudo nft add element inet filter kube_src { enp2s0, enp5s0 } # infra-net e dhcp-net
# Define quais redes têm permissão para acessar a rede de Autenticação (Samba/FreeIPA)
sudo nft add set inet filter auth_src { type ifname\; }
sudo nft add element inet filter auth_src { enp2s0, enp5s0, enp6s0 }
# Define quais redes têm permissão para acessar a rede de Banco de Dados
sudo nft add set inet filter db_src { type ifname\; }
sudo nft add element inet filter db_src { enp2s0, enp5s0, enp6s0 }
Agrupamento das portas necessárias para cada tipo de serviço que roda na infraestrutura.
# Serviços Básicos
sudo nft add set inet filter dns_ports { type inet_service\; }
sudo nft add element inet filter dns_ports { 53 }
sudo nft add set inet filter nfs_ports { type inet_service\; }
sudo nft add element inet filter nfs_ports { 111, 2049, 3260, 20048 }
# Serviços de Diretório (Samba AD / FreeIPA)
sudo nft add set inet filter auth_tcp_ports { type inet_service\; }
sudo nft add element inet filter auth_tcp_ports { 389, 636, 88, 464, 135, 139, 445 }
sudo nft add set inet filter auth_udp_ports { type inet_service\; }
sudo nft add element inet filter auth_udp_ports { 88, 464, 137, 138 }
# Bancos de Dados
sudo nft add set inet filter db_ports { type inet_service\; }
sudo nft add element inet filter db_ports { 3306, 5432 } # MySQL e PostgreSQL
# Tráfego Web
sudo nft add set inet filter http_ports { type inet_service\; }
sudo nft add element inet filter http_ports { 80, 443, 8080 }
# Kubernetes - Comunicação do Cluster
sudo nft add set inet filter k8s_api_ports { type inet_service\; }
sudo nft add element inet filter k8s_api_ports { 6443 }
sudo nft add set inet filter k8s_control_ports { type inet_service\; }
sudo nft add element inet filter k8s_control_ports { 2379, 2380, 10250, 10257, 10259, 10249 }
# A flag 'interval' permite especificar um range de portas (ex: 30000-32767)
sudo nft add set inet filter k8s_nodeport_ports { type inet_service\; flags interval\; }
sudo nft add element inet filter k8s_nodeport_ports { 30000-32767 }
sudo nft add set inet filter opensearch_ports { type inet_service\; flags interval\; }
sudo nft add element inet filter opensearch_ports { 9200-9300 }
# MetalLB - Roteamento BGP para LoadBalancers do K8s
sudo nft add set inet filter bgp_ports { type inet_service\; }
sudo nft add element inet filter bgp_ports { 179 }
sudo nft add set inet filter bfd_ports { type inet_service\; }
sudo nft add element inet filter bfd_ports { 3784, 3785 }
Definição dos blocos de IP correspondentes a cada rede lógica do ambiente. A flag interval é obrigatória ao trabalhar com blocos CIDR no nftables.
# Rede Externa (Internet)
sudo nft add set inet filter external_net_v4 { type ipv4_addr\; flags interval\; }
sudo nft add element inet filter external_net_v4 { 0.0.0.0/0 }
sudo nft add set inet filter external_net_v6 { type ipv6_addr\; flags interval\; }
sudo nft add element inet filter external_net_v6 { ::/0 }
# Rede de Infraestrutura
sudo nft add set inet filter infra_net_v4 { type ipv4_addr\; flags interval\; }
sudo nft add element inet filter infra_net_v4 { 10.48.1.0/24 }
sudo nft add set inet filter infra_net_v6 { type ipv6_addr\; flags interval\; }
sudo nft add element inet filter infra_net_v6 { fd00:0:b:1::/64 }
# Rede do Kubernetes
sudo nft add set inet filter kube_net_v4 { type ipv4_addr\; flags interval\; }
sudo nft add element inet filter kube_net_v4 { 10.48.9.0/24 }
sudo nft add set inet filter kube_net_v6 { type ipv6_addr\; flags interval\; }
sudo nft add element inet filter kube_net_v6 { fd00:0:b:9::/64 }
# Rede de Autenticação
sudo nft add set inet filter auth_net_v4 { type ipv4_addr\; flags interval\; }
sudo nft add element inet filter auth_net_v4 { 10.48.3.0/24 }
sudo nft add set inet filter auth_net_v6 { type ipv6_addr\; flags interval\; }
sudo nft add element inet filter auth_net_v6 { fd00:0:b:3::/64 }
# Rede de Banco de Dados
sudo nft add set inet filter db_net_v4 { type ipv4_addr\; flags interval\; }
sudo nft add element inet filter db_net_v4 { 10.48.5.0/24 }
sudo nft add set inet filter db_net_v6 { type ipv6_addr\; flags interval\; }
sudo nft add element inet filter db_net_v6 { fd00:0:b:5::/64 }
# Rede de DHCP
sudo nft add set inet filter dhcp_net_v4 { type ipv4_addr\; flags interval\; }
sudo nft add element inet filter dhcp_net_v4 { 10.48.7.0/24 }
sudo nft add set inet filter dhcp_net_v6 { type ipv6_addr\; flags interval\; }
sudo nft add element inet filter dhcp_net_v6 { fd00:0:b:7::/64 }
# Pool do MetalLB (IPs virtuais anunciados via BGP fora do cluster)
sudo nft add set inet filter metallb_net_v4 { type ipv4_addr\; flags interval\; }
sudo nft add element inet filter metallb_net_v4 { 10.48.10.0/24 }
sudo nft add set inet filter metallb_net_v6 { type ipv6_addr\; flags interval\; }
sudo nft add element inet filter metallb_net_v6 { fd00:0:b:a::/64 }
Com todos os conjuntos (sets) definidos, a escrita das regras torna-se extremamente semântica e fácil de ler.
Esta regra permite que as VMs das redes internas naveguem na internet, substituindo seus IPs internos pelo IP da interface WAN (enp1s0) do Gateway.
sudo nft add rule ip nat postrouting oifname "enp1s0" masquerade
sudo nft add rule ip6 nat postrouting oifname "enp1s0" masquerade
A chain INPUT controla o tráfego destinado ao próprio Gateway.
# Permite tráfego na interface de loopback (local)
sudo nft add rule inet filter input iif "lo" accept
# Permite o retorno de conexões que o Gateway iniciou
sudo nft add rule inet filter input ct state established,related accept
# Permite tráfego ICMP essencial (Ping, Path MTU Discovery)
sudo nft add rule inet filter input ip protocol icmp icmp type { echo-request, echo-reply, destination-unreachable, time-exceeded } accept
sudo nft add rule inet filter input ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply, destination-unreachable, time-exceeded, nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert } accept
# Permite gerenciamento via SSH
sudo nft add rule inet filter input tcp dport 22 ct state new accept
# Permite sincronização de relógio (NTP) vindo das redes internas
sudo nft add rule inet filter input iifname @internal_ifaces udp dport 123 accept
# Permite requisições DHCP apenas na interface dedicada a isso (enp5s0)
sudo nft add rule inet filter input iifname "enp5s0" udp dport { 67, 68 } accept
sudo nft add rule inet filter input iifname "enp5s0" udp dport { 546, 547 } accept
# Permite comunicação BGP/BFD do MetalLB apenas na interface do Kubernetes (enp6s0)
sudo nft add rule inet filter input iifname "enp6s0" tcp dport @bgp_ports accept
sudo nft add rule inet filter input iifname "enp6s0" udp dport @bfd_ports accept
# Cria um contador e registra pacotes bloqueados no syslog (útil para troubleshooting)
sudo nft add counter inet filter blocked_input
sudo nft add rule inet filter input log prefix '"nftables-input-block: "' group 1 limit rate 10/minute burst 5 packets counter name "blocked_input" drop
A chain FORWARD controla o tráfego que passa através do Gateway (de uma rede para outra). É aqui que o isolamento entre os ambientes é garantido.
# Permite o retorno de conexões já estabelecidas entre as redes
sudo nft add rule inet filter forward ct state established,related accept
# Permite ICMP entre todas as redes para diagnóstico
sudo nft add rule inet filter forward ip protocol icmp icmp type { echo-request, echo-reply, destination-unreachable, time-exceeded } accept
sudo nft add rule inet filter forward ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply, destination-unreachable, time-exceeded, nd-neighbor-solicit, nd-neighbor-advert } accept
# Acesso à Internet: Permite que qualquer rede interna saia pela WAN
sudo nft add rule inet filter forward iifname @internal_ifaces oifname "enp1s0" accept
# Acesso à Infraestrutura (DNS e NFS/Storage)
sudo nft add rule inet filter forward iifname @internal_ifaces oifname "enp2s0" tcp dport @dns_ports accept
sudo nft add rule inet filter forward iifname @internal_ifaces oifname "enp2s0" udp dport @dns_ports accept
sudo nft add rule inet filter forward iifname @internal_ifaces oifname "enp2s0" tcp dport @nfs_ports accept
sudo nft add rule inet filter forward iifname @internal_ifaces oifname "enp2s0" udp dport @nfs_ports accept
# Acesso ao Kubernetes (k8s-net)
sudo nft add rule inet filter forward iifname @kube_src oifname "enp6s0" tcp dport @k8s_api_ports accept
sudo nft add rule inet filter forward iifname @internal_ifaces oifname "enp6s0" tcp dport @k8s_control_ports accept
sudo nft add rule inet filter forward iifname @kube_src oifname "enp6s0" tcp dport @k8s_nodeport_ports accept
sudo nft add rule inet filter forward iifname @internal_ifaces oifname "enp6s0" tcp dport @http_ports accept
sudo nft add rule inet filter forward iifname @kube_src oifname "enp6s0" tcp dport @opensearch_ports accept
# Acesso à Autenticação (Samba AD / FreeIPA)
sudo nft add rule inet filter forward iifname @auth_src oifname "enp3s0" tcp dport @auth_tcp_ports accept
sudo nft add rule inet filter forward iifname @auth_src oifname "enp3s0" udp dport @auth_udp_ports accept
# Acesso ao Banco de Dados (MySQL / PostgreSQL)
sudo nft add rule inet filter forward iifname @db_src oifname "enp4s0" tcp dport @db_ports accept
# Acesso aos IPs Virtuais do LoadBalancer (MetalLB)
sudo nft add rule inet filter forward iifname @internal_ifaces ip daddr @metallb_net_v4 accept
sudo nft add rule inet filter forward iifname @internal_ifaces ip6 daddr @metallb_net_v6 accept
# Cria um contador e registra pacotes de encaminhamento bloqueados
sudo nft add counter inet filter blocked_forward
sudo nft add rule inet filter forward log prefix '"nftables-forward-block: "' group 1 limit rate 10/minute burst 5 packets counter name "blocked_forward" drop
Após configurar todas as permissões necessárias, alteramos a política padrão das chains para DROP. Isso significa que "tudo o que não for explicitamente permitido, será bloqueado".
Atenção: Só execute este passo após garantir que a regra de SSH na chain INPUT foi adicionada corretamente, caso contrário você perderá o acesso remoto ao Gateway!
sudo nft chain inet filter input { policy drop\; }
sudo nft chain inet filter forward { policy drop\; }
Diferente do iptables clássico, o nftables requer que o estado atual da memória seja salvo em um arquivo para sobreviver a reinicializações.
# Salva as regras atuais no arquivo de configuração padrão
sudo nft list ruleset | sudo tee /etc/nftables.conf
# Reinicia o serviço para garantir que o arquivo foi lido corretamente
sudo systemctl restart nftables
# Verifica o status
sudo systemctl status nftables
Para verificar se o firewall está bloqueando tráfego não autorizado, consulte os contadores que criamos:
sudo nft list counters
Saída esperada:
table inet filter {
counter blocked_input {
packets 14 bytes 840
}
counter blocked_forward {
packets 0 bytes 0
}
}
O método recomendado para remover regras no nftables é utilizando seu identificador único (handle), garantindo que você não exclua a regra errada.
# Lista todas as regras exibindo o número do handle ao final de cada linha
sudo nft -a list ruleset
# Para focar apenas na chain de encaminhamento:
sudo nft -a list chain inet filter forward
# Exclui a regra específica utilizando seu handle (ex: handle 5)
sudo nft delete rule inet filter forward handle 5
A maior vantagem dos sets é poder adicionar ou remover portas/IPs sem precisar tocar nas regras de firewall propriamente ditas.
# Lista os elementos atuais do conjunto de portas DNS
sudo nft list set inet filter dns_ports
# Remove uma porta do conjunto
sudo nft delete element inet filter dns_ports { 53 }
# Adiciona uma nova porta ao conjunto
sudo nft add element inet filter dns_ports { 5353 }
Sempre que precisar alterar o firewall do Gateway, siga este fluxo seguro:
sudo nft list ruleset > /tmp/nft-backup-$(date +%Y%m%d-%H%M%S).confsudo nft -a list ruleset (Anote os handles)sudo nft list ruleset | sudo tee /etc/nftables.confsudo nft monitor ou journalctl -u nftables -f.