Configurar fail2ban com acionamento por webhooks e Telegram no Ubuntu 22.04

Redes & Segurança · Por · Publicado em · 8 min de leitura

Textura de madeira com anéis e veios visíveis
Opção neutra e profissional para destaque, sem marcas, texto legível ou pessoas Foto: Pexels / Pixabay

Neste tutorial, você vai configurar fail2ban com acionamento por webhooks e alertas no Telegram no Ubuntu 22.04. Vamos criar um script de notificação, registrar uma action personalizada e aplicar tudo em uma jail do SSHD. O objetivo é bloquear tentativas de força bruta e avisar você em tempo real, de forma simples e reproduzível.

Pré-requisitos, objetivos e instalação do fail2ban

Você precisa de um Ubuntu 22.04 com acesso root e saída HTTP/HTTPS. Tenha um bot do Telegram (token e chat ID) e, opcionalmente, um endpoint de webhook. Cuidado: regras incorretas podem bloquear seu IP. Teste de outro host ou use ignoreip.

Objetivos: instalar o fail2ban, criar um script de notificação (webhook + Telegram), registrar uma action e aplicar em uma jail do SSHD.

Se ainda não tem firewall básico, confira como configurar firewall no Ubuntu com UFW. Para um hardening mais amplo, veja o checklist de segurança para VPS Linux.

  • Acesso root ou sudo sem senha
  • curl instalado para chamadas HTTP
  • Bot do Telegram (token) e chat ID
  • Opcional: URL de webhook e segredo (HMAC)
# Atualize pacotes, instale e habilite
sudo apt update && sudo apt install -y fail2ban curl
sudo systemctl enable --now fail2ban

# Verifique versão, status e logs
fail2ban-client -V || true
sudo systemctl status fail2ban --no-pager
sudo tail -n 50 /var/log/fail2ban.log || true

Visão geral do fluxo (o que dispara o quê)

O fail2ban lê logs. Quando um padrão de falha ultrapassa o limite, aplica o ban (ex.: iptables) e executa uma action. Criaremos uma action que chama um script. O script envia um POST para seu webhook e alerta no Telegram.

Você pode adaptar o fluxo para Nginx, Postfix e outros serviços. Para reduzir ataques SSH, avalie um bastion: como configurar bastion SSH no Ubuntu 22.04.

Etapa Componente Exemplo
Evento de falha Log (sshd) Múltiplas senhas erradas
Detecção Filtro + jail (fail2ban) maxretry atingido
Bloqueio Ação de ban (iptables) DROP no IP ofensivo
Notificação Action personalizada Script chama webhook e Telegram

Telegram: criar bot e salvar variáveis com segurança

Crie um bot no Telegram (via BotFather) e obtenha o token. Encontre seu chat ID após enviar /start para o bot. Guardaremos tudo em um arquivo somente‑leitura para root.

Também permitiremos configurar um webhook opcional e um segredo HMAC. Mantenha o arquivo com permissão 600.

  • TELEGRAM_BOT_TOKEN: token do bot
  • TELEGRAM_CHAT_ID: ID do chat/grupo/canal
  • WEBHOOK_URL: URL de automação (opcional)
  • WEBHOOK_SECRET: chave para assinar payload (opcional)
# Crie o arquivo de variáveis sensíveis
sudo tee /etc/fail2ban/telegram.env >/dev/null <<'EOF'
TELEGRAM_BOT_TOKEN="coloque_o_token_aqui"
TELEGRAM_CHAT_ID="coloque_o_chat_id_aqui"
# Opcional: envie também para um webhook de automação
WEBHOOK_URL=""
WEBHOOK_SECRET=""
EOF

# Restrinja permissões
sudo chown root:root /etc/fail2ban/telegram.env
sudo chmod 600 /etc/fail2ban/telegram.env

Script de notificação: webhook + Telegram

