O Firewalld é o daemon moderno e dinâmico de firewall para Linux que substitui o iptables como ferramenta predefinida de gestão de firewall. Fornece uma abordagem mais simples, baseada em zonas, para a configuração do firewall, com gestão de regras em tempo de execução e permanentes. Este guia aborda a configuração de firewalls em servidores de produção na perspetiva de um programador sénior.
Porquê o Firewalld
O Firewalld oferece vantagens significativas face ao iptables em bruto:
- Regras dinâmicas: Aplicar alterações sem reiniciar o firewall
- Baseado em zonas: Agrupar interfaces e origens em zonas de segurança
- Interface D-Bus: Acesso programático para aplicações
- Rich rules: Sintaxe legível por humanos para regras complexas
- Definições de serviços: Regras predefinidas para serviços comuns
Instalação
CentOS/RHEL/Fedora
# Normalmente vem pré-instalado, mas, se necessário:
sudo dnf install firewalld
# Iniciar e ativar
sudo systemctl start firewalld
sudo systemctl enable firewalld
# Verificar estado
sudo firewall-cmd --state
Ubuntu/Debian
sudo apt install firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld
Compreender as zonas
O Firewalld utiliza zonas para definir níveis de confiança para ligações de rede:
| Zone | Description | Default Services |
|---|
| drop | Drop all incoming, no reply | None |
| block | Reject all incoming with message | None |
| public | Untrusted networks (default) | ssh, dhcpv6-client |
| external | For routers with NAT masquerading | ssh |
| dmz | Publicly accessible servers | ssh |
| work | Work environment | ssh, dhcpv6-client |
| home | Home environment | ssh, mdns, dhcpv6-client |
| internal | Internal networks | Same as home |
| trusted | All connections accepted | All |
Ver informação da zona
# Listar todas as zonas
sudo firewall-cmd --get-zones
# Obter a zona predefinida
sudo firewall-cmd --get-default-zone
# Obter as zonas ativas
sudo firewall-cmd --get-active-zones
# Listar tudo numa zona
sudo firewall-cmd --zone=public --list-all
# Listar todas as zonas com detalhes
sudo firewall-cmd --list-all-zones
Definir a zona predefinida
# Alterar a zona predefinida
sudo firewall-cmd --set-default-zone=home
# Atribuir interface à zona
sudo firewall-cmd --zone=internal --change-interface=eth1 --permanent
sudo firewall-cmd --reload
Gerir serviços
Listar e ativar serviços
# Listar serviços disponíveis
sudo firewall-cmd --get-services
# Listar serviços na zona
sudo firewall-cmd --zone=public --list-services
# Adicionar serviço (apenas em tempo de execução)
sudo firewall-cmd --zone=public --add-service=http
# Adicionar serviço permanentemente
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --reload
# Remover serviço
sudo firewall-cmd --zone=public --remove-service=http --permanent
sudo firewall-cmd --reload
Serviços comuns
# Servidor web
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# Base de dados
sudo firewall-cmd --permanent --add-service=mysql
sudo firewall-cmd --permanent --add-service=postgresql
# Correio
sudo firewall-cmd --permanent --add-service=smtp
sudo firewall-cmd --permanent --add-service=imap
sudo firewall-cmd --permanent --add-service=imaps
# Aplicar tudo
sudo firewall-cmd --reload
Gerir portas
Abrir portas específicas
# Abrir porta (tempo de execução)
sudo firewall-cmd --zone=public --add-port=8080/tcp
# Abrir porta permanentemente
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
# Abrir intervalo de portas
sudo firewall-cmd --zone=public --add-port=5000-5100/tcp --permanent
# Listar portas abertas
sudo firewall-cmd --zone=public --list-ports
# Remover porta
sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent
sudo firewall-cmd --reload
Portas UDP
# DNS
sudo firewall-cmd --permanent --add-port=53/udp
# VPN
sudo firewall-cmd --permanent --add-port=1194/udp
# Aplicar
sudo firewall-cmd --reload
Rich rules
As rich rules fornecem controlo granular:
Permitir a partir de um IP específico
# Permitir tudo a partir do IP
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" accept' --permanent
# Permitir porta específica a partir do IP
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="3306" accept' --permanent
# Permitir a partir da sub-rede
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="22" accept' --permanent
Bloquear um IP específico
# Descartar tudo a partir do IP
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.50" drop' --permanent
# Rejeitar (envia resposta)
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.50" reject' --permanent
Limitação de taxa
# Limitar ligações SSH (evitar brute force)
sudo firewall-cmd --zone=public --add-rich-rule='rule service name="ssh" limit value="3/m" accept' --permanent
Registo (logging)
# Registar pacotes descartados
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" log prefix="Dropped: " level="info" drop' --permanent
Listar rich rules
sudo firewall-cmd --zone=public --list-rich-rules
Proteger o SSH
Boa prática: restringir o SSH apenas a IPs de confiança.
# Criar zona trusted para SSH
sudo firewall-cmd --zone=trusted --add-service=ssh --permanent
# Adicionar IPs de confiança
sudo firewall-cmd --zone=trusted --add-source=192.168.1.0/24 --permanent
sudo firewall-cmd --zone=trusted --add-source=10.20.30.40 --permanent
# Remover SSH da zona public
sudo firewall-cmd --zone=public --remove-service=ssh --permanent
# Aplicar
sudo firewall-cmd --reload
Encaminhamento de portas
Encaminhar para outra porta
# Encaminhar a porta 80 para 8080
sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080 --permanent
# Encaminhar para outro IP
sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.10:toport=8080 --permanent
# Ativar masquerading (necessário para encaminhar para outros hosts)
sudo firewall-cmd --zone=public --add-masquerade --permanent
sudo firewall-cmd --reload
Definições de serviços personalizadas
Criar serviço personalizado
# Criar ficheiro de serviço
sudo cat > /etc/firewalld/services/myapp.xml << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>MyApp</short>
<description>My Custom Application</description>
<port protocol="tcp" port="3000"/>
<port protocol="tcp" port="3001"/>
</service>
EOF
# Recarregar para reconhecer o novo serviço
sudo firewall-cmd --reload
# Utilizar o serviço
sudo firewall-cmd --zone=public --add-service=myapp --permanent
sudo firewall-cmd --reload
Exemplo de servidor de produção
Configuração completa para um servidor web típico:
#!/bin/bash
# Configuração segura de firewall para servidor web
# Definir a zona predefinida
firewall-cmd --set-default-zone=public
# Remover serviços desnecessários
firewall-cmd --zone=public --remove-service=dhcpv6-client --permanent
# Serviços web
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --zone=public --add-service=https --permanent
# SSH apenas a partir de IPs de confiança
firewall-cmd --zone=trusted --add-service=ssh --permanent
firewall-cmd --zone=trusted --add-source=10.0.0.0/8 --permanent
firewall-cmd --zone=public --remove-service=ssh --permanent
# Portas da aplicação (apenas internas)
firewall-cmd --zone=internal --add-port=3000/tcp --permanent # Node.js
firewall-cmd --zone=internal --add-port=6379/tcp --permanent # Redis
firewall-cmd --zone=internal --add-source=10.0.1.0/24 --permanent
# Limitar a taxa de tráfego web público
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" service name="http" limit value="25/s" accept' --permanent
# Registar pacotes descartados (para depuração)
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" log prefix="DROPPED: " level="warning" limit value="5/m"' --permanent
# Aplicar todas as alterações
firewall-cmd --reload
# Verificar
firewall-cmd --list-all-zones
Tempo de execução vs. permanente
# Apenas em tempo de execução (perde-se após reinício)
sudo firewall-cmd --add-service=http
# Permanente (persiste após reinício)
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --reload
# Tornar permanentes as regras em tempo de execução
sudo firewall-cmd --runtime-to-permanent
# Recarregar regras permanentes (descartar alterações em tempo de execução)
sudo firewall-cmd --reload
# Reinício completo
sudo firewall-cmd --complete-reload
Repor as predefinições
# Remover ficheiros de zona personalizados
sudo rm /etc/firewalld/zones/*
# Recarregar predefinições
sudo firewall-cmd --complete-reload
Resolução de problemas
Verificar logs
# Ver logs do firewalld
sudo journalctl -u firewalld
# Ver pacotes descartados (se o logging estiver ativado)
sudo journalctl -k | grep DROPPED
Testar conectividade
# A partir de outra máquina
nc -zv server-ip 80
nmap -p 22,80,443 server-ip
Principais conclusões
- Use zonas: Faça corresponder os níveis de confiança da rede às zonas
- Permanente + reload: Utilize sempre
--permanent e --reload - Restringir SSH: Mova o SSH para a zona trusted com origens específicas
- Rich rules para precisão: Filtragem baseada em IP e limitação de taxa
- Definições de serviços: Crie ficheiros de serviço reutilizáveis para aplicações
- Registar com cuidado: Ative o logging para pacotes descartados durante a depuração
O Firewalld disponibiliza um firewall robusto e fácil de gerir, que equilibra segurança com usabilidade — essencial para qualquer servidor Linux de produção.