Fail2Ban no Linux: bloqueie ataques de força bruta no SSH
O Fail2Ban monitora os logs de autenticação e bane automaticamente qualquer IP que errar o login SSH mais vezes do que o permitido em uma janela de tempo. Com maxretry = 5 e findtime = 15m, um scanner que tenta força bruta contra a porta 22 é bloqueado antes de completar um dicionário de senhas. Este guia mostra a instalação, a configuração correta do jail.local e os erros que mais anulam a proteção na prática.
Por que o Fail2Ban importa mesmo com autenticação por chave
Trocar senha por chave pública no SSH reduz o risco de login indevido, mas não impede que bots continuem batendo na porta 22 seguidamente, consumindo CPU, poluindo o log de autenticação e dificultando a identificação de um ataque real no meio do ruído. O Fail2Ban corta esse tráfego na origem: ele cria uma regra de firewall temporária para o IP infrator, então o pacote nem chega a acordar o daemon SSH.
Ele não substitui um firewall — complementa. O firewall define a política geral de portas liberadas; o Fail2Ban reage a comportamento, banindo dinamicamente quem viola essa política repetidamente.
Passo a passo: instalar e configurar
-
Instale o pacote. Em Debian e Ubuntu:
sudo apt update && sudo apt install fail2ban -y
Em RHEL, CentOS Stream e Rocky Linux:
sudo dnf install epel-release -y && sudo dnf install fail2ban -y
-
Nunca edite o
jail.conforiginal. Esse arquivo é sobrescrito a cada atualização do pacote — qualquer ajuste feito nele se perde no próximoapt upgrade. Crie um arquivo próprio, que o Fail2Ban sempre lê por cima do padrão:sudo nano /etc/fail2ban/jail.local
-
Defina os parâmetros globais e a jail do SSH. Cole o conteúdo abaixo, ajustando o IP da whitelist para o seu:
[DEFAULT] bantime = 30m findtime = 15m maxretry = 5 ignoreip = 127.0.0.1/8 ::1 SEU_IP_FIXO_AQUI backend = systemd [sshd] enabled = true port = ssh filter = sshd maxretry = 5
O
ignoreipé o que evita que você mesmo se tranque para fora do servidor depois de errar a senha em uma madrugada cansada — sempre inclua o IP fixo de onde você administra a máquina. -
Ative o ban progressivo para reincidentes. Um scanner que volta depois de cumprir o bloqueio de 30 minutos não deveria receber o mesmo tratamento leve de novo. Acrescente ao bloco
[DEFAULT]:bantime.increment = true bantime.factor = 4 bantime.maxtime = 1w
Cada reincidência multiplica o tempo de ban pelo fator definido, até o teto de uma semana — o custo de insistir cresce a cada tentativa.
-
Combine o
banactioncom o firewall que você realmente usa. Esse é o ajuste mais esquecido e o que mais faz o Fail2Ban parecer “não funcionar” quando na verdade está banindo em um backend que não bloqueia nada:# Servidor com UFW ativo banaction = ufw # Servidor com nftables (padrão em distros recentes) banaction = nftables-multiport # Servidor com iptables legado banaction = iptables-multiport
Confira qual firewall está de fato ativo antes de escolher —
ufw statusousudo nft list rulesetrespondem isso em segundos. -
Reinicie o serviço e confirme que ele subiu sem erro de sintaxe:
sudo systemctl enable --now fail2ban sudo systemctl status fail2ban
-
Verifique a jail e teste o bloqueio. Liste o status geral e o da jail do SSH:
sudo fail2ban-client status sudo fail2ban-client status sshd
Para confirmar que a regra de firewall é aplicada de verdade, force um ban manual e depois reverta:
sudo fail2ban-client set sshd banip 198.51.100.10 sudo fail2ban-client set sshd unbanip 198.51.100.10
Se o
banipnão aparecer na lista de regras do firewall (sudo nft list rulesetousudo iptables -L -n), obanactiondo passo 5 está errado para o seu ambiente — corrija antes de confiar na proteção.
Comandos essenciais do dia a dia
sudo fail2ban-client status sshd # IPs banidos agora e contadores sudo fail2ban-client set sshd unbanip IP # desbanir um IP específico sudo tail -f /var/log/fail2ban.log # acompanhar bans em tempo real sudo fail2ban-client reload # aplicar mudanças no jail.local sem derrubar bans ativos
Erros comuns que anulam a proteção
Logpath errado para a distro. Ubuntu e Debian gravam autenticação em /var/log/auth.log; RHEL e derivados usam o journal do systemd. Com backend = systemd no jail.local, o Fail2Ban lê o journal diretamente e esse problema some — é o motivo de o passo 3 já vir com esse backend definido.
Esquecer de reiniciar depois de editar. Alterações em jail.local só valem após systemctl restart fail2ban ou fail2ban-client reload.
Não colocar o próprio IP em ignoreip. Sem isso, uma sequência de senhas erradas do próprio administrador resulta em autobloqueio — e a única saída é acessar via console do provedor.
banaction descasado do firewall real. Já coberto no passo 5, mas vale repetir: é a causa mais comum de “instalei e não bloqueou nada”.
Perguntas frequentes
O Fail2Ban substitui um firewall completo?
Não. Ele cria e remove regras dinâmicas em cima do firewall existente (UFW, nftables ou iptables) — a política de portas liberadas continua sendo responsabilidade do firewall.
Fail2Ban ainda faz sentido se o SSH já usa só autenticação por chave?
Sim. Ele reduz o ruído de scanners no log, evita consumo desnecessário de CPU com handshakes SSH repetidos e cobre outros serviços expostos (painéis web, FTP, SMTP) que nem sempre suportam chave.
Como banir um IP permanentemente?
Defina bantime = -1 na jail correspondente. Use com cautela — reverter exige unbanip manual.
Uso nftables ou iptables?
Distros lançadas nos últimos anos (Debian 12+, Ubuntu 22.04+) já rodam nftables por baixo mesmo quando o comando iptables ainda funciona, via camada de compatibilidade. Confirme com sudo nft list ruleset antes de fixar o banaction.
O Fail2Ban protege contra ataques distribuídos com muitos IPs diferentes?
Só parcialmente — cada IP precisa acumular as tentativas configuradas antes de ser banido, então um ataque com milhares de IPs únicos dilui o limite. Nesses casos, combine com rate limiting na borda (firewall perimetral ou WAF) além do Fail2Ban local.
Conclusão
Fail2Ban resolve um problema específico e mensurável: tentativas repetidas de login contra serviços expostos. A instalação leva minutos, mas a proteção real depende de três ajustes que o padrão do pacote não cobre — ignoreip com o IP do administrador, banaction alinhado ao firewall em uso e bantime.increment para encarecer a insistência de bots. Configure, teste o ban manual do passo 7 e só então confie que a regra está ativa.