O script recebe dados do fail2ban (IP, jail e evento), monta um JSON e envia: 1) um POST ao seu webhook, com assinatura HMAC opcional; 2) uma mensagem ao Telegram. Teste manualmente antes de integrar.

A mensagem ao Telegram é texto simples. Para automações, integre o webhook em n8n, Zapier ou Make.

  • Assinatura HMAC-SHA256 opcional no header X-Signature
  • Payload JSON claro: ip, jail, evento, timestamps
  • Saídas independentes: webhook e Telegram
sudo tee /usr/local/bin/f2b_notify.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

ENV_FILE="/etc/fail2ban/telegram.env"
[[ -f "$ENV_FILE" ]] && source "$ENV_FILE"

IP="${1:-}"
JAIL="${2:-}"
LOGPATH="${3:-}"
EVENT="${4:-ban}"
FAILURES="${5:-}"
FINDTIME="${6:-}"
BANTIME="${7:-}"

TS="$(date -Iseconds)"
HOSTNAME="$(hostname -f 2>/dev/null || hostname)"

# Monta payload JSON mínimo
PAYLOAD=$(cat <<JSON
{
  "host": "${HOSTNAME}",
  "jail": "${JAIL}",
  "ip": "${IP}",
  "event": "${EVENT}",
  "failures": "${FAILURES}",
  "findtime": "${FINDTIME}",
  "bantime": "${BANTIME}",
  "logpath": "${LOGPATH}",
  "timestamp": "${TS}"
}
JSON
)

