Код: Выделить всё
#!/usr/bin/env bash
# ============================================
# СКРИПТ АВТОМАТИЧЕСКОГО БАНА АТАКУЮЩИХ
# Версия: 2.2 (исправлены все ошибки)
# ============================================
LOG_FILE="/var/log/mail.log"
BANNED_FILE="/tmp/banned_ips.txt"
BAN_LOG="/var/log/ban-attacks.log"
SUBNETS_FILE="/tmp/banned_subnets.txt"
EXCLUDE_FILE="/etc/ban-exclude.txt"
# Функция логирования
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') $*" | tee -a "$BAN_LOG"
}
# Функция проверки исключений
is_excluded() {
local ip="$1"
[[ -z "$ip" ]] && return 1
if [[ -f "$EXCLUDE_FILE" ]]; then
if grep -q "^$ip$" "$EXCLUDE_FILE" 2>/dev/null; then
return 0
fi
fi
return 1
}
# Функция проверки валидности IP
is_valid_ip() {
local ip="$1"
[[ -z "$ip" ]] && return 1
# Проверяем формат IP (4 октета, каждый от 0 до 255)
if echo "$ip" | grep -qE '^([0-9]{1,3}\.){3}[0-9]{1,3}$'; then
# Проверяем, что нет ведущих нулей и каждый октет <= 255
local octet1=$(echo "$ip" | cut -d. -f1)
local octet2=$(echo "$ip" | cut -d. -f2)
local octet3=$(echo "$ip" | cut -d. -f3)
local octet4=$(echo "$ip" | cut -d. -f4)
if [[ $octet1 -le 255 && $octet2 -le 255 && $octet3 -le 255 && $octet4 -le 255 ]]; then
return 0
fi
fi
return 1
}
# Функция очистки IP от ведущих нулей
clean_ip() {
echo "$1" | sed 's/^0*//;s/\.0*/./g' | sed 's/\.\././g'
}
# Создаем списки уже забаненных
sudo iptables -L INPUT -n 2>/dev/null | grep DROP | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" > "$BANNED_FILE" 2>/dev/null || touch "$BANNED_FILE"
sudo iptables -L INPUT -n 2>/dev/null | grep DROP | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+" > "$SUBNETS_FILE" 2>/dev/null || touch "$SUBNETS_FILE"
log "🔍 Поиск атакующих..."
# 1. Баним отдельные IP (с проверкой исключений)
grep -E "SASL.*authentication failed" "$LOG_FILE" 2>/dev/null | \
grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" | \
sed 's/^0*//;s/\.0*/./g' | \
sed 's/\.\././g' | \
sort -u | \
while read ip; do
# Пропускаем пустые строки
[[ -z "$ip" ]] && continue
# Проверяем валидность IP
if ! is_valid_ip "$ip"; then
log "⚠️ Пропускаем невалидный IP: $ip"
continue
fi
# Проверяем исключения
if is_excluded "$ip"; then
log "⏭️ Пропускаем исключенный IP: $ip"
continue
fi
if ! grep -q "^$ip$" "$BANNED_FILE" 2>/dev/null; then
log "🔒 Бан IP: $ip"
sudo iptables -I INPUT -s "$ip" -j DROP 2>/dev/null
if [[ $? -eq 0 ]]; then
echo "$ip" >> "$BANNED_FILE"
fi
fi
done
# 2. Баним подсети
for subnet in 45.148.10.0/24 192.253.248.0/24 103.141.144.0/24; do
if ! grep -q "^$subnet$" "$SUBNETS_FILE" 2>/dev/null; then
count=$(grep -E "SASL.*authentication failed" "$LOG_FILE" 2>/dev/null | grep -c "${subnet%.*}" 2>/dev/null || echo "0")
# Убираем лишние символы
count=$(echo "$count" | tr -d '\n\r' | sed 's/[^0-9]//g')
if [[ -z "$count" ]]; then
count=0
fi
if [[ $count -gt 3 ]]; then
log "🔒 Бан подсети: $subnet ($count атак)"
sudo iptables -I INPUT -s "$subnet" -j DROP 2>/dev/null
echo "$subnet" >> "$SUBNETS_FILE"
fi
fi
done
# Сохраняем правила
sudo netfilter-persistent save 2>/dev/null || sudo iptables-save > /etc/iptables/rules.v4 2>/dev/null || true
total=$(sudo iptables -L INPUT -n 2>/dev/null | grep DROP | grep -v "ADDRTYPE" | grep -v "recent" | wc -l)
log "✅ Забанено IP/подсетей: $total"
Код: Выделить всё
# 1. Создаем скрипт
sudo nano /usr/local/bin/setup-postfix-protection.sh
# 2. Вставляем код выше и сохраняем (Ctrl+O, Enter, Ctrl+X)
# 3. Даем права на выполнение
sudo chmod +x /usr/local/bin/setup-postfix-protection.sh
# 4. Запускаем установку
sudo /usr/local/bin/setup-postfix-protection.sh
Функция Описание
Проверка зависимостей Проверяет установленные пакеты
Создание скрипта бана ban-attackers.sh - автоматический бан
Создание скрипта проверки check-ban.sh - статус защиты
Настройка cron Бан каждые 2 и 5 минут
Настройка iptables Базовые правила защиты
Настройка fail2ban Дополнительная защита (если установлен)
Первый запуск Немедленный бан всех атакующих
Вывод информации Показывает статус и полезные команды
После установки:
Код: Выделить всё
# Проверить статус
sudo /usr/local/bin/check-ban.sh
# Посмотреть логи
sudo tail -f /var/log/ban-attacks.log
# Посмотреть атаки
sudo tail -f /var/log/mail.log | grep "SASL.*failed"
КРАТКАЯ ПАМЯТКА ПО СКРИПТАМ ЗАЩИТЫ POSTFIX
📁 Список скриптов
Скрипт Путь Назначение
ban-attackers.sh /usr/local/bin/ban-attackers.sh Автоматический бан атакующих IP
check-ban.sh /usr/local/bin/check-ban.sh Проверка статуса защиты
unban-ip.sh /usr/local/bin/unban-ip.sh Ручное удаление IP из бана
setup-postfix-protection.sh /usr/local/bin/setup-postfix-protection.sh Установка всей защиты
Код: Выделить всё
# Проверить статус защиты
sudo /usr/local/bin/check-ban.sh
# Запустить бан вручную
sudo /usr/local/bin/ban-attackers.sh
# Разбанить IP
sudo /usr/local/bin/unban-ip.sh 192.168.1.1
# Посмотреть логи бана
sudo tail -f /var/log/ban-attacks.log
# Посмотреть атаки в реальном времени
sudo tail -f /var/log/mail.log | grep "SASL.*failed"
Код: Выделить всё
# Все забаненные IP
sudo iptables -L INPUT -n | grep DROP | grep -v "ADDRTYPE" | grep -v "recent"
# Количество забаненных
sudo iptables -L INPUT -n | grep DROP | grep -v "ADDRTYPE" | grep -v "recent" | wc -l
# Проверить конкретный IP
sudo iptables -L INPUT -n | grep 192.168.1.1
# Удалить IP из iptables вручную
sudo iptables -D INPUT -s 192.168.1.1 -j DROP
Код: Выделить всё
# Добавить IP в исключения (не банить)
echo "192.168.1.1" | sudo tee -a /etc/ban-exclude.txt
# Посмотреть исключения
cat /etc/ban-exclude.txt
# Удалить IP из исключений
sudo sed -i '/192.168.1.1/d' /etc/ban-exclude.txt
Код: Выделить всё
# Проверить задачу в cron
sudo grep "ban-attackers" /etc/crontab
# Добавить в /etc/crontab (если нет)
echo "*/2 * * * * root /usr/local/bin/ban-attackers.sh > /dev/null 2>&1" | sudo tee -a /etc/crontab
# Перезапустить cron
sudo systemctl restart cron
Код: Выделить всё
Логи
Лог Путь Содержание
Лог бана /var/log/ban-attacks.log Все действия скрипта бана
Лог почты /var/log/mail.log Атаки и ошибки Postfix
Лог fail2ban /var/log/fail2ban.log Если используется fail2ban
Код: Выделить всё
# Удалить IP из iptables
sudo iptables -D INPUT -s 198.13.77.86 -j DROP
# Удалить все правила с IP
sudo iptables -L INPUT -n --line-numbers | grep 198.13.77.86 | awk '{print $1}' | sort -rn | while read num; do sudo iptables -D INPUT $num; done
# Добавить в исключения
echo "198.13.77.86" | sudo tee -a /etc/ban-exclude.txt
Код: Выделить всё
# Если что-то пошло не так - перезапустить
sudo systemctl restart cron
sudo /usr/local/bin/ban-attackers.sh
Код: Выделить всё
IP в /etc/ban-exclude.txt НЕ БАНЯТСЯ автоматически
Скрипт запускается каждые 2 минуты через cron
Все баны сохраняются после перезагрузки
Логи хранятся в /var/log/ban-attacks.log
