vm:nginx:06-file2ban_v2

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
vm:nginx:06-file2ban_v2 [2025/12/01 12:16] adminvm:nginx:06-file2ban_v2 [2025/12/01 12:19] (текущий) admin
Строка 1: Строка 1:
 +====== Установка и настройка Fail2ban для Nginx Proxy Manager ======
 +
 +===== Описание =====
 +
 +Данная инструкция описывает процесс установки и настройки Fail2ban для защиты Nginx Proxy Manager от:
 +  * Сканирования уязвимостей
 +  * 404 флуда
 +  * DoS атак
 +  * SSH брутфорса
 +
 +===== Требования =====
 +
 +  * Ubuntu Server 24.04 (или аналогичный дистрибутив)
 +  * Nginx Proxy Manager установленный в Docker
 +  * Root доступ к серверу
 +
 +===== Быстрая установка (автоматический скрипт) =====
 +
 +**Рекомендуется:** Используйте автоматический скрипт установки для быстрой настройки всей системы за один шаг.
 +
 +==== Шаг 1: Создание скрипта установки ====
 +
 +<code bash>
 +nano install-fail2ban.sh
 +</code>
 +
 +==== Шаг 2: Содержимое скрипта ====
 +
 +Скопируйте следующий код в файл:
 +
 +<code bash>
 +#!/bin/bash
 +
 +################################################################################
 +# Скрипт автоматической установки и настройки Fail2ban для Nginx Proxy Manager
 +# Версия: 1.0
 +# Дата: 2025-11-30
 +################################################################################
 +
 +set -e  # Остановка при ошибке
 +
 +# Цвета для вывода
 +RED='\033[0;31m'
 +GREEN='\033[0;32m'
 +YELLOW='\033[1;33m'
 +NC='\033[0m' # No Color
 +
 +# Функция вывода сообщений
 +log_info() {
 +    echo -e "${GREEN}[INFO]${NC} $1"
 +}
 +
 +log_warn() {
 +    echo -e "${YELLOW}[WARN]${NC} $1"
 +}
 +
 +log_error() {
 +    echo -e "${RED}[ERROR]${NC} $1"
 +}
 +
 +# Проверка прав root
 +if [[ $EUID -ne 0 ]]; then
 +   log_error "Этот скрипт должен быть запущен с правами root"
 +   exit 1
 +fi
 +
 +log_info "Начало установки и настройки Fail2ban для Nginx Proxy Manager"
 +echo ""
 +
 +################################################################################
 +# НАСТРОЙКИ - ИЗМЕНИТЕ ПОД СВОИ НУЖДЫ
 +################################################################################
 +
 +# Путь к логам Nginx Proxy Manager
 +NPM_LOG_DIR="/opt/nginxpm/data/logs"
 +
 +# Имя контейнера Nginx Proxy Manager
 +NPM_CONTAINER_NAME="nginxpm"
 +
 +# Директории Fail2ban
 +FAIL2BAN_BASE="/opt/fail2ban"
 +FAIL2BAN_SCRIPTS="${FAIL2BAN_BASE}/scripts"
 +FAIL2BAN_LOGS="${FAIL2BAN_BASE}/logs"
 +FAIL2BAN_CONFIG="${FAIL2BAN_BASE}/config"
 +FAIL2BAN_JAIL_D="${FAIL2BAN_CONFIG}/jail.d"
 +FAIL2BAN_FILTER_D="${FAIL2BAN_CONFIG}/filter.d"
 +
 +# Файл лога для fail2ban
 +NGINX_ACCESS_LOG="${FAIL2BAN_LOGS}/nginx-access.log"
 +
 +# Игнорируемые IP (локальные сети)
 +IGNORE_IP="127.0.0.1/8 ::1 192.168.0.0/24 172.16.0.0/12 10.0.0.0/8"
 +
 +################################################################################
 +# Шаг 1: Проверка существования Nginx Proxy Manager
 +################################################################################
 +
 +log_info "Проверка наличия контейнера Nginx Proxy Manager..."
 +
 +if ! docker ps --format "{{.Names}}" | grep -q "^${NPM_CONTAINER_NAME}$"; then
 +    log_error "Контейнер ${NPM_CONTAINER_NAME} не найден или не запущен"
 +    log_error "Убедитесь что Nginx Proxy Manager установлен и запущен"
 +    exit 1
 +fi
 +
 +if [ ! -d "$NPM_LOG_DIR" ]; then
 +    log_error "Директория логов ${NPM_LOG_DIR} не найдена"
 +    exit 1
 +fi
 +
 +log_info "Контейнер ${NPM_CONTAINER_NAME} найден и работает"
 +echo ""
 +
 +################################################################################
 +# Шаг 2: Установка Fail2ban
 +################################################################################
 +
 +log_info "Установка Fail2ban..."
 +
 +apt update -qq
 +apt install -y fail2ban >/dev/null 2>&1
 +
 +log_info "Fail2ban успешно установлен"
 +echo ""
 +
 +################################################################################
 +# Шаг 3: Создание структуры каталогов
 +################################################################################
 +
 +log_info "Создание структуры каталогов..."
 +
 +mkdir -p "${FAIL2BAN_SCRIPTS}"
 +mkdir -p "${FAIL2BAN_LOGS}"
 +mkdir -p "${FAIL2BAN_JAIL_D}"
 +mkdir -p "${FAIL2BAN_FILTER_D}"
 +
 +log_info "Структура каталогов создана"
 +echo ""
 +
 +################################################################################
 +# Шаг 4: Создание скрипта парсера логов
 +################################################################################
 +
 +log_info "Создание скрипта парсера логов..."
 +
 +cat > "${FAIL2BAN_SCRIPTS}/parse-nginx-logs.sh" << 'PARSER_EOF'
 +#!/bin/bash
 +# Скрипт парсинга логов nginx-proxy-manager для fail2ban
 +
 +LOG_DIR="/opt/nginxpm/data/logs"
 +LOG_FILE="/opt/fail2ban/logs/nginx-access.log"
 +CONTAINER_NAME="nginxpm"
 +PARSER_LOG="/opt/fail2ban/logs/parser.log"
 +
 +mkdir -p "$(dirname "$LOG_FILE")" "$(dirname "$PARSER_LOG")"
 +
 +if ! docker ps --format "table {{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then
 +    echo "$(date): Контейнер $CONTAINER_NAME не найден" >> "$PARSER_LOG"
 +    exit 1
 +fi
 +
 +if [ ! -d "$LOG_DIR" ]; then
 +    echo "$(date): Директория $LOG_DIR не найдена" >> "$PARSER_LOG"
 +    exit 1
 +fi
 +
 +> "$LOG_FILE"
 +
 +processed_files=0
 +total_lines=0
 +
 +for logfile in "$LOG_DIR"/proxy-host-*_access.log; do
 +    if [ -f "$logfile" ]; then
 +        lines_from_file=$(tail -n 2000 "$logfile" | wc -l)
 +        tail -n 2000 "$logfile" >> "$LOG_FILE"
 +        processed_files=$((processed_files + 1))
 +        total_lines=$((total_lines + lines_from_file))
 +        echo "$(date): Обработан: $(basename "$logfile") - $lines_from_file строк" >> "$PARSER_LOG"
 +    fi
 +done
 +
 +if [ $processed_files -eq 0 ]; then
 +    echo "$(date): Файлы логов не найдены" >> "$PARSER_LOG"
 +    touch "$LOG_FILE"
 +fi
 +
 +chmod 644 "$LOG_FILE"
 +
 +MINUTE=$(date +%M)
 +if [ "$MINUTE" = "00" ]; then
 +    final_lines=$(wc -l < "$LOG_FILE" 2>/dev/null || echo "0")
 +    echo "$(date): Обработано $processed_files файлов, $final_lines записей" >> "$PARSER_LOG"
 +fi
 +
 +if [ -f "$PARSER_LOG" ] && [ $(stat -c%s "$PARSER_LOG" 2>/dev/null || echo 0) -gt 5242880 ]; then
 +    mv "$PARSER_LOG" "$PARSER_LOG.old"
 +    touch "$PARSER_LOG"
 +    chmod 644 "$PARSER_LOG"
 +fi
 +
 +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"
 +    echo "$(date): Ротация лог-файла" >> "$PARSER_LOG"
 +fi
 +
 +exit 0
 +PARSER_EOF
 +
 +chmod +x "${FAIL2BAN_SCRIPTS}/parse-nginx-logs.sh"
 +
 +log_info "Скрипт парсера создан"
 +echo ""
 +
 +################################################################################
 +# Шаг 5: Первый запуск парсера
 +################################################################################
 +
 +log_info "Первый запуск парсера..."
 +
 +"${FAIL2BAN_SCRIPTS}/parse-nginx-logs.sh"
 +
 +if [ -f "$NGINX_ACCESS_LOG" ]; then
 +    log_info "Лог-файл создан: ${NGINX_ACCESS_LOG}"
 +    log_info "Количество строк: $(wc -l < ${NGINX_ACCESS_LOG})"
 +else
 +    log_error "Не удалось создать лог-файл"
 +    exit 1
 +fi
 +echo ""
 +
 +################################################################################
 +# Шаг 6: Создание фильтров Fail2ban
 +################################################################################
 +
 +log_info "Создание фильтров Fail2ban..."
 +
 +cat > "${FAIL2BAN_FILTER_D}/nginx-scan-block.conf" << 'FILTER_SCAN_EOF'
 +[Definition]
 +
 +failregex = ^\[.*\] - \d+ \d+ - GET https? .* ".*(/\.env|/\.git|/\.aws|/\.ssh|/config|/backup|wp-config|phpinfo|admin/config|server-status|server-info).*" \[Client <HOST>\]
 +            ^\[.*\] - 40\d \d+ - GET https? .* ".*\.(php|asp|jsp|cgi|pl|py).*" \[Client <HOST>\]
 +            ^\[.*\] - \d+ \d+ - GET https? .* ".*\.\.\/.*" \[Client <HOST>\]
 +            ^\[.*\] - \d+ \d+ - GET https? .* ".*(union|select|insert|update|delete|drop|create|alter).*" \[Client <HOST>\]
 +            ^\[.*\] - \d+ \d+ - (GET|POST) https? .* ".*(<script|javascript:|vbscript:|onload|onerror).*" \[Client <HOST>\]
 +            ^\[.*\] - \d+ \d+ - (GET|POST) https? .* ".*(\||`|;|<|>|\\|\{|\}|\[|\]).*" \[Client <HOST>\]
 +            ^\[.*\] - \d+ \d+ - GET https? .* ".*/(etc/|var/|bin/|usr/bin/|tmp/|proc/).*" \[Client <HOST>\]
 +
 +ignoreregex =
 +FILTER_SCAN_EOF
 +
 +cat > "${FAIL2BAN_FILTER_D}/nginx-404-flood.conf" << 'FILTER_404_EOF'
 +[Definition]
 +
 +failregex = ^\[.*\] - 404 \d+ - (GET|POST|HEAD) https? .* ".*" \[Client <HOST>\]
 +
 +ignoreregex =
 +FILTER_404_EOF
 +
 +cat > "${FAIL2BAN_FILTER_D}/nginx-dos-block.conf" << 'FILTER_DOS_EOF'
 +[Definition]
 +
 +failregex = ^\[.*\] - \d+ \d+ - (GET|POST|HEAD) https? .* ".*" \[Client <HOST>\]
 +
 +ignoreregex = ^\[.*\] - \d+ \d+ - (GET|POST) https? .* ".*\.(css|js|jpg|jpeg|png|gif|ico|woff|woff2|ttf|svg).*" \[Client <HOST>\]
 +FILTER_DOS_EOF
 +
 +ln -sf "${FAIL2BAN_FILTER_D}/nginx-scan-block.conf" /etc/fail2ban/filter.d/nginx-scan-block.conf
 +ln -sf "${FAIL2BAN_FILTER_D}/nginx-404-flood.conf" /etc/fail2ban/filter.d/nginx-404-flood.conf
 +ln -sf "${FAIL2BAN_FILTER_D}/nginx-dos-block.conf" /etc/fail2ban/filter.d/nginx-dos-block.conf
 +
 +log_info "Фильтры созданы"
 +echo ""
 +
 +################################################################################
 +# Шаг 7: Создание конфигурации jail
 +################################################################################
 +
 +log_info "Создание конфигурации jail..."
 +
 +cat > "${FAIL2BAN_JAIL_D}/nginx-protection.conf" << JAIL_EOF
 +[DEFAULT]
 +bantime = 3600
 +findtime = 300
 +ignoreip = ${IGNORE_IP}
 +
 +[nginx-scan-block]
 +enabled = true
 +port = http,https
 +filter = nginx-scan-block
 +logpath = ${NGINX_ACCESS_LOG}
 +backend = polling
 +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 = ${NGINX_ACCESS_LOG}
 +backend = polling
 +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 = ${NGINX_ACCESS_LOG}
 +backend = polling
 +maxretry = 10
 +bantime = 3600
 +findtime = 600
 +action = iptables-multiport[name=nginx-404, port="http,https", protocol=tcp]
 +JAIL_EOF
 +
 +ln -sf "${FAIL2BAN_JAIL_D}/nginx-protection.conf" /etc/fail2ban/jail.d/nginx-protection.conf
 +
 +log_info "Конфигурация jail создана"
 +echo ""
 +
 +################################################################################
 +# Шаг 8: Тестирование
 +################################################################################
 +
 +log_info "Тестирование конфигурации..."
 +
 +if fail2ban-client -t; then
 +    log_info "Конфигурация корректна"
 +else
 +    log_error "Ошибка в конфигурации"
 +    exit 1
 +fi
 +echo ""
 +
 +log_info "Тестирование фильтров..."
 +
 +fail2ban-regex "${NGINX_ACCESS_LOG}" "${FAIL2BAN_FILTER_D}/nginx-scan-block.conf" | grep -E "Failregex:|matched"
 +fail2ban-regex "${NGINX_ACCESS_LOG}" "${FAIL2BAN_FILTER_D}/nginx-404-flood.conf" | grep -E "Failregex:|matched"
 +fail2ban-regex "${NGINX_ACCESS_LOG}" "${FAIL2BAN_FILTER_D}/nginx-dos-block.conf" | grep -E "Failregex:|matched"
 +
 +echo ""
 +
 +################################################################################
 +# Шаг 9: Добавление в cron
 +################################################################################
 +
 +log_info "Добавление в cron..."
 +
 +CRON_ENTRY="*/2 * * * * ${FAIL2BAN_SCRIPTS}/parse-nginx-logs.sh"
 +
 +if crontab -l 2>/dev/null | grep -q "parse-nginx-logs.sh"; then
 +    log_warn "Уже добавлено в cron"
 +else
 +    (crontab -l 2>/dev/null; echo "$CRON_ENTRY") | crontab -
 +    log_info "Добавлено в cron"
 +fi
 +echo ""
 +
 +################################################################################
 +# Шаг 10: Запуск
 +################################################################################
 +
 +log_info "Запуск Fail2ban..."
 +
 +systemctl enable fail2ban >/dev/null 2>&1
 +systemctl restart fail2ban
 +
 +sleep 5
 +
 +if systemctl is-active --quiet fail2ban; then
 +    log_info "Fail2ban успешно запущен"
 +else
 +    log_error "Не удалось запустить Fail2ban"
 +    exit 1
 +fi
 +echo ""
 +
 +################################################################################
 +# Проверка
 +################################################################################
 +
 +log_info "Проверка jail..."
 +echo ""
 +
 +fail2ban-client status
 +
 +echo ""
 +fail2ban-client status nginx-scan-block
 +echo ""
 +fail2ban-client status nginx-404-flood
 +echo ""
 +fail2ban-client status nginx-dos-block
 +echo ""
 +
 +################################################################################
 +# Завершение
 +################################################################################
 +
 +log_info "=========================================="
 +log_info "Установка завершена успешно!"
 +log_info "=========================================="
 +echo ""
 +
 +echo "Создано:"
 +echo "  - Парсер: ${FAIL2BAN_SCRIPTS}/parse-nginx-logs.sh"
 +echo "  - Логи: ${NGINX_ACCESS_LOG}"
 +echo "  - Фильтры: ${FAIL2BAN_FILTER_D}/"
 +echo "  - Jail: ${FAIL2BAN_JAIL_D}/nginx-protection.conf"
 +echo ""
 +
 +echo "Защита:"
 +echo "  ✅ nginx-scan-block (3 попытки, бан 2 часа)"
 +echo "  ✅ nginx-404-flood (10 попыток, бан 1 час)"
 +echo "  ✅ nginx-dos-block (50/мин, бан 10 минут)"
 +echo "  ✅ sshd"
 +echo ""
 +
 +echo "Команды:"
 +echo "  fail2ban-client status"
 +echo "  fail2ban-client status nginx-scan-block"
 +echo "  iptables -L f2b-nginx-scan -n -v"
 +echo "  tail -f /var/log/fail2ban.log"
 +echo "  fail2ban-client unban IP"
 +echo ""
 +
 +cat > "${FAIL2BAN_BASE}/README.md" << 'README_EOF'
 +# Fail2ban для Nginx Proxy Manager
 +
 ## Управление ## Управление
  
