sshd — алерт по росту auth-fail (до бана fail2ban)
fail2ban банит источники по threshold — но кампания идёт с тысячи IP по 1 attempt каждый. Каждый IP не попадает в ban, но общий шум на ssh-порту огромный.
Рецепт
#!/usr/bin/env bash
# /etc/cron.d/sshd-spike
# */5 * * * * root /opt/sshd-spike.sh
WINDOW=${WINDOW:-5min}
THRESH=${THRESH:-100} # fails / 5 min
COUNT=$(journalctl -u ssh --since "$WINDOW ago" --no-pager 2>/dev/null \
| grep -cE 'Failed password|Invalid user|maximum authentication attempts')
if [ "${COUNT:-0}" -gt "$THRESH" ]; then
UNIQUE=$(journalctl -u ssh --since "$WINDOW ago" --no-pager 2>/dev/null \
| grep -oE 'from [0-9.]+' | sort -u | wc -l)
curl -fsS "$HEARTBEAT_URL" --data "ssh_fails=$COUNT,unique_ips=$UNIQUE"
exit 2
fi
echo "OK ($COUNT auth-fails / 5m)"
То же самое в Enterno.io
Заверните в Enterno heartbeat — увидите кампанию distributed-bruteforce раньше, чем она «прокликает» одну ослабленную ssh-учётку.
Похожие рецепты
Сайт в HSTS preload-листе, но после рефакторинга nginx конфиг заголовок пропал. Через 3 месяца домен будет удалён из preload-листа. Нужен ежедневный чек.
Мисконфигурация name-server открыла AXFR на интернет — все ваши поддомены, MX, TXT (включая SPF DKIM ключи) видны атакующему. Ежедневный чек с алертом.
Атакующий упёрся в `limit_req_zone` — все легитимные запросы тоже начали получать 429. Логи показывают это, но никто не следит.