Представь, что твой Nginx-сервер постоянно атакуют: боты сканируют уязвимости, злоумышленники пытаются подобрать пароли, а логи забиваются тысячами запросов. Давай разберем, как использовать fail2ban для автоматической блокировки таких атак — это твой цифровой вышибала для веб-сервера.
Что такое fail2ban и зачем он нужен с Nginx?
Fail2ban — это система предотвращения вторжений, которая анализирует логи и автоматически блокирует IP-адреса, демонстрирующие подозрительное поведение. Для Nginx это означает защиту от:
- Брутфорс-атак на админ-панели
- Сканирования уязвимостей (например, попыток доступа к /wp-admin, /phpmyadmin)
- DDoS-атак и чрезмерного количества запросов
- Попыток SQL-инъекций и XSS
Установка и базовая настройка fail2ban
Давай начнем с установки. Для Ubuntu/Debian:
sudo apt update
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Для CentOS/RHEL:
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/ | Каталог фильтров | — |
Настройка fail2ban для защиты Nginx
Шаг 1: Базовые настройки в jail.local
Создаем или редактируем основной конфиг:
# /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: Защита от сканирования уязвимостей
Создаем фильтр для блокировки сканеров уязвимостей:
# /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 =
Добавляем тюрьму для этого фильтра:
# В /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-блоки:
# /etc/fail2ban/filter.d/nginx-auth.conf
[Definition]
failregex = ^ -.*\"(GET|POST).*\" 401
^ -.*\"(GET|POST).*\" 403
ignoreregex =
[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
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:
# /etc/fail2ban/filter.d/nginx-limit-req.conf
[Definition]
failregex = ^ -.*\"(GET|POST|HEAD).*\" 503
ignoreregex =
[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
Проверка статуса
# Статус службы
sudo systemctl status fail2ban
# Статус тюрем
sudo fail2ban-client status
# Статус конкретной тюрьмы
sudo fail2ban-client status nginx-scanners
# Проверка логов fail2ban
sudo tail -f /var/log/fail2ban.log
Ручное управление блокировками
# Разблокировать 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
# Через iptables
sudo iptables -L -n
# Через fail2ban
sudo fail2ban-client get nginx-scanners banned
Продвинутые настройки и оптимизация
Использование nftables вместо iptables
Для современных систем с systemd:
# В /etc/fail2ban/jail.local
[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables-allports
Настройка уведомлений на Telegram
# Создаем скрипт для уведомлений
sudo nano /etc/fail2ban/action.d/telegram.conf
# /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 =
Оптимизация для высоконагруженных серверов
# В /etc/fail2ban/jail.local
[DEFAULT]
# Увеличиваем размер буфера для логов
logbuffer = 1048576
# Используем более эффективный бэкенд
backend = pyinotify
# Увеличиваем лимиты для высоконагруженных серверов
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbmaxmatches = %(dbmaxmatches)s
# Оптимизация для большого количества правил
chain = INPUT
Отладка и решение проблем
Тестирование фильтров
# Тест фильтра с лог-файлом
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
- Скрипты для сбора статистики:
#!/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 для Nginx — это не разовая задача, а процесс. Начни с базовых правил, наблюдай за работой системы, постепенно добавляй новые фильтры и оптимизируй существующие. Помни, что fail2ban — это лишь один из слоев защиты, и его нужно использовать в комплексе с другими мерами безопасности.