Fail2Ban não é mais necessário? Analisando PerSourcePenalties no OpenSSH do Ubuntu 26.04
Desde o OpenSSH 9.7, o sshd tem a capacidade de restringir automaticamente endereços IP suspeitos por um período de tempo, sem a necessidade de Fail2Ban ou iptables. No Ubuntu 26.04, essa funcionalidade já está ativada por padrão, mesmo que não haja menção dela no sshd_config. Vamos analisar como isso funciona.
Disclaimer
Este artigo foi escrito sem o uso de IA. A inteligência artificial foi utilizada apenas para revisão estilística. Não estou promovendo nada e não estou convidando para chats no Telegram. Não estou vendendo uma garagem.
Como você sabe, a nova versão LTS do Ubuntu 26.04 - Resolute Raccoon - foi lançada no mês passado. Lendo as notas de lançamento (sim, existem muitas pessoas que as leem), encontrei o seguinte ponto interessante na seção sobre OpenSSH: a nova diretiva PerSourcePenalties irá "punir" endereços de clientes que, por algum motivo, não concluem a autenticação.
Na verdade, a funcionalidade não é nova. Os desenvolvedores do OpenSSH a adicionaram em 2024 (lista de discussão) e a ativaram por padrão na versão 9.7, mas essa versão não chegou ao Ubuntu 24.04.
Verificando a versão máxima disponível para atualização no Ubuntu 24.04
No Ubuntu 26.04, o OpenSSH versão 10.2p1 de 27 de janeiro de 2026 vem "pronto para uso". Portanto, tudo está ativado por padrão agora. Instalei uma imagem oficial, fui verificar as configurações e... não há nada nelas! Acontece que a funcionalidade existe e está ativada, mas não há uma única palavra sobre isso na configuração. E se você não leu as notas de lançamento, nem sabe que a tem.
No Ubuntu 26.04, você pode verificar se está ativado com o comando:
bashsshd -T | grep -i persource
Verificando se está ativado.
Estamos interessados na linha:
persourcepenalties crash:90 authfail:5 noauth:1 grace-exceeded:10 refuseconnection:10 max:600 min:15 max-sources4:65536 max-sources6:65536 overflow:permissive overflow6:permissive
Parâmetros da nova diretiva
Vamos analisar cada parâmetro em ordem.
Penalidades básicas (em segundos)
- crash:90 - a penalidade mais severa. Atribuída se o cliente causar uma falha ou término anormal do processo sshd. Esta é uma proteção contra potenciais exploits e clientes instáveis.
- authfail:5 - autenticação malsucedida (senha incorreta, chave, método, etc.). Força bruta clássica. Cada falha adiciona 5 segundos de penalidade.
- noauth:1 - o cliente se conectou, não tomou nenhuma ação de autenticação e desconectou. Comportamento típico de scanners e "ruído" da internet.
- grace-exceeded:10 - o cliente não conseguiu se autenticar dentro do tempo LoginGraceTime (120 segundos por padrão). Adiciona 10 segundos de penalidade.
- refuseconnection:10 - o servidor recusou a conexão (por exemplo, devido ao excesso de MaxStartups). Também 10 segundos.
Limiares de disparo
- min:15 - a penalidade acumulada mínima na qual o IP começa a ser bloqueado. Enquanto a soma das penalidades for inferior a 15 segundos, as conexões serão aceitas normalmente. Isso protege contra erros únicos acidentais.
- max:600 - a penalidade máxima (10 minutos). Mesmo que o cliente "acumule" mais, a penalidade não excederá esse valor.
Restrições no número de fontes rastreadas
- max-sources4:65536 - o número máximo de endereços IPv4 que o sshd rastreia simultaneamente.
- max-sources6:65536 - o mesmo para IPv6.
Os valores padrão são muito altos - essencialmente, "rastrear todos".
Comportamento em caso de estouro da tabela
- overflow:permissive
- overflow6:permissive
Quando o número de fontes rastreadas excede o limite, o servidor muda para o modo "suave": para de adicionar novos IPs à tabela de penalidades, mas não os bloqueia. Isso evita um ataque DoS ao próprio mecanismo de proteção. A eficácia do mecanismo é significativamente reduzida.
PerSourcePenalties não substitui o Fail2Ban. Ao contrário dele, o mecanismo não bane o IP completamente, mas temporariamente retarda ou bloqueia as conexões proporcionalmente ao grau de "culpabilidade" da fonte (se o buffer não estiver cheio).
Como o PerSourcePenalties funciona
A recusa de conexão é iniciada pelo próprio processo sshd (no nível do aplicativo), e não por meio de regras de firewall (iptables/nftables).
O mecanismo funciona da seguinte forma:
- Aceitação da conexão: o processo principal sshd aceita a conexão TCP de entrada (executa accept()).
- Verificação da tabela: imediatamente após aceitar a conexão, o sshd verifica o endereço IP do cliente em sua tabela interna de penalidades. PerSourcePenalties armazena o estado na memória interna do processo mestre sshd, portanto, não há uma maneira padrão de ver o conteúdo atual da tabela.
- Desconexão imediata: se a penalidade acumulada para este IP exceder o limite definido, o sshd simplesmente fecha o socket, sem iniciar um processo filho para autenticação.
Por que isso foi feito dessa forma?
- Autonomia. A funcionalidade está disponível "pronta para uso" em qualquer sistema operacional (Linux, BSD, macOS) sem a necessidade de ter direitos de root para modificar as regras de filtragem de pacotes.
- Segurança. Como o processo principal sshd agora não executa a lógica complexa de análise de dados do cliente (um sshd-session separado faz isso), a verificação rápida do IP na lista de penalidades quase não consome recursos e protege contra sobrecarga.
- Falta de integração com o kernel. Ao contrário do Fail2Ban, o OpenSSH não chama comandos externos como iptables -A.... Isso é mais rápido e elimina o risco de que um erro no script bloqueie o acesso a todo o servidor.
Observação importante. PerSourcePenalties funciona por IP. Isso significa que escritórios, VPNs, operadoras de telefonia móvel, CGNAT podem acidentalmente "punir" um grupo inteiro de usuários de uma vez.
Seção "e-e-experimentos"
Vamos testar como isso funciona na prática. Tentarei me conectar com uma senha incorreta várias vezes seguidas e observarei os logs:
(IP ocultado para não chamar a atenção)
(script-kiddie)
Aliás, isso não é visível no log normal. Tive que adicionar a configuração LogLevel VERBOSE ao arquivo /etc/ssh/sshd_config.
Com as configurações padrão, não notei o funcionamento desse recurso quando tentei fazer força bruta manualmente. Ou seja, pode-se concluir que o próprio usuário não se bloqueará ao inserir sua senha incorretamente (Lembre-se que o login por senha não é a melhor ideia. Configure chaves e trabalhe com elas).
Mas ninguém faz isso manualmente, então vamos automatizar. Executei o Hydra com os valores padrão e com rockyou:
Vamos olhar os logs no terminal da "vítima":
Na primeira etapa, o Hydra criou um grande número de conexões sem tentar a autenticação. Por isso, o IP recebeu a penalidade mínima:
srclimit_penalise: ipv4: new x.x.x.11/32 deferred penalty of 1 seconds
- esta é a penalidade noauth (1 segundo)
for penalty: connections without attempting authentication
Em seguida, o servidor começou a descartar conexões redundantes pelo limite MaxStartups.
Então, quando as conexões chegaram ao estágio de inserção da senha, as penalidades por falha na autenticação começaram a se acumular. O momento crítico chegou quando a penalidade acumulada excedeu o limite:
srclimit_penalise: x.x.x.11/32: activating ipv4 penalty of 19 seconds
- penalidade acumulada
Depois disso, todas as novas conexões desse IP começaram a ser descartadas com a mensagem
drop connection ... penalty: failed authentication.
Um detalhe importante: Do ponto de vista do atacante, isso se parece com "Connection closed by remote host" imediatamente após o estabelecimento da sessão TCP.
Comparação com Fail2Ban: quando usar o quê
Muitos administradores lembram imediatamente do Fail2Ban quando se trata de proteger o SSH. Vamos comparar as duas abordagens.
| Parâmetro | PerSourcePenalties (OpenSSH) | Fail2Ban |
|---|---|---|
| Local de trabalho | Embutido no sshd | Demônio externo, analisa logs |
| Velocidade de reação | Imediata (no momento do evento) | Atraso (depende da frequência de verificação dos logs) |
| Tipo de bloqueio | Temporário, dinâmico (segundos - dezenas de minutos) | Geralmente rígido e longo (minutos - dias) |
| Intensidade de recursos | Muito baixa | Média e superior (monitoramento constante de logs) |
| Flexibilidade de penalidades | Alta (penalidades diferentes para diferentes violações) | Alta, mas requer a escrita de filtros |
| Proteção contra DoS na própria proteção | Sim (overflow:permissive) | Depende da configuração |
| Proibições permanentes | Impossível | Fácil e familiar |
Se você olhar para os prós de ambas as abordagens, aqui está o que pode ser destacado.
Vantagens do PerSourcePenalties
- Funciona pronto para uso e está ativado por padrão no Ubuntu 26.04.
- Não requer análise de logs - a reação é mais rápida e confiável.
- Significativamente menos falsos positivos em usuários legítimos (especialmente aqueles que digitam a senha incorretamente por engano).
- Resistente a ataques ao próprio mecanismo de proteção.
- Consumo mínimo de recursos.
Vantagens do Fail2Ban
- Uma ferramenta mais familiar e "visível".
- Você pode banir para sempre ou por um período muito longo.
- Funciona com quaisquer serviços.
- Integra-se facilmente com iptables/nftables, bots Fail2Ban no Telegram, Cloudflare, etc.
- Um rico ecossistema de jail's prontas.
Eu não recomendaria desativar completamente o mecanismo, mas se for necessário, você pode criar uma configuração de substituição separada:
/etc/ssh/sshd_config.d/99-pensourcepenalties-disable.conf
O nome do arquivo pode ser qualquer um. O prefixo numérico determina a ordem de carregamento da configuração.
Você pode desativar completamente o mecanismo com a diretiva:
PerSourcePenalties no
Ou desativar apenas certos tipos de penalidades:
PerSourcePenalties authfail:0 noauth:0
Após alterar a configuração, não se esqueça de reiniciar o sshd:
systemctl restart ssh
Conclusões e dica útil
PerSourcePenalties não substitui completamente o Fail2Ban, mas o complementa perfeitamente, como a primeira linha de defesa (reação rápida ao ruído e força bruta leve).
Fail2Ban - é perfeito para o papel da segunda linha (proibições longas para ataques persistentes, proteção de outros serviços, monitoramento conveniente).
Apos os testes, não tive a sensação de que PerSourcePenalties deveria substituir o Fail2Ban. Mas agora o servidor SSH pelo menos consegue se defender do ruído mais primitivo e da força bruta sem gambiarras externas. E, para ser sincero, para um mecanismo embutido, isso funciona inesperadamente bem. O que você acha?