Строка 29: Строка 463:
 ``` ```
  
-## Настройка параметров+## Настройка
  
-Редактировать файл: `/opt/fail2ban/config/jail.d/nginx-protection.conf`+Файл: `/opt/fail2ban/config/jail.d/nginx-protection.conf`
  
-`maxretryколичество попыток до бана +- maxretry - попытки до бана 
-`findtimeвременное окно поиска (секунды) +- findtime - окно поиска (секунды) 
-`bantime- время бана (секунды) +- bantime - время бана (секунды) 
-`ignoreip- игнорируемые IP+- ignoreip - исключения
  
 После изменений: После изменений:
Строка 45: Строка 479:
 ## Мониторинг ## Мониторинг
  
-### Просмотр забаненных IP+### Забаненные IP
 ```bash ```bash
 iptables -L f2b-nginx-scan -n -v iptables -L f2b-nginx-scan -n -v
Строка 62: Строка 496:
 README_EOF README_EOF
  
-log_info "Создан README файл: ${FAIL2BAN_BASE}/README.md" +log_info "Установка завершена! Сервер защищен 🛡️"
-echo "" +
- +
-log_info "Установка завершена! Ваш сервер защищен 🛡️"+
 </code> </code>
  
Строка 104: Строка 535:
 ========================================== ==========================================
  
