Instalar Fail2ban no Ubuntu 24.04 e bloquear bots SSH
No Ubuntu 24.04, apt install ja bloqueia brute force SSH. Veja fail2ban-client status sshd e corrija o caso em que Total failed fica em 0.
O que o Fail2ban faz de facto
O Fail2ban é um daemon que lê logs. Monitoriza as mensagens de autenticação do SSH e, depois de várias falhas provenientes de um endereço no espaço de tempo definido, executa um comando da firewall que bloqueia esse endereço durante algum tempo. Essa é a ideia completa. A configuração ocupa cerca de 30 linhas num ficheiro, e no Ubuntu 24.04 a instalação é feita com um único comando apt, que deixa o sistema protegido antes de alterar qualquer configuração.
É importante compreender o que ele é e o que não é. O Fail2ban não autentica utilizadores, não cifra dados e não impede uma única tentativa de início de sessão determinada; apenas bloqueia tentativas repetidas provenientes da mesma origem. É um filtro de ruído e um limitador de taxa, não um bloqueio absoluto. A função é impedir que a análise contínua da porta 22 em segundo plano consuma CPU, largura de banda e espaço nos logs, além de atrasar qualquer atacante que tenha de utilizar um endereço de cada vez.
O que o Fail2ban não substitui
O Fail2ban é a terceira camada, não a primeira. Se o seu servidor ainda aceitar palavras-passe por SSH, uma botnet distribuída por milhares de endereços pode continuar a tentar autenticar-se, porque cada endereço permanece abaixo do limite de bloqueio e nunca o atinge. A defesa real contra isso é a autenticação apenas por chave, que torna impossível adivinhar palavras-passe, independentemente do número de tentativas. O Fail2ban, sobre a autenticação apenas por chave, cumpre duas funções úteis: reduz o ruído de brute force nos logs e expulsa os scanners logo no início, para que deixem de bombardear a porta. Considere-o uma medida de defesa em profundidade. Fica atrás da autenticação por chave e da firewall, nunca à frente delas.
Pré-requisitos e a realidade do Ubuntu 24.04
Precisa de um VPS com Ubuntu 24.04, acesso root ou sudo e SSH já a funcionar, de preferência com autenticação por chave. O Fail2ban consome poucos recursos: algumas dezenas de megabytes de RAM, sem necessidade de ajustar limites.
Agora, a parte em que todos os guias antigos erram. Durante anos, a recomendação padrão foi "instale o Fail2ban e depois adicione backend = systemd, porque o Ubuntu deixou de escrever em /var/log/auth.log." Essa recomendação descreve uma alteração real: as imagens modernas de servidores e da cloud são disponibilizadas sem rsyslog, pelo que os logs do SSH são escritos apenas no journal do systemd e esse ficheiro de texto deixou de existir. No Ubuntu 24.04, porém, o pacote do Fail2ban já trata desse caso. O pacote instala /etc/fail2ban/jail.d/defaults-debian.conf e é esse ficheiro, não os padrões upstream, que o servidor realmente utiliza:
[DEFAULT]
banaction = nftables
banaction_allports = nftables[type=allports]
backend = systemd
[sshd]
enabled = trueLeia isto com atenção, porque esclarece duas questões antes de alterar qualquer configuração. backend = systemd significa que a jail do SSH lê o journal, pelo que a ausência de auth.log não é relevante. banaction = nftables significa que os bans são aplicados através do nftables, que é a firewall realmente utilizada pelo Ubuntu 24.04, em vez do iptables legado. E [sshd] enabled = true significa que a jail fica ativa desde o primeiro boot. Em resumo: uma instalação padrão de apt install fail2ban no Ubuntu 24.04 bloqueia tentativas de brute force contra o SSH imediatamente. A maior parte do trabalho consiste em confirmar esse comportamento, ajustar a política e garantir que não perde o acesso ao servidor.
A armadilha antiga de auth.log ainda ocorre em três situações, que convém reconhecer: instalou o Fail2ban com pip em vez de apt, pelo que não existe defaults-debian.conf; está dentro de um contentor sem privilégios e sem um journal do systemd para consultar; ou seguiu um tutorial antigo e colou backend = auto no seu próprio jail.local, substituindo a configuração padrão funcional. A secção sobre modos de falha mostra exatamente o aspeto de cada caso.
Passo 1: Instale e confirme que o bloqueio já está ativo
sudo apt update
sudo apt install -y fail2banO Ubuntu 24.04 inclui o Fail2ban 1.0.2, e o pacote instala python3-systemd como dependência obrigatória. Por isso, o backend do journal já tem tudo de que precisa. O serviço é ativado e iniciado automaticamente:
sudo systemctl status fail2banO resultado esperado é active (running). Em seguida, consulte a jail que já está a funcionar:
sudo fail2ban-client status sshdNum VPS público que esteja acessível há apenas alguns minutos, é comum já ver falhas contabilizadas e endereços bloqueados. A Internet verifica continuamente a porta 22. Isso prova que a configuração padrão funciona. A partir daqui, irá aperfeiçoá-la, não criá-la do zero.
Passo 2: Edite jail.local, nunca jail.conf
O Fail2ban mantém os valores predefinidos originais em /etc/fail2ban/jail.conf. Não edite esse ficheiro. Cada apt upgrade do pacote pode substituí-lo, e as suas alterações desaparecem sem aviso. O Fail2ban lê os ficheiros por uma ordem fixa: primeiro jail.conf, depois tudo o que estiver em jail.d/ e, por fim, jail.local. Prevalece o último valor. O ficheiro .local é seu, e as atualizações do pacote nunca o alteram. A mesma regra aplica-se aos filtros: um ficheiro *.local substitui o filter.d/*.conf fornecido pelo pacote.
Por isso, crie um pequeno jail.local que substitua apenas as poucas definições de que precisa e deixe jail.conf e jail.d/defaults-debian.conf fornecidos pelo pacote intactos, como referência.
Passo 3: Escreva /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.localInsira este conteúdo e altere o endereço na linha ignoreip para o seu próprio IP público:
[DEFAULT]
# Ubuntu 24.04 already sets these two in jail.d/defaults-debian.conf.
# Pinning them here documents the dependency and survives if that
# file is ever removed or changed by an upgrade.
backend = systemd
banaction = nftables
# Ban for one hour ...
bantime = 1h
# ... if an address fails ...
maxretry = 5
# ... 5 times within 10 minutes.
findtime = 10m
# Never ban these. PUT YOUR OWN IP HERE.
ignoreip = 127.0.0.1/8 ::1 10.0.0.24
# Longer bans for repeat offenders: 1h, 2h, 4h ... up to a week.
bantime.increment = true
bantime.maxtime = 1w
[sshd]
enabled = trueCada linha tem uma função:
bantime,findtimeemaxretrydefinem a política. O valor predefinido fornecido embantimeé de apenas dez minutos; uma hora é um limite mínimo mais adequado. Cinco falhas do mesmo endereço no período de dez minutos resultam num bloqueio. Pessoas reais introduzem uma palavra-passe incorreta uma ou duas vezes; cinco falhas em dez minutos indicam um script.ignoreipé a sua proteção contra bloqueios acidentais. Insira aqui o endereço público a partir do qual estabelece a ligação, para que o Fail2ban nunca possa bloquear o acesso ao seu próprio servidor. Uma ligação doméstica com IP variável é um motivo para preferir a abordagem com VPN apresentada no final, não para omitir esta linha.bantime.increment = truefaz com que cada bloqueio repetido dure mais tempo do que o anterior: uma hora, depois duas, depois quatro, atébantime.maxtime. Os endereços que continuam a voltar ficam progressivamente bloqueados durante mais tempo.
Obtenha o endereço a colocar na lista de permissões a partir da máquina a partir da qual estabelece a ligação SSH, não a partir do servidor:
curl -s ifconfig.mePode gerar aqui um jail.local ajustado às suas portas e à política de bloqueio e, depois, inseri-lo no ficheiro:
Etapa 4: Reinicie e verifique se está a ler o journal
sudo fail2ban-client -t
sudo systemctl restart fail2ban
sudo fail2ban-client status sshdO -t executa primeiro um teste da configuração. Assim, um erro de sintaxe em jail.local é identificado imediatamente, em vez de deixar o serviço parado. Um estado saudável da jail é semelhante a este:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 14
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 3
`- Banned IP list: 10.0.0.66O número que comprova que o Fail2ban está efetivamente a ler os seus logins é Total failed. Se for superior a zero ou aumentar quando falhar deliberadamente um login a partir de outra máquina, o journal está a ser lido e terminou. Se permanecer em 0 independentemente do número de tentativas falhadas, e tiver a certeza de que não está a testar a partir do endereço em ignoreip, consulte as causas de falha abaixo.
Repare que a linha Journal matches ainda identifica sshd.service. No Ubuntu, a unidade SSH é efetivamente ssh.service, mas o filtro fornecido também corresponde a _COMM=sshd. Além disso, o OpenSSH em 24.04 regista as falhas a partir de um processo com o nome sshd, pelo que a correspondência funciona. Este detalhe só é relevante se estiver a utilizar uma versão mais recente do OpenSSH (9.8 ou posterior, em que o worker por ligação é sshd-session); as causas de falha abrangem esse caso.
Etapa 5: Monitorize um banimento real ou force um para testar
Os banimentos reais surgem sozinhos em poucos minutos em qualquer VPS pública. Para monitorizar um, acompanhe o log:
sudo tail -f /var/log/fail2ban.logUm banimento tem este aspeto:
2026-07-15 10:31:40,502 fail2ban.filter [812]: INFO [sshd] Found 10.0.0.66 - 2026-07-15 10:31:40
2026-07-15 10:31:44,118 fail2ban.actions [812]: NOTICE [sshd] Ban 10.0.0.66Para testar todo o processo sem esperar, banir manualmente um endereço de documentação, nunca o seu próprio:
sudo fail2ban-client set sshd banip 10.0.0.66O comando apresenta 1, e o endereço aparece em Banned IP list dentro de fail2ban-client status sshd. Agora confirme que o bloqueio existe efetivamente no firewall. No Ubuntu 24.04, trata-se de nftables, não de iptables:
sudo nft list table inet f2b-tableVerá um conjunto chamado addr-set-sshd que contém 10.0.0.66 e uma cadeia f2b-chain que rejeita qualquer origem desse conjunto. Se fail2ban-client indicar que um endereço foi banido, mas nada aparecer em nft list, a ação de banimento não corresponde ao seu firewall. Consulte a nota sobre nftables/iptables na secção de modos de falha.
Passo 6: Remova o seu próprio banimento e recupere o acesso se ficar bloqueado
Se baniu um endereço que não devia, incluindo o seu próprio, remova-o:
sudo fail2ban-client set sshd unbanip 10.0.0.66O comando devolve 1 em caso de sucesso. Para limpar todos os banimentos em todas as jails:
sudo fail2ban-client unban --allNão conte com uma sessão SSH já aberta para o salvar: o banimento do nftables rejeita todos os pacotes do endereço banido para a porta 22, incluindo os das ligações estabelecidas. Por isso, uma sessão existente bloqueia no momento em que o banimento é aplicado. Se se banir e não tiver uma entrada ignoreip, ficará sem acesso até o banimento expirar. Recupere o acesso através da consola web do seu fornecedor (VNC ou serial), que não usa SSH, e aguarde bantime ou execute aí o comando para remover o banimento.
Passo 7: Faça as proibições persistirem e aumentarem
O Fail2ban mantém as proibições ativas numa pequena base de dados SQLite em /var/lib/fail2ban/fail2ban.sqlite3, para que sobrevivam ao reinício do serviço ou a um reboot; não as perde. As linhas bantime.increment que adicionou anteriormente transformam cada infrator reincidente num problema cada vez maior para si próprio, aumentando aproximadamente para o dobro, de uma hora até cerca de uma semana.
Para aplicar uma política global de "três infrações", o Fail2ban inclui uma jail recidive que monitoriza o seu próprio /var/log/fail2ban.log e aplica proibições longas a qualquer endereço que tenha sido proibido repetidamente em várias jails. Como o seu [DEFAULT] agora usa o backend systemd, fixe esta jail novamente no ficheiro de log que foi concebida para ler:
[recidive]
enabled = true
backend = auto
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 5backend = auto com o logpath explícito mantém recidive a ler o fail2ban.log simples. É nesse ficheiro que aparecem efetivamente as linhas Ban contabilizadas. O valor predefinido do systemd que definiu globalmente apontaria para o journal, onde essas linhas não aparecem.
Passo 8: Combine com SSH baseado apenas em chaves e, melhor ainda, com uma VPN
O Fail2ban só é realmente eficaz quando usado com autenticação por chave. Num ficheiro de configuração complementar em /etc/ssh/sshd_config.d/, por exemplo /etc/ssh/sshd_config.d/00-hardening.conf, defina:
PasswordAuthentication no
KbdInteractiveAuthentication noDepois, sudo systemctl restart ssh. Com as palavras-passe desativadas, a força bruta não pode ter sucesso; o Fail2ban serve então para reduzir o ruído nos logs e bloquear os scanners logo no início. Mais seguro ainda é manter o SSH completamente fora da Internet pública: coloque o SSH atrás de uma VPN WireGuard autoalojada e configure a firewall para que a porta 22 responda apenas através do túnel. Ninguém pode fazer força bruta contra uma porta à qual não consegue chegar, e o Fail2ban passa a ser uma proteção secundária, não a primeira linha de defesa.
O Fail2ban não serve apenas para SSH. Qualquer serviço que registe tentativas de início de sessão falhadas pode ter uma jail: um servidor de correio, um site nginx ou um gestor de palavras-passe Vaultwarden autoalojado, cujo início de sessão web talvez não queira deixar exposto a tentativas automatizadas de credenciais. Depois de uma aplicação web ficar atrás de um site nginx com um certificado Let's Encrypt, aponte um filtro do Fail2ban para o respetivo access log, tal como a jail do SSH aponta para o journal.
Modos de falha, com as strings exatas que verá
"Have not found any log file for sshd jail", e o Fail2ban não inicia. Este é o problema antigo de auth.log. No Ubuntu 24.04, só ocorre se algo tiver substituído o valor predefinido do pacote, numa instalação de pip sem defaults-debian.conf, num contentor sem journal ou devido a um backend = auto isolado que tenha sido colado em jail.local. Num backend baseado em ficheiros sem /var/log/auth.log, a jail sshd não encontra o log e todo o daemon termina. fail2ban.log mostra:
ERROR Failed during configuration: Have not found any log file for sshd jailComo este erro é fatal, o serviço não inicia. Em seguida, fail2ban-client status apresenta o sintoma resultante:
ERROR Failed to access socket path: /var/run/fail2ban/fail2ban.sock. Is fail2ban running?A linha "socket path" não significa que o Fail2ban esteja avariado. Significa que ele não iniciou porque uma jail não encontrou o respetivo log. Definir backend = systemd em [DEFAULT], algo que o pacote do Ubuntu já faz por si, corrige as duas mensagens de uma vez.
A jail está ativa, mas Total failed nunca avança. O daemon está em execução e o journal está a ser lido, mas as falhas reais acumulam-se em journalctl -u ssh enquanto o contador permanece em 0. Primeiro, exclua a causa mais óbvia: está a testar a partir de um endereço listado em ignoreip, pelo que as suas próprias falhas são excluídas por definição. Se não for esse o caso, está a usar uma compilação do OpenSSH em que o worker por ligação está sshd-session (9.8 e posterior). O respetivo journal _COMM é sshd-session, não sshd, pelo que a correspondência fornecida não o deteta. Alargue a correspondência no bloco [sshd]:
[sshd]
enabled = true
backend = systemd
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd + _COMM=sshd-sessionReinicie, provoque uma falha de início de sessão a partir de um endereço que não esteja em ignoreip e confirme que Total failed começa finalmente a aumentar.
Bloqueou o seu próprio acesso: Connection refused. Não incluiu o seu próprio endereço em ignoreip, testou alguns inícios de sessão inválidos e agora:
ssh: connect to host 10.0.0.10 port 22: Connection refusedA recusa, em vez de um timeout silencioso, é o veredito reject predefinido da ação nftables a funcionar contra si. Corrija a situação como no Passo 6: retire o bloqueio a partir de uma sessão num endereço diferente e não bloqueado ou através da consola do fornecedor. Uma sessão já aberta a partir do endereço bloqueado também fica congelada. Depois, adicione o seu endereço a ignoreip para evitar que isto volte a acontecer.
O Fail2ban indica que um endereço está bloqueado, mas ele continua a conseguir ligar-se. O contador em status sshd aumenta, mas o endereço continua a chegar à porta 22. Isto indica uma incompatibilidade entre a ação de bloqueio e a firewall. No Ubuntu 24.04, quase sempre significa que substituiu o banaction = nftables funcional por banaction = iptables-multiport, copiado de um guia antigo, num sistema sem uma camada iptables. fail2ban.log mostra:
fail2ban.actions [812]: ERROR Failed to execute ban jail 'sshd' action 'iptables-multiport'Elimine essa substituição e deixe a ação nftables fornecida pelo pacote em vigor. Em alternativa, se gerir toda a firewall através do ufw e quiser que os bloqueios também apareçam aí, defina banaction = ufw em [DEFAULT]. Reinicie e confirme que a regra aparece com sudo nft list ruleset | grep f2b.
O Fail2ban não inicia depois de editar jail.local. Um erro de digitação, um cabeçalho isolado ou um valor de tempo inválido pode fazer com que o serviço recuse iniciar. Peça ao Fail2ban para verificar a configuração antes de o executar:
sudo fail2ban-client -tO comando indica o ficheiro e a jail com o problema, por exemplo Errors in jail 'sshd'. Skipping.... Assim, corrige a origem em vez de tentar adivinhar.
FAQ
A instalação padrão do Fail2ban no Ubuntu 24.04 bloqueia realmente ataques SSH?
Sim. O pacote inclui /etc/fail2ban/jail.d/defaults-debian.conf, que ativa a jail sshd, define backend = systemd para ler o journal do systemd em vez do /var/log/auth.log ausente e define banaction = nftables para que os bloqueios sejam aplicados através da firewall real do Ubuntu. Um apt install fail2ban simples protege o SSH desde o primeiro boot. Confirme com sudo fail2ban-client status sshd e procure um valor não nulo em Total failed.
Por que o Fail2ban não bloqueia nada no meu servidor?
Exclua as três causas comuns pela ordem. Pode estar a testar a partir de um endereço em ignoreip, que está isento por definição. Pode ter substituído a configuração padrão funcional ao colar backend = auto em jail.local a partir de um guia antigo, o que impede a leitura do journal numa imagem sem auth.log. Ou pode estar dentro de um contentor sem qualquer journal do systemd para ler. Verifique Total failed em fail2ban-client status sshd: se nunca aumentar enquanto journalctl -u ssh mostra falhas reais, a jail está a ler o local errado.
Como removo o bloqueio do meu próprio endereço IP?
Execute sudo fail2ban-client set sshd unbanip YOUR.IP.HERE, que devolve 1 em caso de sucesso, ou sudo fail2ban-client unban --all para limpar todos os bloqueios. Se perdeu o acesso SSH, use a consola web ou VNC do seu fornecedor para executar o mesmo comando. O bloqueio rejeita todos os pacotes do seu endereço para a porta 22, pelo que até uma sessão já aberta deixa de funcionar. Depois, adicione o seu endereço a ignoreip para impedir que isto volte a acontecer.
Qual é a diferença entre jail.conf e jail.local?
jail.conf contém os padrões fornecidos pelo projeto Fail2ban e é substituído em cada atualização do pacote, pelo que qualquer alteração acaba por ser perdida. O pacote Debian/Ubuntu aplica as suas próprias definições através de jail.d/defaults-debian.conf. As suas alterações devem ficar em jail.local, que é lido por último e tem precedência sobre os dois ficheiros, além de nunca ser alterado pelas atualizações. Mantenha jail.conf apenas como referência de leitura.
O Fail2ban substitui a autenticação SSH baseada em chaves?
Não. O Fail2ban limita a frequência de falhas repetidas provenientes de um endereço. Não impede uma tentativa lenta e distribuída em que cada endereço permanece abaixo do limite. A autenticação apenas com chaves (PasswordAuthentication no) torna impossível adivinhar palavras-passe, e o Fail2ban reduz o ruído nos logs e remove os scanners mais cedo. Use ambos e, idealmente, mantenha o SSH completamente fora da Internet pública.