vm:nginx:05-file2ban

Различия

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

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

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
vm:nginx:05-file2ban [2025/11/09 21:10] adminvm:nginx:05-file2ban [2026/03/03 12:15] (текущий) – удалено admin
Строка 1: Строка 1:
-Как использовать /opt/fail2ban для конфигов 
-Самый универсальный способ — создать символические ссылки из /etc/fail2ban/jail.d и /etc/fail2ban/filter.d на соответствующие файлы и папки в /opt/fail2ban: 
  
-text 
-sudo ln -s /opt/fail2ban/config/jail.d/* /etc/fail2ban/jail.d/ 
-sudo ln -s /opt/fail2ban/config/filter.d/* /etc/fail2ban/filter.d/ 
- 
- 
- 
- 
-====== Настройка Fail2ban с Nginx Proxy Manager ====== 
- 
-===== Описание ===== 
- 
-Fail2ban - это система защиты от брутфорс атак и автоматизированных сканирований. В связке с Nginx Proxy Manager (nginxpm) обеспечивает автоматическую блокировку подозрительных IP-адресов на основе анализа логов доступа. 
- 
-===== Требования ===== 
- 
-  * Docker и docker-compose 
-  * Nginx Proxy Manager (nginxpm) 
-  * Ubuntu/Debian система 
-  * Права root или sudo 
- 
-===== Установка Fail2ban ===== 
- 
-<code bash> 
-# Обновление пакетов 
-sudo apt update 
- 
-# Установка fail2ban 
-sudo apt install fail2ban -y 
- 
-# Включение автозапуска 
-sudo systemctl enable fail2ban 
-sudo systemctl start fail2ban 
-</code> 
- 
-===== Структура конфигурации ===== 
- 
-<code> 
-/opt/fail2ban/ 
-├── scripts/ 
-│   ├── manage-fail2ban.sh     # Скрипт управления и мониторинга 
-│   └── parse-nginx-logs.sh    # Парсер логов nginxpm 
-├── logs/ 
-│   ├── nginx-access.log       # Обработанные логи для fail2ban (последний месяц) 
-│   └── parser.log             # Логи работы парсера 
-└── config/ 
-    ├── jail.local             # Конфигурация jail'ов 
-    └── filters/               # Кастомные фильтры 
-</code> 
- 
-===== Docker Compose конфигурация Nginx Proxy Manager ===== 
- 
-<code yaml> 
-services: 
-  app: 
-    image: 'jc21/nginx-proxy-manager:latest' 
-    container_name: nginxpm 
-    restart: always 
-    ports: 
-      - '80:80'     # HTTP 
-      - '443:443'   # HTTPS 
-    environment: 
-      DB_MYSQL_HOST: "db" 
-      DB_MYSQL_PORT: 3306 
-      DB_MYSQL_USER: "npm" 
-      DB_MYSQL_PASSWORD: "YOUR_PASSWORD" 
-      DB_MYSQL_NAME: "npm" 
-    volumes: 
-      - ./data:/data              # данные NPM 
-      - ./letsencrypt:/etc/letsencrypt  # сертификаты 
-    depends_on: 
-      - db 
-    networks: 
-      - webproxy 
- 
-  db: 
-    image: 'mariadb:10.11' 
-    container_name: nginxpm_db 
-    restart: always 
-    environment: 
-      MYSQL_ROOT_PASSWORD: "YOUR_ROOT_PASSWORD" 
-      MYSQL_DATABASE: "npm" 
-      MYSQL_USER: "npm" 
-      DB_MYSQL_PASSWORD: "YOUR_PASSWORD" 
-    volumes: 
-      - ./mysql:/var/lib/mysql    # база MariaDB 
-    networks: 
-      - webproxy 
- 
-networks: 
-  webproxy: 
-    external: true 
-</code> 
- 
-===== Создание директорий ===== 
- 
-<code bash> 
-# Создание структуры папок 
-sudo mkdir -p /opt/fail2ban/{scripts,logs,config,config/filters} 
-</code> 
- 
-===== Скрипт парсинга логов parse-nginx-logs.sh ===== 
- 
-Создать файл **/opt/fail2ban/scripts/parse-nginx-logs.sh**: 
- 
-<code bash> 
-#!/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 
- 
-# Дата отсечки (30 дней назад) для фильтрации логов 
-CUTOFF_DATE=$(date -d '30 days ago' '+%d/%b/%Y') 
-CUTOFF_TIMESTAMP=$(date -d '30 days ago' '+%s') 
- 
-# Обрабатываем все файлы с окончанием *_access.log 
-for logfile in "$LOG_DIR"/*_access.log; do 
-    # Проверяем, что файл существует (на случай если паттерн не найден) 
-    if [ -f "$logfile" ]; then 
-        # Читаем файл и фильтруем записи не старше 30 дней 
-        awk -v cutoff_ts="$CUTOFF_TIMESTAMP" ' 
-        { 
-            # Извлекаем дату из строки лога (формат: 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) 
-                 
-                # Если дата лога >= даты отсечки, выводим строку 
-                if (log_timestamp >= cutoff_ts) { 
-                    print $0 
-                } 
-            } else { 
-                # Если не удалось извлечь дату, оставляем запись 
-                print $0 
-            } 
-        }' "$logfile" >> "$LOG_FILE" 
-         
-        processed_files=$((processed_files + 1)) 
-        echo "$(date): Обработан файл: $(basename "$logfile") - отфильтрованы записи за последний месяц" >> "$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 
-    TEMP_FILTERED="/tmp/nginx-final-filtered" 
-     
-    # Финальная фильтрация собранного файла 
-    awk -v cutoff_ts="$CUTOFF_TIMESTAMP" ' 
-    { 
-        # Извлекаем дату из строки лога (формат: 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) 
-             
-            # Если дата лога >= даты отсечки, выводим строку 
-            if (log_timestamp >= cutoff_ts) { 
-                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 
-</code> 
- 
-===== Настройка прав доступа и cron ===== 
- 
-<code bash> 
-# Сделать скрипт исполняемым 
-sudo chmod +x /opt/fail2ban/scripts/parse-nginx-logs.sh 
- 
-# Создать задачу cron для автоматического запуска каждые 5 минут 
-sudo crontab -e 
- 
-# Добавить строку: 
-*/5 * * * * /opt/fail2ban/scripts/parse-nginx-logs.sh >/dev/null 2>&1 
-</code> 
- 
-===== Скрипт управления manage-fail2ban.sh ===== 
- 
-Создать файл **/opt/fail2ban/scripts/manage-fail2ban.sh**: 
- 
-<code bash> 
-#!/bin/bash 
-# Скрипт управления и мониторинга fail2ban 
- 
-case "$1" in 
-    status) 
-        echo "=== Статус fail2ban ===" 
-        fail2ban-client status 
-        echo "" 
-        echo "=== Детальная информация ===" 
-        for jail in $(fail2ban-client status | grep "Jail list:" | cut -d: -f2 | tr ',' '\n' | xargs); do 
-            echo "--- $jail ---" 
-            fail2ban-client status "$jail" 
-        done 
-        ;; 
-    reload) 
-        echo "Перезагрузка fail2ban..." 
-        systemctl reload fail2ban 
-        ;; 
-    restart) 
-        echo "Перезапуск fail2ban..." 
-        systemctl restart fail2ban 
-        ;; 
-    unban) 
-        if [ -z "$2" ]; then 
-            echo "Использование: $0 unban <IP>" 
-            exit 1 
-        fi 
-        echo "Разблокировка IP: $2" 
-        fail2ban-client unban "$2" 
-        ;; 
-    *) 
-        echo "Использование: $0 {status|reload|restart|unban <IP>}" 
-        exit 1 
-        ;; 
-esac 
-</code> 
- 
-<code bash> 
-# Сделать скрипт исполняемым 
-sudo chmod +x /opt/fail2ban/scripts/manage-fail2ban.sh 
-</code> 
- 
-===== Команды управления ===== 
- 
-==== Управление службой fail2ban ==== 
- 
-<code bash> 
-# Проверка статуса службы 
-sudo systemctl status fail2ban 
- 
-# Запуск службы 
-sudo systemctl start fail2ban 
- 
-# Остановка службы 
-sudo systemctl stop fail2ban 
- 
-# Перезапуск службы 
-sudo systemctl restart fail2ban 
- 
-# Включить автозапуск 
-sudo systemctl enable fail2ban 
-</code> 
- 
-==== Использование скрипта управления ==== 
- 
-<code bash> 
-# Показать статус всех jail'ов 
-sudo /opt/fail2ban/scripts/manage-fail2ban.sh status 
- 
-# Перезагрузить конфигурацию 
-sudo /opt/fail2ban/scripts/manage-fail2ban.sh reload 
- 
-# Перезапустить службу 
-sudo /opt/fail2ban/scripts/manage-fail2ban.sh restart 
- 
-# Разблокировать IP 
-sudo /opt/fail2ban/scripts/manage-fail2ban.sh unban 192.168.1.100 
-</code> 
- 
-===== Просмотр логов ===== 
- 
-==== Логи fail2ban ==== 
- 
-<code bash> 
-# Основные логи fail2ban 
-sudo tail -f /var/log/fail2ban.log 
- 
-# Логи через systemd 
-sudo journalctl -u fail2ban -f 
- 
-# Просмотр последних 100 записей 
-sudo journalctl -u fail2ban -n 100 
- 
-# Поиск конкретных событий 
-sudo grep "Ban " /var/log/fail2ban.log | tail -20 
-sudo grep "Unban " /var/log/fail2ban.log | tail -20 
-</code> 
- 
-==== Логи парсера nginx ==== 
- 
-<code bash> 
-# Лог работы парсера 
-sudo tail -f /opt/fail2ban/logs/parser.log 
- 
-# Просмотр обработанных логов nginx 
-sudo tail -f /opt/fail2ban/logs/nginx-access.log 
- 
-# Статистика размера логов 
-sudo ls -lah /opt/fail2ban/logs/ 
- 
-# Проверка последних записей в исходных логах nginxpm 
-sudo ls -la /opt/nginxpm/data/logs/ 
-sudo tail -10 /opt/nginxpm/data/logs/*_access.log 
- 
-# Подсчет строк в логах 
-sudo wc -l /opt/fail2ban/logs/nginx-access.log 
-sudo wc -l /opt/nginxpm/data/logs/*_access.log 
-</code> 
- 
-===== Диагностика и тестирование ===== 
- 
-==== Проверка работы парсера ==== 
- 
-<code bash> 
-# Запуск парсера вручную 
-sudo /opt/fail2ban/scripts/parse-nginx-logs.sh 
- 
-# Проверка размера результирующего лога 
-sudo wc -l /opt/fail2ban/logs/nginx-access.log 
- 
-# Проверка даты самых старых записей (должно быть не более месяца) 
-sudo head -5 /opt/fail2ban/logs/nginx-access.log 
-sudo tail -5 /opt/fail2ban/logs/nginx-access.log 
- 
-# Проверка что контейнер nginxpm запущен 
-sudo docker ps | grep nginxpm 
-</code> 
- 
-==== Тестирование фильтров ==== 
- 
-<code bash> 
-# Тест фильтра на соответствие логу 
-sudo fail2ban-regex /opt/fail2ban/logs/nginx-access.log /etc/fail2ban/filter.d/nginx-scan-block.conf 
- 
-# Проверка конкретного jail 
-sudo fail2ban-client status nginx-scan-block 
- 
-# Тест с выводом совпадений 
-sudo fail2ban-regex --print-all-matched /opt/fail2ban/logs/nginx-access.log /etc/fail2ban/filter.d/nginx-404-flood.conf 
-</code> 
- 
-===== Мониторинг системы ===== 
- 
-==== Ежедневные проверки ==== 
- 
-<code bash> 
-# Проверка статуса системы 
-sudo /opt/fail2ban/scripts/manage-fail2ban.sh status 
- 
-# Размер логов 
-sudo du -sh /opt/fail2ban/logs/ 
-sudo du -sh /opt/nginxpm/data/logs/ 
- 
-# Количество заблокированных IP 
-sudo fail2ban-client status | grep "Currently banned" 
- 
-# Статистика по jail'ам 
-sudo fail2ban-client status sshd 
-sudo fail2ban-client status nginx-404-flood 
-sudo fail2ban-client status nginx-scan-block 
-sudo fail2ban-client status nginx-dos-block 
-</code> 
- 
-==== Просмотр iptables правил ==== 
- 
-<code bash> 
-# Просмотр всех правил fail2ban 
-sudo iptables -L -n | grep f2b 
- 
-# Просмотр правил конкретного jail 
-sudo iptables -L f2b-nginx-scan-block -n 
- 
-# Подсчет заблокированных IP 
-sudo iptables -L f2b-nginx-scan-block -n | grep -c "REJECT" 
-</code> 
- 
-===== Особенности работы ===== 
- 
-  * **Полное пересоздание файла**: Файл ''nginx-access.log'' полностью пересоздается каждые 5 минут 
-  * **Фильтрация по времени**: Скрипт автоматически отбирает только записи за последний месяц (30 дней) 
-  * **Ротация логов**: Автоматическая ротация при превышении размера в 10MB 
-  * **Множественные хосты**: Обработка всех файлов ''*_access.log'' в папке nginxpm 
-  * **Регулярное обновление**: Запуск каждые 5 минут через cron 
-  * **Логирование процесса**: Подробные логи работы парсера в ''/opt/fail2ban/logs/parser.log'' 
- 
-===== Устранение неполадок ===== 
- 
-==== Типичные проблемы ==== 
- 
-<code bash> 
-# Проверка что директория nginxpm существует 
-sudo ls -la /opt/nginxpm/data/logs/ 
- 
-# Проверка прав доступа 
-sudo ls -la /opt/fail2ban/logs/ 
- 
-# Проверка cron задач 
-sudo crontab -l 
- 
-# Проверка запуска Docker контейнера 
-sudo docker logs nginxpm | tail -20 
- 
-# Проверка работы fail2ban 
-sudo systemctl is-active fail2ban 
-sudo systemctl is-enabled fail2ban 
-</code> 
- 
-==== Если нет блокировок ==== 
- 
-1. **Проверить наличие данных в логах**: 
-<code bash> 
-sudo cat /opt/fail2ban/logs/nginx-access.log | wc -l 
-</code> 
- 
-2. **Проверить работу фильтров**: 
-<code bash> 
-sudo fail2ban-regex /opt/fail2ban/logs/nginx-access.log /etc/fail2ban/filter.d/nginx-scan-block.conf 
-</code> 
- 
-3. **Проверить cron задачу**: 
-<code bash> 
-sudo systemctl status cron 
-sudo tail -f /var/log/syslog | grep CRON 
-</code> 
- 
-<note important> 
-Регулярно проверяйте работу системы командой ''sudo /opt/fail2ban/scripts/manage-fail2ban.sh status'' и следите за размером логов. 
-</note> 
- 
-<note tip> 
-Для тестирования можно добавить тестовую запись в лог и проверить срабатывание фильтров: 
-''echo '192.168.1.100 - - [01/Sep/2025:10:00:00 +0000] "GET /.env HTTP/1.1" 404 162 "-" "curl"' | sudo tee -a /opt/fail2ban/logs/nginx-access.log'' 
-</note> 
  • vm/nginx/05-file2ban.1762722647.txt.gz
  • Последнее изменение: 2025/11/09 21:10
  • admin