Один из способов защиты Linux-системы - мониторинг неудачных попыток входа. Сегодня покажу пример скрипта, который:
📍 анализирует лог /var/log/auth.log,
📍 определяет IP и пользователей, совершивших >10 неудачных попыток входа за 10 минут,
📍 автоматически блокирует IP через iptables на 3 часа,
📍 блокирует пользователя через passwd -l на 1 час,
📍 отправляет уведомление в телеграмм,
📍 и по таймеру снимает блокировку.
📱 Скрипт:
#!/bin/bash
LOG="/var/log/auth.log"
TMP="/tmp/login_check.tmp"
MAX_ATTEMPTS=10
TIME_WINDOW=600 # 10 минут
TELEGRAM_TOKEN="your_token"
CHAT_ID="your_chat_id"
IP_BLOCK_LIST="/tmp/ip_blocked.list"
USER_BLOCK_LIST="/tmp/user_blocked.list"
touch "$IP_BLOCK_LIST" "$USER_BLOCK_LIST"
NOW=$(date +%s)
# Удаляем истёкшие блокировки
grep -vE "^[^ ]+ [^ ]+ [0-9]+$" "$IP_BLOCK_LIST" > "$IP_BLOCK_LIST.tmp" && mv "$IP_BLOCK_LIST.tmp" "$IP_BLOCK_LIST"
grep -vE "^[^ ]+ [0-9]+$" "$USER_BLOCK_LIST" > "$USER_BLOCK_LIST.tmp" && mv "$USER_BLOCK_LIST.tmp" "$USER_BLOCK_LIST"
# Чтение лога и подсчёт попыток
grep "Failed password" "$LOG" | \
awk -v now="$NOW" -v limit="$TIME_WINDOW" '
{
match($0, /([A-Z][a-z]{2} [0-9]{1,2} [0-9:]{8})/, m);
cmd = "date -d\"" m[1] "\" +%s";
cmd | getline t;
close(cmd);
if (now - t <= limit) {
for (i=1;i<=NF;i++) {
if ($i == "from") ip=$(i+1);
if ($i == "for" && $(i+1) != "invalid") user=$(i+1);
}
if (ip != "" && user != "") print ip, user;
}
}' | sort | uniq -c | sort -nr > "$TMP"
# Обработка IP и пользователей
while read count ip user; do
if (( count >= MAX_ATTEMPTS )); then
# Блокировка IP
if ! grep -q "$ip " "$IP_BLOCK_LIST"; then
iptables -I INPUT -s "$ip" -j DROP
expire=$((NOW + 10800)) # 3 часа
echo "$ip $user $expire" >> "$IP_BLOCK_LIST"
curl -s -X POST https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage \
-d chat_id="$CHAT_ID" -d text="IP $ip заблокирован на 3 часа за $count неудачных попыток входа." > /dev/null
fi
# Блокировка пользователя
if ! grep -q "^$user " "$USER_BLOCK_LIST"; then
passwd -l "$user" 2>/dev/null
expire_user=$((NOW + 3600)) # 1 час
echo "$user $expire_user" >> "$USER_BLOCK_LIST"
curl -s -X POST https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage \
-d chat_id="$CHAT_ID" -d text="Учетка $user заблокирована на 1 час." > /dev/null
fi
fi
done < "$TMP"
# Снятие IP-блоков
while read ip user expire; do
if (( NOW >= expire )); then
iptables -D INPUT -s "$ip" -j DROP
sed -i "\|^$ip $user|d" "$IP_BLOCK_LIST"
fi
done < "$IP_BLOCK_LIST"
# Снятие блоков с пользователей
while read user expire; do
if (( NOW >= expire )); then
passwd -u "$user" 2>/dev/null
sed -i "\|^$user |d" "$USER_BLOCK_LIST"
fi
done < "$USER_BLOCK_LIST"
⭐️ Как использовать:
1. Замените your_token и your_chat_id на свои данные TG-бота.
2. Убедитесь, что скрипт имеет root-доступ (для iptables и passwd).
3. Добавьте в crontab:
*/5 * * * * /path/to/script.sh
Такой подход ближе к самописному fail2ban, но с расширенной логикой.
BashTex 📱 #bash