TL;DR — Resumo Rápido
Fail2Ban guia completo: instalação, jails SSH, banimento progressivo, filtros personalizados, proteção Nginx/Apache/e-mail e integração com Cloudflare no Linux.
Cada servidor Linux exposto à internet está sob ataque constante. Bots automatizados varrem todo o espaço de endereços IPv4 em horas, testando milhares de combinações de usuário e senha contra SSH e outros serviços. O Fail2Ban é um framework de prevenção de intrusões baseado em logs que detecta esses ataques em tempo real e instrui o firewall a bloquear os IPs ofensores — automaticamente, sem intervenção manual. Este guia cobre a configuração completa do Fail2Ban: instalação, configuração de jails SSH, banimento progressivo, criação de filtros personalizados, proteção para Nginx, Apache e servidores de e-mail, e integração com a API do Cloudflare.
Pré-requisitos
Antes de começar, certifique-se de ter:
- Um servidor Linux rodando Ubuntu 20.04/22.04/24.04, Debian 11/12 ou RHEL/Rocky/AlmaLinux 8/9
- Acesso root ou sudo
- Acesso SSH ao servidor
- iptables, nftables ou firewalld gerenciando seu firewall
- Familiaridade básica com gerenciamento de serviços systemd
Como o Fail2Ban Funciona
O Fail2Ban opera em um ciclo monitorar → combinar → banir:
- Monitoramento de logs — O daemon
logtargetdo Fail2Ban monitora arquivos de log (por exemplo,/var/log/auth.log,/var/log/nginx/error.log) usando inotify ou polling. - Correspondência de regex — Cada jail referencia um filtro contendo um ou mais padrões
failregex. Quando uma linha de log corresponde, o Fail2Ban incrementa um contador de falhas para o IP de origem. - Verificação de limiar — Quando o contador atinge
maxretrydentro da janelafindtime, o IP é considerado hostil. - Banimento no firewall — O Fail2Ban chama uma ação (normalmente iptables, nftables ou firewalld) para inserir uma regra DROP para o IP ofensor. A regra é removida automaticamente após
bantimesegundos.
Instalação
Ubuntu / Debian
sudo apt update
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban
RHEL / Rocky / AlmaLinux
O repositório EPEL é necessário:
sudo dnf install epel-release -y
sudo dnf install fail2ban -y
sudo systemctl enable --now fail2ban
Em sistemas da família RHEL, o firewalld é o backend padrão:
sudo dnf install fail2ban-firewalld -y
Configuração do Jail SSH
Nunca edite /etc/fail2ban/jail.conf diretamente — ele é sobrescrito em atualizações de pacotes. Em vez disso, crie suas substituições em /etc/fail2ban/jail.local:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Um jail SSH completo e pronto para produção:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
backend = systemd
maxretry = 4
findtime = 1h
bantime = 24h
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
Parâmetros-chave explicados:
| Parâmetro | Valor | Significado |
|---|---|---|
maxretry | 4 | Tentativas falhas antes do banimento |
findtime | 1h | Janela para contar falhas |
bantime | 24h | Duração do banimento do IP |
ignoreip | Lista CIDR | IPs que nunca são banidos |
backend | systemd | Ler logs do journald |
Aviso: Sempre adicione seu próprio IP ou sub-rede de gerenciamento ao
ignoreipantes de habilitar jails rigorosos. Ficar bloqueado em uma VM na nuvem requer acesso ao console para recuperação.
Banimento Progressivo
Adicione estas configurações ao [DEFAULT] no jail.local:
[DEFAULT]
bantime.increment = true
bantime.multipliers = 1 5 30 60 300 720 1440 2880
bantime.maxtime = 5w
bantime.overalljails = true
Com a sequência de multiplicadores 1 5 30 60 300 720 1440 2880 e bantime base de 10 minutos:
- 1º banimento: 10 minutos
- 2º banimento: 50 minutos
- 3º banimento: 5 horas
- 4º banimento: 10 horas
- 5º banimento: ~2 dias
Criação de Filtros Personalizados
Filtros ficam em /etc/fail2ban/filter.d/. Exemplo para uma API Node.js que registra:
2026-03-22 14:05:33 [AUTH FAIL] 203.0.113.42 - Invalid token on /api/v1/login
Crie /etc/fail2ban/filter.d/myapp-auth.conf:
[Definition]
failregex = ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} \[AUTH FAIL\] <HOST> -
ignoreregex =
Teste sua regex antes de ativar:
sudo fail2ban-regex /var/log/myapp/app.log /etc/fail2ban/filter.d/myapp-auth.conf
Proteção do Nginx
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 1h
[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 24h
[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 10
bantime = 10m
Jails para Apache e Servidor de E-mail
Apache
[apache-auth]
enabled = true
port = http,https
logpath = /var/log/apache2/error.log
maxretry = 3
[apache-badbots]
enabled = true
port = http,https
logpath = /var/log/apache2/access.log
bantime = 48h
Postfix / Dovecot
[postfix]
enabled = true
port = smtp,465,submission
logpath = /var/log/mail.log
maxretry = 3
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps,submission,465,sieve
logpath = /var/log/mail.log
maxretry = 3
bantime = 12h
Gerenciando Banimentos com fail2ban-client
# Mostrar todos os jails ativos
sudo fail2ban-client status
# Mostrar IPs banidos em um jail específico
sudo fail2ban-client status sshd
# Banir manualmente um IP
sudo fail2ban-client set sshd banip 203.0.113.42
# Desbanir um IP
sudo fail2ban-client set sshd unbanip 203.0.113.42
# Recarregar configuração sem reiniciar
sudo fail2ban-client reload
# Ver todos os IPs banidos em todos os jails
sudo fail2ban-client banned
Configuração de Ações
[DEFAULT]
# iptables (clássico, mais compatível)
banaction = iptables-multiport
# nftables (recomendado para distros modernas)
banaction = nftables-multiport
# firewalld (RHEL/Rocky)
banaction = firewallcmd-ipset
# Enviar notificação por e-mail ao banir
action = %(action_mwl)s
Testando Filtros com fail2ban-regex
# Testar contra um arquivo de log
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# Testar com uma linha de log específica
sudo fail2ban-regex "Mar 22 14:05:33 server sshd[12345]: Failed password for root from 203.0.113.42 port 54321 ssh2" sshd
Integração com Cloudflare
Opção 1 — Restaurar IPs reais via cabeçalho CF-Connecting-IP:
set_real_ip_from 103.21.244.0/22;
real_ip_header CF-Connecting-IP;
Opção 2 — Banir na borda do Cloudflare usando a ação cloudflare:
[DEFAULT]
cftoken = SEU_TOKEN_API_CLOUDFLARE
cfzoneid = SEU_ZONE_ID
[nginx-botsearch]
enabled = true
action = %(action_)s
cloudflare[cftoken="%(cftoken)s", cfzoneid="%(cfzoneid)s"]
Fail2Ban vs Alternativas
| Ferramenta | Mecanismo | Linguagem | Escopo | Comunidade |
|---|---|---|---|---|
| Fail2Ban | Regex de logs + firewall local | Python | Servidor local | Não |
| CrowdSec | Análise comportamental + listas compartilhadas | Go | Multi-servidor | Sim |
| DenyHosts | Apenas /etc/hosts.deny SSH | Python | Somente SSH | Opcional |
| SSHGuard | Daemon C, multi-backend | C | Serviços limitados | Não |
Dicas de Hardening em Produção
- Altere a porta SSH do 22 para uma não padrão para reduzir o ruído de varredura automatizada
- Defina
bantimepara pelo menos 24h para SSH - Monitore o log do Fail2Ban em
/var/log/fail2ban.log - Faça backup de
/var/lib/fail2ban/fail2ban.sqlite3para preservar o histórico de banimentos - Combine com limitação de velocidade do UFW (
sudo ufw limit ssh) para defesa em profundidade - Audite sua lista
ignoreipperiodicamente
Resumo
O Fail2Ban fornece proteção robusta e automatizada contra força bruta para qualquer servidor Linux que exponha serviços à internet. Principais conclusões:
- O Fail2Ban monitora logs, combina padrões de falha com regex e adiciona regras de firewall para bloquear IPs ofensores
- Nunca edite
jail.conf— usejail.localou arquivos drop-in emjail.d/ - Sempre configure
ignoreipcom seu próprio IP antes de habilitar jails rigorosos - O banimento progressivo (
bantime.increment) torna atacantes persistentes efetivamente permanentes - Use
fail2ban-regexpara testar e validar padrões de filtros antes da implantação