Вот пошаговая инструкция по настройке fail2ban для защиты от сканирования Папки все создадутся по этому адресу /opt/fail2ban:
Создать файл в папке /opt/ install-fail2ban-complete.sh и вставить в него скрипт
#!/bin/bash
# Полная автоматическая установка и настройка fail2ban для Docker nginx-proxy
# Все файлы будут созданы в /opt/fail2ban/
# Запуск: sudo bash install-fail2ban-complete.sh
set -e
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
echo_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
echo_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Проверка прав root
if [[ $EUID -ne 0 ]]; then
echo_error "Этот скрипт должен запускаться с правами root"
echo "Использование: sudo bash $0"
exit 1
fi
echo_info "=== Начинаем установку fail2ban в /opt/fail2ban ==="
# 1. Создание структуры директорий
echo_info "Создаем структуру директорий..."
mkdir -p /opt/fail2ban/{config,logs,scripts}
mkdir -p /opt/fail2ban/config/{filter.d,jail.d,action.d}
# 2. Установка fail2ban и зависимостей
echo_info "Устанавливаем fail2ban..."
apt update
apt install -y fail2ban iptables-persistent
# 3. Создание скрипта парсинга логов Docker
echo_info "Создаем скрипт парсинга логов..."
cat > /opt/fail2ban/scripts/parse-nginx-logs.sh << 'EOF'
#!/bin/bash
# Скрипт парсинга логов nginx-proxy Docker контейнера
LOG_FILE="/opt/fail2ban/logs/nginx-access.log"
CONTAINER_NAME="nginx-proxy"
TEMP_FILE="/tmp/nginx-logs-temp"
# Проверяем, что контейнер запущен
if ! docker ps --format "table {{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then
echo "$(date): Контейнер $CONTAINER_NAME не найден или не запущен" >> /opt/fail2ban/logs/parser.log
exit 1
fi
# Получаем последние 2000 строк логов
docker logs "$CONTAINER_NAME" --tail 2000 2>/dev/null > "$TEMP_FILE"
# Фильтруем только nginx.1 записи и убираем префикс
grep 'nginx\.1.*"[A-Z]' "$TEMP_FILE" | \
sed 's/nginx\.1[[:space:]]*|[[:space:]]*//' | \
grep -E '"(GET|POST|PUT|DELETE|HEAD|OPTIONS)' > "$LOG_FILE"
# Устанавливаем права доступа
chmod 644 "$LOG_FILE"
# Логируем успешное выполнение (раз в час)
MINUTE=$(date +%M)
if [ "$MINUTE" = "00" ]; then
LINES=$(wc -l < "$LOG_FILE" 2>/dev/null || echo "0")
echo "$(date): Обработано $LINES записей из контейнера $CONTAINER_NAME" >> /opt/fail2ban/logs/parser.log
fi
# Очищаем временный файл
rm -f "$TEMP_FILE"
# Ротация логов (если файл больше 10MB)
if [ -f "$LOG_FILE" ] && [ $(stat -c%s "$LOG_FILE" 2>/dev/null || echo 0) -gt 10485760 ]; then
mv "$LOG_FILE" "$LOG_FILE.old"
touch "$LOG_FILE"
chmod 644 "$LOG_FILE"
fi
EOF
# 4. Создание фильтра для сканирования
echo_info "Создаем фильтры fail2ban..."
cat > /opt/fail2ban/config/filter.d/nginx-scan-block.conf << 'EOF'
# Фильтр для блокировки сканирования nginx
[Definition]
# Блокировка попыток доступа к конфигурационным файлам
failregex = ^.* <HOST> - - .*"GET (/\.env|/\.git|/\.aws|/\.ssh|/config|/backup|wp-config|phpinfo|admin/config|server-status|server-info).*" [0-9]{3}
^.* <HOST> - - .*"GET .*\.(php|asp|jsp|cgi|pl|py).*" 40[0-9]
^.* <HOST> - - .*"GET.*\.\./.*" [0-9]{3}
^.* <HOST> - - .*"GET.*(union|select|insert|update|delete|drop|create|alter).*" [0-9]{3}
^.* <HOST> - - .*"GET.*(<script|javascript:|vbscript:|onload|onerror).*" [0-9]{3}
^.* <HOST> - - .*"(GET|POST).* .*(\||`|;|<|>|'|\\|\{|\}|\[|\]).*" [0-9]{3}
^.* <HOST> - - .*"GET.*/\.(htaccess|htpasswd|passwd|shadow|hosts).*" [0-9]{3}
^.* <HOST> - - .*"GET.*/(etc/|var/|bin/|usr/bin/|tmp/|proc/).*" [0-9]{3}
ignoreregex = ^.* <HOST> - - .*"GET / HTTP.*" 200
^.* <HOST> - - .*"GET /favicon\.ico HTTP.*"
^.* <HOST> - - .*"GET /robots\.txt HTTP.*"
EOF
# 5. Создание фильтра для DoS атак
cat > /opt/fail2ban/config/filter.d/nginx-dos-block.conf << 'EOF'
# Фильтр для блокировки DoS атак
[Definition]
# Слишком много запросов с одного IP
failregex = ^.* <HOST> - - .*"(GET|POST).*" [0-9]{3}
# Игнорируем изображения и статические файлы
ignoreregex = ^.* <HOST> - - .*"GET .+\.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg).*" [0-9]{3}
EOF
# 6. Создание фильтра для 404 флуда
cat > /opt/fail2ban/config/filter.d/nginx-404-flood.conf << 'EOF'
# Фильтр для блокировки 404 флуда
[Definition]
# Много 404 ошибок подряд
failregex = ^.* <HOST> - - .*"(GET|POST).*" 404
ignoreregex = ^.* <HOST> - - .*"GET /(favicon\.ico|robots\.txt|sitemap\.xml).*" 404
EOF
# 7. Создание jail конфигурации
cat > /opt/fail2ban/config/jail.d/nginx-protection.conf << 'EOF'
# Jail конфигурация для nginx защиты
[DEFAULT]
# Время бана в секундах (1 час = 3600)
bantime = 3600
# Время поиска нарушений (5 минут = 300)
findtime = 300
# Игнорировать локальные IP
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
[nginx-scan-block]
enabled = true
port = http,https
filter = nginx-scan-block
logpath = /opt/fail2ban/logs/nginx-access.log
maxretry = 3
bantime = 7200
findtime = 300
action = iptables-multiport[name=nginx-scan, port="http,https", protocol=tcp]
[nginx-dos-block]
enabled = true
port = http,https
filter = nginx-dos-block
logpath = /opt/fail2ban/logs/nginx-access.log
maxretry = 50
bantime = 600
findtime = 60
action = iptables-multiport[name=nginx-dos, port="http,https", protocol=tcp]
[nginx-404-flood]
enabled = true
port = http,https
filter = nginx-404-flood
logpath = /opt/fail2ban/logs/nginx-access.log
maxretry = 10
bantime = 3600
findtime = 600
action = iptables-multiport[name=nginx-404, port="http,https", protocol=tcp]
EOF
# 8. Создание скрипта управления
echo_info "Создаем скрипт управления..."
cat > /opt/fail2ban/scripts/manage-fail2ban.sh << 'EOF'
#!/bin/bash
# Скрипт управления fail2ban
case "$1" in
status)
echo "=== Статус fail2ban ==="
fail2ban-client status
echo ""
echo "=== Детальная информация ==="
for jail in nginx-scan-block nginx-dos-block nginx-404-flood; do
if fail2ban-client status | grep -q "$jail"; then
echo "--- $jail ---"
fail2ban-client status $jail 2>/dev/null || echo "Jail $jail недоступен"
echo ""
fi
done
;;
logs)
echo "=== Последние 50 записей nginx логов ==="
tail -50 /opt/fail2ban/logs/nginx-access.log 2>/dev/null || echo "Лог файл не найден"
;;
banned)
echo "=== Заблокированные IP ==="
iptables -L -n | grep f2b || echo "Нет заблокированных IP"
;;
unban)
if [ -z "$2" ]; then
echo "Использование: $0 unban <IP>"
exit 1
fi
echo "Разблокируем IP: $2"
fail2ban-client unban $2
;;
ban)
if [ -z "$2" ] || [ -z "$3" ]; then
echo "Использование: $0 ban <jail> <IP>"
echo "Пример: $0 ban nginx-scan-block 1.2.3.4"
exit 1
fi
echo "Блокируем IP $3 в jail $2"
fail2ban-client set $2 banip $3
;;
reload)
echo "Перезагружаем fail2ban..."
systemctl restart fail2ban
sleep 3
fail2ban-client status
;;
parse)
echo "Запускаем парсинг логов..."
/opt/fail2ban/scripts/parse-nginx-logs.sh
LINES=$(wc -l < /opt/fail2ban/logs/nginx-access.log 2>/dev/null || echo "0")
echo "Парсинг завершен. Строк в логе: $LINES"
;;
test)
echo "=== Тестирование конфигурации ==="
fail2ban-client -t && echo "Конфигурация корректна!" || echo "Ошибка в конфигурации!"
;;
block-suspicious)
echo "Блокируем подозрительные IP из ваших логов..."
SUSPICIOUS_IPS=("109.202.99.36" "213.152.176.252" "185.177.72.10" "193.46.255.46" "103.246.146.203")
for ip in "${SUSPICIOUS_IPS[@]}"; do
echo "Блокируем $ip"
iptables -I INPUT -s $ip -j DROP 2>/dev/null || echo "IP $ip уже заблокирован или ошибка"
done
iptables-save > /etc/iptables/rules.v4 2>/dev/null || echo "Не удалось сохранить правила iptables"
echo "Заблокировано IP адресов: ${#SUSPICIOUS_IPS[@]}"
;;
*)
echo "Использование: $0 {status|logs|banned|unban|ban|reload|parse|test|block-suspicious}"
echo ""
echo "Команды:"
echo " status - Показать статус всех jail"
echo " logs - Показать последние логи nginx"
echo " banned - Показать заблокированные IP"
echo " unban <IP> - Разблокировать IP"
echo " ban <jail> <IP> - Заблокировать IP в определенном jail"
echo " reload - Перезагрузить fail2ban"
echo " parse - Запустить парсинг логов вручную"
echo " test - Проверить конфигурацию"
echo " block-suspicious - Заблокировать подозрительные IP из логов"
exit 1
;;
esac
EOF
# 9. Установка прав доступа
echo_info "Устанавливаем права доступа..."
chmod +x /opt/fail2ban/scripts/*.sh
chmod 644 /opt/fail2ban/config/filter.d/*
chmod 644 /opt/fail2ban/config/jail.d/*
chown -R root:root /opt/fail2ban/
# 10. Создание символических ссылок
echo_info "Создаем символические ссылки..."
ln -sf /opt/fail2ban/config/filter.d/* /etc/fail2ban/filter.d/
ln -sf /opt/fail2ban/config/jail.d/* /etc/fail2ban/jail.d/
# 11. Создание cron задачи
echo_info "Настраиваем cron для парсинга логов..."
(crontab -l 2>/dev/null; echo "*/2 * * * * /opt/fail2ban/scripts/parse-nginx-logs.sh") | crontab -
# 12. Первоначальный парсинг логов
echo_info "Запускаем первоначальный парсинг логов..."
/opt/fail2ban/scripts/parse-nginx-logs.sh || echo_warn "Не удалось запустить парсинг (возможно контейнер nginx-proxy не запущен)"
# 13. Перезапуск fail2ban
echo_info "Перезапускаем и включаем fail2ban..."
systemctl restart fail2ban
systemctl enable fail2ban
# 14. Ожидание запуска
sleep 5
# 15. Проверка статуса
echo_info "Проверяем статус fail2ban..."
fail2ban-client status || echo_warn "fail2ban запущен, но возможны проблемы с jail"
# 16. Создание алиаса для удобства
echo_info "Создаем алиас для управления..."
echo 'alias f2b="/opt/fail2ban/scripts/manage-fail2ban.sh"' >> /root/.bashrc
# 17. Блокировка подозрительных IP из логов
echo_info "Блокируем подозрительные IP из ваших логов..."
SUSPICIOUS_IPS=("109.202.99.36" "213.152.176.252" "185.177.72.10" "193.46.255.46" "103.246.146.203")
for ip in "${SUSPICIOUS_IPS[@]}"; do
echo "Блокируем $ip"
iptables -I INPUT -s $ip -j DROP 2>/dev/null || echo_warn "IP $ip уже заблокирован или ошибка"
done
# Сохранение правил iptables
iptables-save > /etc/iptables/rules.v4 2>/dev/null || echo_warn "Не удалось сохранить правила iptables"
echo ""
echo_info "=== УСТАНОВКА ЗАВЕРШЕНА УСПЕШНО! ==="
echo ""
echo "📁 Структура файлов:"
echo " /opt/fail2ban/scripts/ - Скрипты управления"
echo " /opt/fail2ban/config/ - Конфигурации"
echo " /opt/fail2ban/logs/ - Логи"
echo ""
echo "🚀 Полезные команды:"
echo " /opt/fail2ban/scripts/manage-fail2ban.sh status - Статус"
echo " /opt/fail2ban/scripts/manage-fail2ban.sh logs - Просмотр логов"
echo " /opt/fail2ban/scripts/manage-fail2ban.sh banned - Заблокированные IP"
echo " f2b status - Алиас (после перелогина)"
echo ""
echo "🛡️ Защита активна для:"
echo " - Сканирования конфигурационных файлов (.env, .git, wp-config, etc)"
echo " - DoS атак (более 50 запросов в минуту)"
echo " - 404 флуда (более 10 ошибок 404 за 10 минут)"
echo ""
echo "⚠️ Заблокированы подозрительные IP из ваших логов: ${#SUSPICIOUS_IPS[@]} адресов"
echo ""
echo "Для проверки статуса выполните: /opt/fail2ban/scripts/manage-fail2ban.sh status"
Далее запустить скрипт:
cd /opt/ sudo bash install-fail2ban-complete.sh
Проверить статус
/opt/fail2ban/scripts/manage-fail2ban.sh status