# 1) Envio para webhook (opcional)
if [[ -n "${WEBHOOK_URL:-}" ]]; then
  SIG=""
  if [[ -n "${WEBHOOK_SECRET:-}" ]]; then
    SIG=$(printf '%s' "$PAYLOAD" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" -binary | base64)
  fi
  curl -fsS -X POST "$WEBHOOK_URL" \
    -H 'Content-Type: application/json' \
    ${SIG:+-H "X-Signature: ${SIG}"} \
    --data-raw "$PAYLOAD" || true
fi

# 2) Envio para Telegram (opcional)
if [[ -n "${TELEGRAM_BOT_TOKEN:-}" && -n "${TELEGRAM_CHAT_ID:-}" ]]; then
  TEXT="[fail2ban] ${EVENT^^} em ${JAIL} — IP ${IP} — host ${HOSTNAME} — ${TS}"
  curl -fsS -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
    -H 'Content-Type: application/json' \
    -d "{\"chat_id\":\"${TELEGRAM_CHAT_ID}\",\"text\":\"${TEXT}\"}" || true
fi
EOF

sudo chmod +x /usr/local/bin/f2b_notify.sh

Registrar a action personalizada no fail2ban

Crie uma action em action.d para que a jail possa chamá-la em cada ban e unban. Passaremos ao script as variáveis necessárias.

Manteremos actionban e actionunban. O ban real (iptables) ficará definido na jail.

# /etc/fail2ban/action.d/f2b-notify-webhook-telegram.conf
[Definition]
actionstart =
actionstop =
# Evento de ban
actionban = /usr/local/bin/f2b_notify.sh "<ip>" "<name>" "<logpath>" "ban" "<failures>" "<findtime>" "<bantime>"
# Evento de unban (informativo)
actionunban = /usr/local/bin/f2b_notify.sh "<ip>" "<name>" "<logpath>" "unban" "0" "0" "0"

[Init]
name = default

Jail do SSHD usando iptables e a nova action

Agora criaremos uma jail para sshd. Ela bloqueia via iptables e dispara nossa action de notificação. Adicione seu IP em ignoreip para não se banir.

Adapte maxretry, findtime e bantime ao seu risco e volume de acessos.

  • backend systemd funciona bem no Ubuntu 22.04
  • iptables-nft é padrão; iptables-multiport segue válido
  • ignoreip aceita listas e CIDRs
# /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled = true
port = 22
logpath = %(sshd_log)s
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 192.168.0.0/16

# Ação de bloqueio (iptables)
banaction = iptables-multiport

# Notificações
action = f2b-notify-webhook-telegram

Testes: recarregar, simular falhas e validar alertas

Hora de testar. Recarregue o fail2ban, verifique a jail sshd e simule logins com senha errada a partir de outro host. Confirme o ban, a execução da action e o recebimento dos alertas no Telegram e no webhook.

Você também pode forçar um unban para validar o alerta de desbloqueio.

  • Use uma máquina separada para testar falhas de SSH
  • Monitore /var/log/fail2ban.log em tempo real
  • Se nada chegar ao Telegram, valide token e chat ID
# Recarregar e inspecionar
sudo fail2ban-client reload
sudo fail2ban-client status
sudo fail2ban-client status sshd

# Acompanhar logs
sudo tail -f /var/log/fail2ban.log &

# (Em outro host) force tentativas erradas de SSH
# ssh usuario@SEU_IP  # digite senhas erradas

# Checar IPs banidos e desbanir para testar unban
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 1.2.3.4  # troque pelo IP de teste

Solução de problemas e aprimoramentos úteis

Alguns problemas são comuns e fáceis de resolver. Veja dicas e extensões do setup abaixo. Para observabilidade, considere métricas com Prometheus e dashboards com Grafana: veja o guia em configurar Prometheus e Grafana com Docker Compose em VPS.

  • Sem alertas: verifique permissões 600 em /etc/fail2ban/telegram.env e se o script é executável.
  • Proxy corporativo: exporte http_proxy/https_proxy para o serviço.
  • UFW ativo: iptables-multiport costuma coexistir; se conflitar, use ufw como banaction.
  • Mensagem do Telegram com caracteres estranhos: simplifique o TEXT.
  • Webhook não recebe: teste manual com curl e valide retorno HTTP 2xx.
  • Reduza ruído: ajuste filtros, maxretry e findtime; considere banaction incremental.
  • Assinatura: valide X-Signature no seu fluxo (n8n, Zapier, Make).
# Teste manual do webhook (substitua URL)
WEBHOOK_URL="https://example.com/webhook"
payload='{"hello":"world"}'
curl -v -X POST "$WEBHOOK_URL" -H 'Content-Type: application/json' --data-raw "$payload"

Perguntas frequentes

Funciona com outros serviços além do SSH (sshd)?

Sim. Crie ou habilite jails para Nginx, Postfix e Apache, apontando o log certo e ajustando maxretry, findtime e bantime. Reuse a mesma action para padronizar os alertas.

Como encontro meu chat ID no Telegram?

Inicie conversa com seu bot, envie uma mensagem e use um bot utilitário para obter o chat ID. Também é possível ler o update JSON da API do Telegram após enviar a primeira mensagem.

UFW e fail2ban podem rodar juntos?

Geralmente, sim. O fail2ban aplica regras temporárias enquanto o UFW mantém a política base. Se houver conflito, troque a ação de ban para ufw no lugar de iptables-multiport.

Como evitar me banir por engano?

Use ignoreip com seu IP fixo ou um bloco confiável. Teste de outra máquina e, se necessário, reduza temporariamente o bantime. Se travar o acesso, use o console e execute unbanip.

Posso assinar o payload do webhook para validar a origem?

Sim. Defina WEBHOOK_SECRET. O script calcula um HMAC-SHA256 do corpo e envia no header X-Signature em base64. No receptor, recalcule e compare para validar.

Como integrar com n8n, Zapier ou Make?

Aponte WEBHOOK_URL para um webhook público criado na ferramenta. A automação pode rotear alertas para e-mail, SMS, Slack e abrir tickets. Valide X-Signature antes de processar.

Precisa adaptar este setup ao seu ambiente?

Quer ampliar para outras jails, reduzir falsos positivos e padronizar alertas? Vamos revisar filtros, actions e automações do seu stack.

Falar sobre segurança e automação

Veja também