Настройка fail2ban для Nginx - защита от атак и брутфорса | AdminWiki

Настройка fail2ban для Nginx: Полное руководство по защите веб-сервера

18 декабря 2025 7 мин. чтения #devops #fail2ban #linux #nginx #безопасность #брандмауэр #защита

Представь, что твой Nginx-сервер постоянно атакуют: боты сканируют уязвимости, злоумышленники пытаются подобрать пароли, а логи забиваются тысячами запросов. Давай разберем, как использовать fail2ban для автоматической блокировки таких атак — это твой цифровой вышибала для веб-сервера.

Что такое fail2ban и зачем он нужен с Nginx?

Fail2ban — это система предотвращения вторжений, которая анализирует логи и автоматически блокирует IP-адреса, демонстрирующие подозрительное поведение. Для Nginx это означает защиту от:

  • Брутфорс-атак на админ-панели
  • Сканирования уязвимостей (например, попыток доступа к /wp-admin, /phpmyadmin)
  • DDoS-атак и чрезмерного количества запросов
  • Попыток SQL-инъекций и XSS
Важно: Fail2ban работает на уровне iptables/nftables, поэтому блокирует трафик до того, как он достигнет Nginx. Это снижает нагрузку на сервер.

Установка и базовая настройка fail2ban

Давай начнем с установки. Для Ubuntu/Debian:

bash
sudo apt update
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Для CentOS/RHEL:

bash
sudo yum install epel-release -y
sudo yum install fail2ban -y
sudo systemctl enable --now fail2ban

Основные конфигурационные файлы

Fail2ban использует два типа конфигов:

Файл Назначение Приоритет
/etc/fail2ban/jail.conf Основной конфиг (не редактировать!) Низкий
/etc/fail2ban/jail.local Пользовательские настройки Высокий
/etc/fail2ban/filter.d/ Каталог фильтров
Внимание: Никогда не редактируйте jail.conf напрямую! Создавайте jail.local или файлы в jail.d/. При обновлении fail2ban ваш jail.conf будет перезаписан.

Настройка fail2ban для защиты Nginx

Шаг 1: Базовые настройки в jail.local

Создаем или редактируем основной конфиг:

config
# /etc/fail2ban/jail.local
[DEFAULT]
# Адрес для уведомлений (опционально)
destemail = admin@yourdomain.com
sender = fail2ban@yourdomain.com

# Действия при блокировке
action = %(action_)s

# Время блокировки (в секундах)
bantime = 3600

# Окно времени для подсчета попыток
findtime = 600

# Количество попыток до блокировки
maxretry = 5

# Бэкенд для анализа логов
backend = auto

# Игнорируем локальные IP
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16 10.0.0.0/8

Шаг 2: Защита от сканирования уязвимостей

Создаем фильтр для блокировки сканеров уязвимостей:

config
# /etc/fail2ban/filter.d/nginx-scanners.conf
[Definition]
failregex = ^ -.*\"(GET|POST|HEAD).*(wp-admin|phpmyadmin|administrator|mysql|admin\.php|/admin/|/backup/|/config/|\.env|\.git).*\"
            ^ -.*\"(GET|POST|HEAD).*(/cgi-bin/|/shell\.|/cmd\.|/command\.).*\"

ignoreregex =

Добавляем тюрьму для этого фильтра:

config
# В /etc/fail2ban/jail.local добавляем:
[nginx-scanners]
enabled = true
port = http,https
filter = nginx-scanners
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 300
bantime = 86400
action = %(action_)s

Шаг 3: Защита от брутфорса на аутентификацию

Если у тебя есть защищенные базовой аутентификацией location-блоки:

config
# /etc/fail2ban/filter.d/nginx-auth.conf
[Definition]
failregex = ^ -.*\"(GET|POST).*\" 401
            ^ -.*\"(GET|POST).*\" 403

ignoreregex =
config
[nginx-auth]
enabled = true
port = http,https
filter = nginx-auth
logpath = /var/log/nginx/error.log
maxretry = 3
findtime = 300
bantime = 3600

Шаг 4: Защита от DDoS и лимит запросов

Используем модуль ngx_http_limit_req_module в Nginx вместе с fail2ban:

nginx
# В конфиге Nginx
http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;
    
    server {
        location / {
            limit_req zone=one burst=5 nodelay;
            # При превышении лимита возвращаем 503
            limit_req_status 503;
        }
    }
}

Фильтр для fail2ban:

config
# /etc/fail2ban/filter.d/nginx-limit-req.conf
[Definition]
failregex = ^ -.*\"(GET|POST|HEAD).*\" 503