-Создано: +Защита: 
-  - Скрипт парсера: /opt/fail2ban/scripts/parse-nginx-logs.sh +  ✅ nginx-scan-block (3 попытки, бан 2 часа) 
-  - Лог-файл: /opt/fail2ban/logs/nginx-access.log +  ✅ nginx-404-flood (10 попыток, бан 1 час) 
-  - Фильтры: /opt/fail2ban/config/filter.d/ +  ✅ nginx-dos-block (50/мин, бан 10 минут) 
-  - Конфигурация jail: /opt/fail2ban/config/jail.d/nginx-protection.conf +  ✅ sshd
- +
-Активные защиты+
-  ✅ nginx-scan-block - Блокировка сканирования (maxretry: 3, bantime: 2 часа) +
-  ✅ nginx-404-flood - Блокировка 404 флуда (maxretry: 10, bantime: 1 час) +
-  ✅ nginx-dos-block - Блокировка DoS (maxretry: 50/мин, bantime: 10 минут) +
-  ✅ sshd - Защита SSH+
 </code> </code>
  
Строка 134: Строка 559:
 </code> </code>
  
-==== Создание парсера логов Nginx Proxy Manager ==== +==== Создание парсера логов ====
- +
-Создайте файл /opt/fail2ban/scripts/parse-nginx-logs.sh:+
  
 <code bash> <code bash>