ignoreregex =
config
[nginx-limit-req]
enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/access.log
maxretry = 2
findtime = 60
bantime = 1800

Мониторинг и управление fail2ban

Проверка статуса

bash
# Статус службы
sudo systemctl status fail2ban

# Статус тюрем
sudo fail2ban-client status

# Статус конкретной тюрьмы
sudo fail2ban-client status nginx-scanners

# Проверка логов fail2ban
sudo tail -f /var/log/fail2ban.log

Ручное управление блокировками

bash
# Разблокировать IP
sudo fail2ban-client set nginx-scanners unbanip 192.168.1.100

# Заблокировать IP вручную
sudo fail2ban-client set nginx-scanners banip 192.168.1.100

# Перезагрузить конфигурацию
sudo fail2ban-client reload

# Перезапустить конкретную тюрьму
sudo fail2ban-client restart nginx-scanners

Просмотр заблокированных IP

bash
# Через iptables
sudo iptables -L -n

# Через fail2ban
sudo fail2ban-client get nginx-scanners banned

Продвинутые настройки и оптимизация

Использование nftables вместо iptables

Для современных систем с systemd:

config
# В /etc/fail2ban/jail.local
[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables-allports

Настройка уведомлений на Telegram

bash
# Создаем скрипт для уведомлений
sudo nano /etc/fail2ban/action.d/telegram.conf
config
# /etc/fail2ban/action.d/telegram.conf
[Definition]
actionstart = 
actionstop = 
actioncheck = 
actionban = curl -s -X POST "https://api.telegram.org/bot/sendMessage" \
             -d chat_id= \
             -d text="[fail2ban] : IP  banned for  seconds"
actionunban =

Оптимизация для высоконагруженных серверов

config
# В /etc/fail2ban/jail.local
[DEFAULT]
# Увеличиваем размер буфера для логов
logbuffer = 1048576

# Используем более эффективный бэкенд
backend = pyinotify

# Увеличиваем лимиты для высоконагруженных серверов
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbmaxmatches = %(dbmaxmatches)s

# Оптимизация для большого количества правил
chain = INPUT
Совет: На высоконагруженных серверах рассмотрите использование отдельного лог-файла для подозрительных запросов через директиву `access_log` в Nginx с отдельным форматом.

Отладка и решение проблем

Тестирование фильтров

bash
# Тест фильтра с лог-файлом
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-scanners.conf

# Тест с конкретной строкой
sudo fail2ban-regex "192.168.1.100 - - [01/Jan/2023:12:00:00 +0000] \"GET /wp-admin HTTP/1.1\" 404 123" /etc/fail2ban/filter.d/nginx-scanners.conf

Частые проблемы и решения

Проблема Причина Решение
Fail2ban не блокирует IP Неправильный путь к логам или формат логов Проверь logpath и используй fail2ban-regex для теста
Высокая нагрузка на CPU Слишком сложные regex или большой лог-файл Упрости regex, используй ротацию логов
Блокировка легитимных пользователей Слишком строгие правила или низкий maxretry Добавь IP в ignoreip, увеличь maxretry
Правила iptables не применяются Конфликт с другими фаерволами (ufw, firewalld) Отключи другие фаерволы или настрой интеграцию

Интеграция с мониторингом

Для мониторинга fail2ban можно использовать:

  • Prometheus + Grafana: Используй экспортер fail2ban-prometheus-exporter
  • Zabbix: Шаблоны для мониторинга fail2ban
  • ELK Stack: Анализ логов fail2ban вместе с логами Nginx
  • Скрипты для сбора статистики:
bash
#!/bin/bash
# Статистика по заблокированным IP
JAILS=$(sudo fail2ban-client status | grep "Jail list" | sed 's/.*Jail list://' | tr ',' ' ')

for JAIL in $JAILS
do
  BANNED=$(sudo fail2ban-client status $JAIL | grep "Currently banned" | awk '{print $4}')
  echo "$JAIL: $BANNED заблокированных IP"
done
Важно: Регулярно проверяй логи fail2ban на предмет ложных срабатываний и корректируй фильтры. Слишком агрессивные настройки могут заблокировать легитимных пользователей.

Настройка fail2ban для Nginx — это не разовая задача, а процесс. Начни с базовых правил, наблюдай за работой системы, постепенно добавляй новые фильтры и оптимизируй существующие. Помни, что fail2ban — это лишь один из слоев защиты, и его нужно использовать в комплексе с другими мерами безопасности.

Поделиться:
Сохранить гайд? В закладки браузера