-cat > /opt/fail2ban/scripts/parse-nginx-logs.sh << 'EOF' +nano /opt/fail2ban/scripts/parse-nginx-logs.sh
-#!/bin/bash +
-# Скрипт парсинга логов nginx-proxy-manager для fail2ban +
-# Обрабатывает все access логи из папки nginxpm +
- +
-LOG_DIR="/opt/nginxpm/data/logs" +
-LOG_FILE="/opt/fail2ban/logs/nginx-access.log" +
-CONTAINER_NAME="nginxpm" +
-PARSER_LOG="/opt/fail2ban/logs/parser.log" +
- +
-# Создаем директории если они не существуют +
-mkdir -p "$(dirname "$LOG_FILE")" "$(dirname "$PARSER_LOG")" +
- +
-# Проверяем, что контейнер запущен +
-if ! docker ps --format "table {{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then +
-    echo "$(date): Контейнер $CONTAINER_NAME не найден или не запущен" >> "$PARSER_LOG" +
-    exit 1 +
-fi +
- +
-# Проверяем существование директории с логами +
-if [ ! -d "$LOG_DIR" ]; then +
-    echo "$(date): Директория логов $LOG_DIR не найдена" >> "$PARSER_LOG" +
-    exit 1 +
-fi +
- +
-# Очищаем целевой файл +
-> "$LOG_FILE" +
- +
-# Счетчик обработанных файлов и строк +
-processed_files=0 +
-total_lines=0 +
- +
-# Обрабатываем все файлы с окончанием *_access.log +
-for logfile in "$LOG_DIR"/proxy-host-*_access.log; do +
-    # Проверяем, что файл существует (на случай если паттерн не найден) +
-    if [ -f "$logfile" ]; then +
-        lines_from_file=$(tail -n 2000 "$logfile" | wc -l) +
-        tail -n 2000 "$logfile" >> "$LOG_FILE" +
-        processed_files=$((processed_files + 1)) +
-        total_lines=$((total_lines + lines_from_file)) +
-        echo "$(date): Обработан файл: $(basename "$logfile") - $lines_from_file строк" >> "$PARSER_LOG" +
-    fi +
-done +
- +
-# Если не найдено ни одного файла логов +
-if [ $processed_files -eq 0 ]; then +
-    echo "$(date): Не найдено файлов логов *_access.log в директории $LOG_DIR" >> "$PARSER_LOG" +
-    # Создаем пустой файл чтобы fail2ban не ругался +
-    touch "$LOG_FILE" +
-fi +
- +
-# Устанавливаем права доступа +
-chmod 644 "$LOG_FILE" +
- +
-# Логируем статистику каждый час (когда минуты = 00) +
-MINUTE=$(date +%M) +
-if [ "$MINUTE" = "00" ]; then +
-    final_lines=$(wc -l < "$LOG_FILE" 2>/dev/null || echo "0"+
-    echo "$(date): Итого обработано $processed_files файлов, $final_lines записей из контейнера $CONTAINER_NAME" >> "$PARSER_LOG" +
-fi +
- +
-# Ротация логов parser.log (если больше 5MB) +
-if [ -f "$PARSER_LOG" ] && [ $(stat -c%s "$PARSER_LOG" 2>/dev/null || echo 0) -gt 5242880 ]; then +
-    mv "$PARSER_LOG" "$PARSER_LOG.old" +
-    touch "$PARSER_LOG" +
-    chmod 644 "$PARSER_LOG" +
-fi +
- +
-# Удаление записей старше 30 дней из лог-файла +
-if [ -f "$LOG_FILE" ] && [ -s "$LOG_FILE" ]; then +
-    CUTOFF_DATE=$(date -d '30 days ago' '+%d/%b/%Y'+
-    TEMP_FILTERED="/tmp/nginx-filtered-logs" +
-     +
-    # Фильтруем записи не старше 30 дней +
-    awk -v cutoff="$CUTOFF_DATE"+
-    { +
-        # Извлекаем дату из строки лога (формат: DD/MMM/YYYY) +
-        match($0, /\[([0-9]{2}\/[A-Za-z]{3}\/[0-9]{4})/, date_match) +
-        if (date_match[1]) { +
-            # Преобразуем дату в timestamp для сравнения +
-            cmd = "date -d \"" date_match[1] "\" +%s 2>/dev/null" +
-            cmd | getline log_timestamp +
-            close(cmd) +
-             +
-            cmd2 = "date -d \"" cutoff "\" +%s 2>/dev/null" +
-            cmd2 | getline cutoff_timestamp +
-            close(cmd2) +
-             +
-            # Если дата лога >= даты отсечки, выводим строку +
-            if (log_timestamp >= cutoff_timestamp) { +
-                print $0 +
-            } +
-        } else { +
-            # Если не удалось извлечь дату, оставляем запись +
-            print $0 +
-        } +
-    }' "$LOG_FILE" > "$TEMP_FILTERED" +
-     +
-    # Заменяем оригинальный файл отфильтрованным +
-    if [ -f "$TEMP_FILTERED" ]; then +
-        mv "$TEMP_FILTERED" "$LOG_FILE" +
-        chmod 644 "$LOG_FILE" +
-    fi +
-fi +
- +
-# Ротация основного лог-файла (если больше 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" +
-    echo "$(date): Выполнена ротация лог-файла $LOG_FILE" >> "$PARSER_LOG" +
-fi +
- +
-exit 0 +
-EOF+
 </code> </code>
  
-Установка прав на скрипт:+Содержимое файла указано в автоматическом скрипте выше (раздел PARSER_EOF). 
 + 
 +Установка прав:
  
 <code bash> <code bash>
Строка 262: Строка 573:
 </code> </code>
  
-Первый запуск парсера:+Первый запуск:
  
 <code bash> <code bash>
 /opt/fail2ban/scripts/parse-nginx-logs.sh /opt/fail2ban/scripts/parse-nginx-logs.sh
 ls -lh /opt/fail2ban/logs/nginx-access.log ls -lh /opt/fail2ban/logs/nginx-access.log
-tail -10 /opt/fail2ban/logs/nginx-access.log 
 </code> </code>
  
-Добавление скрипта в cron:+Добавление в cron:
  
 <code bash> <code bash>
 (crontab -l 2>/dev/null; echo "*/2 * * * * /opt/fail2ban/scripts/parse-nginx-logs.sh") | crontab - (crontab -l 2>/dev/null; echo "*/2 * * * * /opt/fail2ban/scripts/parse-nginx-logs.sh") | crontab -
-</code> 
- 
-Проверка добавления в cron: 
- 
-<code bash> 
 crontab -l crontab -l
 </code> </code>
  
-==== Настройка фильтров Fail2ban ==== +==== Создание фильтров ====
- +
-Создание фильтра для блокировки сканирования:+
  
 <code bash> <code bash>
 +# Фильтр сканирования
 cat > /opt/fail2ban/config/filter.d/nginx-scan-block.conf << 'EOF' cat > /opt/fail2ban/config/filter.d/nginx-scan-block.conf << 'EOF'
 [Definition] [Definition]
  
-# Формат NPM: [DATE] - STATUS STATUS - METHOD PROTOCOL DOMAIN "PATH" [Client IP] 
 failregex = ^\[.*\] - \d+ \d+ - GET https? .* ".*(/\.env|/\.git|/\.aws|/\.ssh|/config|/backup|wp-config|phpinfo|admin/config|server-status|server-info).*" \[Client <HOST>\] failregex = ^\[.*\] - \d+ \d+ - GET https? .* ".*(/\.env|/\.git|/\.aws|/\.ssh|/config|/backup|wp-config|phpinfo|admin/config|server-status|server-info).*" \[Client <HOST>\]
             ^\[.*\] - 40\d \d+ - GET https? .* ".*\.(php|asp|jsp|cgi|pl|py).*" \[Client <HOST>\]             ^\[.*\] - 40\d \d+ - GET https? .* ".*\.(php|asp|jsp|cgi|pl|py).*" \[Client <HOST>\]
Строка 301: Строка 604:
 ignoreregex = ignoreregex =
 EOF EOF
-</code> 
  
-Создание фильтра для блокировки 404 флуда: +# Фильтр 404
- +
-<code bash>+
 cat > /opt/fail2ban/config/filter.d/nginx-404-flood.conf << 'EOF' cat > /opt/fail2ban/config/filter.d/nginx-404-flood.conf << 'EOF'
 [Definition] [Definition]
  
-# Блокировка множественных 404 ошибок 
 failregex = ^\[.*\] - 404 \d+ - (GET|POST|HEAD) https? .* ".*" \[Client <HOST>\] failregex = ^\[.*\] - 404 \d+ - (GET|POST|HEAD) https? .* ".*" \[Client <HOST>\]
  
 ignoreregex = ignoreregex =
 EOF EOF
-</code> 
  
-Создание фильтра для блокировки DoS+# Фильтр DoS
- +
-<code bash>+
 cat > /opt/fail2ban/config/filter.d/nginx-dos-block.conf << 'EOF' cat > /opt/fail2ban/config/filter.d/nginx-dos-block.conf << 'EOF'
 [Definition] [Definition]
  
-# Блокировка слишком частых запросов (DoS) 
 failregex = ^\[.*\] - \d+ \d+ - (GET|POST|HEAD) https? .* ".*" \[Client <HOST>\] failregex = ^\[.*\] - \d+ \d+ - (GET|POST|HEAD) https? .* ".*" \[Client <HOST>\]
  
 ignoreregex = ^\[.*\] - \d+ \d+ - (GET|POST) https? .* ".*\.(css|js|jpg|jpeg|png|gif|ico|woff|woff2|ttf|svg).*" \[Client <HOST>\] ignoreregex = ^\[.*\] - \d+ \d+ - (GET|POST) https? .* ".*\.(css|js|jpg|jpeg|png|gif|ico|woff|woff2|ttf|svg).*" \[Client <HOST>\]
 EOF EOF
-</code> 
  
-Создание символических ссылок на фильтры: +Символические ссылки 
- +ln -sf /opt/fail2ban/config/filter.d/nginx-scan-block.conf /etc/fail2ban/filter.d/ 
-<code bash> +ln -sf /opt/fail2ban/config/filter.d/nginx-404-flood.conf /etc/fail2ban/filter.d/ 
-ln -sf /opt/fail2ban/config/filter.d/nginx-scan-block.conf /etc/fail2ban/filter.d/nginx-scan-block.conf +ln -sf /opt/fail2ban/config/filter.d/nginx-dos-block.conf /etc/fail2ban/filter.d/
-ln -sf /opt/fail2ban/config/filter.d/nginx-404-flood.conf /etc/fail2ban/filter.d/nginx-404-flood.conf +
-ln -sf /opt/fail2ban/config/filter.d/nginx-dos-block.conf /etc/fail2ban/filter.d/nginx-dos-block.conf+
 </code> </code>
  
-==== Настройка jail для Nginx Proxy Manager ====+==== Создание конфигурации jail ====
  
-**ВАЖНО:** Замените IP адреса в параметре ''ignoreip'' на свои локальные сети и доверенные IP.+**ВАЖНО:** Замените IP адреса в параметре ''ignoreip'' на свои.
  
 <code bash> <code bash>
 cat > /opt/fail2ban/config/jail.d/nginx-protection.conf << 'EOF' cat > /opt/fail2ban/config/jail.d/nginx-protection.conf << 'EOF'
-# Jail конфигурация для nginx защиты 
 [DEFAULT] [DEFAULT]
-# Время бана в секундах (1 час = 3600) 
 bantime = 3600 bantime = 3600
-# Время поиска нарушений (5 минут = 300) 
 findtime = 300 findtime = 300
-# Игнорировать локальные IP 
 ignoreip = 127.0.0.1/8 ::1 192.168.0.0/24 172.16.0.0/12 10.0.0.0/8 ignoreip = 127.0.0.1/8 ::1 192.168.0.0/24 172.16.0.0/12 10.0.0.0/8
  
Строка 385: Строка 673:
 action = iptables-multiport[name=nginx-404, port="http,https", protocol=tcp] action = iptables-multiport[name=nginx-404, port="http,https", protocol=tcp]
 EOF EOF
-</code> 
  
-Создание символической ссылки на jail: +ln -sf /opt/fail2ban/config/jail.d/nginx-protection.conf /etc/fail2ban/jail.d/
- +
-<code bash> +
-ln -sf /opt/fail2ban/config/jail.d/nginx-protection.conf /etc/fail2ban/jail.d/nginx-protection.conf+
 </code> </code>
  
-==== Тестирование конфигурации ==== +==== Тестирование и запуск ====
- +
-Проверка синтаксиса конфигурации:+
  
 <code bash> <code bash>
 +# Тест конфигурации
 fail2ban-client -t fail2ban-client -t
-</code> 
  
-Ожидаемый результат: +Тест фильтров
-<code> +
-OK: configuration test is successful +
-</code> +
- +
-Тестирование фильтров на реальных логах: +
- +
-<code bash>+
 fail2ban-regex /opt/fail2ban/logs/nginx-access.log /opt/fail2ban/config/filter.d/nginx-scan-block.conf fail2ban-regex /opt/fail2ban/logs/nginx-access.log /opt/fail2ban/config/filter.d/nginx-scan-block.conf
-fail2ban-regex /opt/fail2ban/logs/nginx-access.log /opt/fail2ban/config/filter.d/nginx-404-flood.conf 
-fail2ban-regex /opt/fail2ban/logs/nginx-access.log /opt/fail2ban/config/filter.d/nginx-dos-block.conf 
-</code> 
  
-Должны быть найдены совпадения (matched > 0). +Запуск
- +
-==== Запуск и включение автозагрузки ==== +
- +
-<code bash> +
-# Включить автозагрузку+
 systemctl enable fail2ban systemctl enable fail2ban
- 
-# Запустить службу 
 systemctl start fail2ban systemctl start fail2ban
- 
-# Проверить статус 
 systemctl status fail2ban systemctl status fail2ban
 </code> </code>
  
 ===== Проверка работы ===== ===== Проверка работы =====
- 
-==== Проверка активных jail ==== 
  
 <code bash> <code bash>
 +# Статус jail
 fail2ban-client status fail2ban-client status
-</code>+fail2ban-client status nginx-scan-block
  
-Ожидаемый вывод: +# Правила iptables 
-<code> +iptables --n | grep nginx 
-Status +iptables -L f2b-nginx-scan --v
-|Number of jail:      4 +
-`Jail list:   nginx-404-flood, nginx-dos-block, nginx-scan-block, sshd+
 </code> </code>
  
-==== Проверка статуса конкретного jail ====+===== Управление ===== 
 + 
 +==== Проверка статуса ====
  
 <code bash> <code bash>
 +fail2ban-client status
 fail2ban-client status nginx-scan-block fail2ban-client status nginx-scan-block
-fail2ban-client status nginx-404-flood 
-fail2ban-client status nginx-dos-block 
-</code> 
- 
-Пример вывода: 
-<code> 
-Status for the jail: nginx-scan-block 
-|- Filter 
-|  |- Currently failed: 5 
-|  |- Total failed:     176 
-|  `- File list:        /opt/fail2ban/logs/nginx-access.log 
-`- Actions 
-   |- Currently banned: 2 
-   |- Total banned:     2 
-   `- Banned IP list:   3.96.220.169 56.228.32.138 
 </code> </code>
  
-==== Проверка правил iptables ====+==== Разбан IP ====
  
 <code bash> <code bash>
-iptables --n | grep -E "Chain|nginx"+fail2ban-client unban 1.2.3.4 
 +fail2ban-client set nginx-scan-block unbanip 1.2.3.4
 </code> </code>
  
-Ожидаемый результат: +==== Ручной бан ====
-<code> +
-Chain INPUT (policy ACCEPT) +
-f2b-nginx-dos  6    --  0.0.0.0/           0.0.0.0/           multiport dports 80,443 +
-f2b-nginx-404  6    --  0.0.0.0/           0.0.0.0/           multiport dports 80,443 +
-f2b-nginx-scan  6    --  0.0.0.0/           0.0.0.0/           multiport dports 80,443 +
-Chain f2b-nginx-404 (1 references) +
-Chain f2b-nginx-dos (1 references) +
-Chain f2b-nginx-scan (1 references) +
-</code>+
  
-Детальный просмотр забаненных IP: 
 <code bash> <code bash>
-iptables -L f2b-nginx-scan -n -v +fail2ban-client set nginx-scan-block banip 1.2.3.4
-iptables -L f2b-nginx-404 -n -v +
-iptables -L f2b-nginx-dos -n -v+
 </code> </code>
  
-===== Мониторинг ===== +==== Просмотр логов ====
- +
-==== Просмотр логов Fail2ban ====+
  
 <code bash> <code bash>
-# Последние 50 строк +tail -/var/log/fail2ban.log 
-tail -50 /var/log/fail2ban.log +tail -f /opt/fail2ban/logs/parser.log
- +
-# Только баны+
 tail -100 /var/log/fail2ban.log | grep -E "Ban|Unban" tail -100 /var/log/fail2ban.log | grep -E "Ban|Unban"
- 
-# Мониторинг в реальном времени 
-tail -f /var/log/fail2ban.log 
 </code> </code>
  
-==== Просмотр логов парсера ====+===== Настройка параметров =====
  
-<code bash> +^ Параметр ^ Описание ^ Значение ^ 
-tail -50 /opt/fail2ban/logs/parser.log +| maxretry | Попытки до бана | 3-10 для scan, 50 для DoS | 
-</code>+| findtime | Окно поиска (секунды) | 300 (5 минут) | 
 +| bantime | Время бана (секунды) | 3600-7200 (1-2 часа) |
  
-==== Общая статистика ====+Файл: ''/opt/fail2ban/config/jail.d/nginx-protection.conf''
  
-<code bash> +После изменений:
-echo "=== NGINX SCAN BLOCK ===" +
-fail2ban-client status nginx-scan-block +
-echo "" +
-echo "=== NGINX 404 FLOOD ===" +
-fail2ban-client status nginx-404-flood +
-echo "" +
-echo "=== NGINX DOS BLOCK ===" +
-fail2ban-client status nginx-dos-block +
-</code> +
- +
-===== Управление банами ===== +
- +
-==== Разбан IP адреса ====+
  
 <code bash> <code bash>
-# Разбан в конкретном jail +systemctl restart fail2ban
-fail2ban-client set nginx-scan-block unbanip 1.2.3.4 +
- +
-# Разбан во всех jail +
-fail2ban-client unban 1.2.3.4+
 </code> </code>
- 
-==== Ручной бан IP адреса ==== 
- 
-<code bash> 
-fail2ban-client set nginx-scan-block banip 1.2.3.4 
-</code> 
- 
-===== Настройка параметров защиты ===== 
- 
-==== Описание параметров jail ==== 
- 
-^ Параметр ^ Описание ^ Рекомендуемое значение ^ 
-| ''maxretry'' | Количество попыток до бана | 3-10 для scan, 50 для DoS, 10 для 404 | 
-| ''findtime'' | Временное окно поиска нарушений (секунды) | 300 (5 минут) | 
-| ''bantime'' | Время бана (секунды) | 3600-7200 (1-2 часа) | 
- 
-==== nginx-scan-block (сканирование) ==== 
- 
-  * **maxretry**: 3 попытки 
-  * **findtime**: 300 секунд (5 минут) 
-  * **bantime**: 7200 секунд (2 часа) 
- 
-Блокирует попытки доступа к: 
-  * Конфигурационным файлам (.env, .git, wp-config.php) 
-  * Скриптам (.php, .asp, .jsp, .cgi) 
-  * SQL инъекциям 
-  * XSS атакам 
-  * Path traversal 
- 
-==== nginx-404-flood (404 флуд) ==== 
- 
-  * **maxretry**: 10 попыток 
-  * **findtime**: 600 секунд (10 минут) 
-  * **bantime**: 3600 секунд (1 час) 
- 
-Блокирует множественные запросы к несуществующим страницам. 
- 
-==== nginx-dos-block (DoS атаки) ==== 
- 
-  * **maxretry**: 50 запросов 
-  * **findtime**: 60 секунд (1 минута) 
-  * **bantime**: 600 секунд (10 минут) 
- 
-Блокирует слишком частые запросы, игнорируя статические файлы (css, js, изображения). 
  
 ===== Troubleshooting ===== ===== Troubleshooting =====
Строка 583: Строка 753:
 ==== Fail2ban не запускается ==== ==== Fail2ban не запускается ====
  
-Проверка логов: 
 <code bash> <code bash>
 journalctl -xeu fail2ban journalctl -xeu fail2ban
-systemctl status fail2ban 
-</code> 
- 
-Проверка конфигурации: 
-<code bash> 
 fail2ban-client -d fail2ban-client -d
 </code> </code>
  
-==== Jail не банит атаки ====+==== Jail не банит ====
  
-Проверка чтения лог-файла: 
 <code bash> <code bash>
 fail2ban-client status nginx-scan-block fail2ban-client status nginx-scan-block
 </code> </code>
  
-Должно быть ''File list: /opt/fail2ban/logs/nginx-access.log'', а не ''Journal matches''.+Должно быть''File list: /opt/fail2ban/logs/nginx-access.log''
  
-Если видите ''Journal matches'', убедитесь что в конфигурации jail указан ''backend = polling''.+Если ''Journal matches'' - добавьте ''backend = polling'' в jail.
  
-==== Фильтры не находят совпадений ====+==== Фильтры не работают ====
  
-Тестирование фильтра: 
 <code bash> <code bash>
 fail2ban-regex /opt/fail2ban/logs/nginx-access.log /opt/fail2ban/config/filter.d/nginx-scan-block.conf --print-all-matched fail2ban-regex /opt/fail2ban/logs/nginx-access.log /opt/fail2ban/config/filter.d/nginx-scan-block.conf --print-all-matched
-</code> 
- 
-Проверка формата логов: 
-<code bash> 
 head -3 /opt/fail2ban/logs/nginx-access.log head -3 /opt/fail2ban/logs/nginx-access.log
 </code> </code>
  
-Формат должен быть: +==== Парсер не работает ====
-<code> +
-[DATE] - STATUS STATUS - METHOD PROTOCOL DOMAIN "PATH" [Client IP] ... +
-</code>+
  
-==== Парсер не создает лог-файл ==== 
- 
-Проверка работы парсера: 
 <code bash> <code bash>
 bash -x /opt/fail2ban/scripts/parse-nginx-logs.sh bash -x /opt/fail2ban/scripts/parse-nginx-logs.sh
 cat /opt/fail2ban/logs/parser.log cat /opt/fail2ban/logs/parser.log
-</code> +ls -la /opt/nginxpm/data/logs/
- +
-Проверка наличия логов Nginx Proxy Manager: +
-<code bash> +
-ls -la /opt/nginxpm/data/logs/proxy-host-*_access.log +
-</code> +
- +
-Проверка работы контейнера: +
-<code bash>+
 docker ps | grep nginxpm docker ps | grep nginxpm
-</code> 
- 
-===== Автоматическое обновление ===== 
- 
-Fail2ban обновляется вместе с системой: 
- 
-<code bash> 
-apt update 
-apt upgrade fail2ban -y 
-systemctl restart fail2ban 
 </code> </code>
  
 ===== Резервное копирование ===== ===== Резервное копирование =====
- 
-==== Файлы для бэкапа ==== 
- 
-<code bash> 
-# Конфигурация 
-/opt/fail2ban/config/ 
- 
-# Скрипты 
-/opt/fail2ban/scripts/ 
- 
-# Логи (опционально) 
-/opt/fail2ban/logs/ 
-</code> 
- 
-==== Создание бэкапа ==== 
  
 <code bash> <code bash>
 tar -czf fail2ban-backup-$(date +%Y%m%d).tar.gz \ tar -czf fail2ban-backup-$(date +%Y%m%d).tar.gz \
   /opt/fail2ban/config/ \   /opt/fail2ban/config/ \
-  /opt/fail2ban/scripts/ +  /opt/fail2ban/scripts/
-  /etc/fail2ban/jail.d/nginx-protection.conf \ +
-  /etc/fail2ban/filter.d/nginx-*.conf+
 </code> </code>
  
Строка 678: Строка 795:
  
 <code bash> <code bash>
-# Остановить службу 
 systemctl stop fail2ban systemctl stop fail2ban
 systemctl disable fail2ban systemctl disable fail2ban
- 
-# Удалить пакет 
 apt remove --purge fail2ban -y apt remove --purge fail2ban -y
- 
-# Удалить конфигурацию 
 rm -rf /opt/fail2ban rm -rf /opt/fail2ban
 rm -f /etc/fail2ban/jail.d/nginx-protection.conf rm -f /etc/fail2ban/jail.d/nginx-protection.conf
-rm -f /etc/fail2ban/filter.d/nginx-scan-block.conf +rm -f /etc/fail2ban/filter.d/nginx-*.conf 
-rm -f /etc/fail2ban/filter.d/nginx-404-flood.conf +crontab -e  # Удалить строку с parse-nginx-logs.sh
-rm -f /etc/fail2ban/filter.d/nginx-dos-block.conf +
- +
-# Удалить из cron +
-crontab -e +
-# Удалить строку с parse-nginx-logs.sh +
- +
-# Очистить правила iptables+
 iptables -F iptables -F
 </code> </code>
- 
-===== Заключение ===== 
- 
-После выполнения всех шагов ваш сервер будет защищен от: 
-  * ✅ Сканирования уязвимостей 
-  * ✅ 404 флуда 
-  * ✅ DoS атак 
-  * ✅ SSH брутфорса 
- 
-Fail2ban автоматически: 
-  * Собирает логи из Nginx Proxy Manager каждые 2 минуты 
-  * Анализирует запросы на предмет атак 
-  * Блокирует подозрительные IP на уровне iptables 
-  * Автоматически разбанивает IP после истечения времени бана 
  
 ===== Полезные ссылки ===== ===== Полезные ссылки =====
  • vm/nginx/06-file2ban_v2.1764591401.txt.gz
  • Последнее изменение: 2025/12/01 12:16
  • admin