Коротко: fail2ban читает access-лог nginx и банит IP-адреса, которые ведут себя как боты: перебирают служебные пути (wp-login.php, .env), приходят с User-Agent скриптов или без него. Ниже готовые фильтры, jail и настройки nginx, которые мы проверили на тестовом логе командой fail2ban-regex и конфигом через nginx -t.

Если по разбору access-лога вы нашли ботов, следующий вопрос: как перестать пускать их автоматически. Самый доступный способ на своём сервере это fail2ban: он следит за логом и временно блокирует адреса по правилам. Он не заменяет полноценную защиту, но снимает основную массу простых сканеров.

Как это работает и чего ждать

  • fail2ban читает лог уже после того, как запрос обработан. Он не блокирует первый запрос, а банит адрес после нескольких срабатываний (параметр maxretry) за период (findtime).
  • Бан ставится на уровне файрвола сервера (iptables или nftables) на заданное время (bantime).
  • Правила описываются регулярными выражениями в файлах фильтров. Ошибка в выражении может забанить своих посетителей, поэтому каждое правило проверяйте командой fail2ban-regex до включения.

Фильтр 1: сканеры и служебные пути

Файл /etc/fail2ban/filter.d/nginx-bots.conf. Реагирует на запросы к служебным адресам, которые закончились ошибкой или отказом:

[Definition]
failregex = ^<HOST> .* "(GET|POST|HEAD) [^"]*(wp-login\.php|xmlrpc\.php|\.env|phpmyadmin|\.git/|wp-admin/setup-config\.php)[^"]*" (400|403|404|405|444)
ignoreregex =

Статус ответа в правиле важен: обычная страница входа WordPress отвечает 200 и под правило не попадёт, а сканер, который ищет несуществующий /.env, получает 404 и попадёт. Если на вашем сайте нет WordPress, любые обращения к wp-login.php это разведка.

Фильтр 2: скриптовые User-Agent и пустая строка

Файл /etc/fail2ban/filter.d/nginx-badua.conf:

[Definition]
failregex = ^<HOST> .* ".*" \d{3} \S+ ".*" "(python-requests|curl|Go-http-client|Scrapy|-)[^"]*"$
ignoreregex =

Правило ловит запросы, у которых User-Agent начинается с названия скриптового клиента или состоит из прочерка (пустая строка в логе). Осторожно: этими же клиентами могут пользоваться ваши собственные сервисы мониторинга и интеграции. Добавьте их адреса в белый список (ниже) и не делайте этот фильтр жёстким в первые дни.

Jail: что и как банить

Файл /etc/fail2ban/jail.local:

[nginx-bots]
enabled  = true
port     = http,https
filter   = nginx-bots
logpath  = /var/log/nginx/access.log
maxretry = 3
findtime = 600
bantime  = 3600
ignoreip = 127.0.0.1/8 ::1 ВАШ_IP

[nginx-badua]
enabled  = true
port     = http,https
filter   = nginx-badua
logpath  = /var/log/nginx/access.log
maxretry = 20
findtime = 600
bantime  = 3600
ignoreip = 127.0.0.1/8 ::1 ВАШ_IP

Для сканеров достаточно 3 срабатываний за 10 минут. Для скриптовых User-Agent порог выше (20), чтобы не зацепить единичные запросы. Подставьте в ignoreip свой адрес и адреса мониторинга. Включите fail2ban командой systemctl restart fail2ban и смотрите состояние: fail2ban-client status nginx-bots.

Сначала проверьте, потом включайте

Перед запуском прогоните фильтр по реальному логу, чтобы увидеть, кого он забанит:

fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-bots.conf
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-badua.conf

В выводе нужна строка Lines: ... matched. Посмотрите примеры совпавших строк: в них не должно быть ваших пользователей и поисковых ботов. Мы проверили оба фильтра на тестовом логе из девяти строк: фильтр сканеров совпал с четырьмя запросами сканеров (wp-login.php, .env, xmlrpc.php, phpmyadmin с ответом 4xx), а фильтр User-Agent с пятью запросами скриптов (python-requests, curl, Go-http-client, пустой User-Agent). Обычный браузер на странице входа (ответ 200) и Googlebot не совпали.

Что добавить на стороне nginx

fail2ban реагирует с задержкой, поэтому часть правил лучше выполнять в самом nginx. Проверенный конфиг (пример для nginx.conf, адреса и пути замените своими):

http {
    # скриптовые User-Agent и пустая строка
    map $http_user_agent $bad_ua {
        default 0;
        ""      1;
        ~*(python-requests|scrapy|go-http-client|libwww-perl|java/) 1;
    }

    # ограничение частоты запросов на IP
    limit_req_zone $binary_remote_addr zone=perip:10m rate=5r/s;

    server {
        # служебные пути, которых на сайте нет
        location ~* (wp-login\.php|xmlrpc\.php|/\.env|/\.git/|phpmyadmin) {
            return 444;
        }

        location / {
            if ($bad_ua) { return 403; }
            limit_req zone=perip burst=20 nodelay;
            # ... ваши настройки сайта ...
        }
    }
}

Код 444 это особый ответ nginx: он закрывает соединение без ответа, что отнимает у сканера время. Ограничение limit_req подбирайте под нагрузку: пять запросов в секунду с одного адреса достаточно для обычных посетителей, но может не хватить для интенсивного API.

Типичные ловушки

  • Сайт за CDN или обратным прокси. Если в логе адрес прокси, а не посетителя, fail2ban забанит прокси и «положит» весь сайт. Сначала настройте передачу реального IP (модуль realip и заголовок от CDN) и убедитесь, что в логе настоящие адреса.
  • Общие адреса (NAT, офис, мобильный оператор). Бан по IP зацепит всех, кто сидит за этим адресом. Поэтому начинайте с короткого bantime и порогов повыше.
  • Поисковые боты. Не банить «по User-Agent вслепую»: подлинность Googlebot и Яндекса проверяется по IP, см. как проверить, настоящий ли это Googlebot.
  • Боты за жилыми прокси. Каждый запрос идёт с нового адреса, поэтому бан по IP их не остановит.

Когда fail2ban недостаточно

fail2ban хорош для простых сканеров и перебора. Он не видит поведение, заголовки браузера, подлинность поисковых ботов, ротацию адресов и рекламный трафик. Для постоянной защиты нужен сервис, который проверяет каждый запрос на лету: Bot Guard делает это по User-Agent, IP, заголовкам и поведению, а подключается к WordPress плагином и к 1С-Битриксу модулем. Общие принципы ограничения частоты описаны в статье про rate limiting, а разобрать свой лог можно в бесплатном анализаторе.

Частые вопросы

Что такое fail2ban и для чего он нужен на сервере с nginx?

Это программа, которая читает журналы сервера и временно блокирует IP-адреса, ведущие себя как атакующие: перебирают пароли, ищут уязвимые страницы, шлют слишком много запросов. Для nginx ей нужен фильтр (регулярное выражение для строки лога) и jail (настройки: сколько срабатываний, на какое время банить).

Как проверить фильтр fail2ban, не рискуя забанить своих?

Запустите fail2ban-regex ЛОГ ФИЛЬТР: команда покажет, сколько строк лога совпало, и ничего не заблокирует. Добавьте свои адреса в ignoreip и начните с короткого времени бана.

Почему fail2ban не банит ботов сразу?

Он читает лог после запроса и банит адрес только после нескольких срабатываний за заданный период. Для мгновенных ответов используйте правила nginx: return 444 для служебных путей и limit_req для ограничения частоты.

Можно ли банить по User-Agent?

Можно, но только для явных скриптов и пустой строки, и с белым списком своих сервисов. Поисковых ботов по User-Agent банить нельзя: сначала проверяйте IP.

fail2ban заменяет защиту от ботов?

Нет. Он справляется с простыми сканерами. Боты за прокси, имитация браузера, поддельные поисковые боты и накрутка рекламы требуют проверки каждого запроса по нескольким признакам.

Защитите свой сайт от ботов прямо сейчас

Подключение занимает несколько минут — вставьте один PHP-сниппет, и Bot Guard начнёт фильтровать ботов, скрейперов и попытки SQL-инъекций автоматически.

Зарегистрироваться бесплатно
Заказать звонок

Читайте также

Что такое трафик PPC-ботов? 5 методов защиты рекламных кампаний
Сегодня мы расскажем, как выявить и уменьшить трафик PPC-ботов, чтобы уменьшить ненужные з…
Что такое взлом?
Взлом учетных данных — это процесс, при котором киберпреступники получают несанкционирован…
Туристические сайты: как быстро защитить свою инфраструктуру от атак ботов
Туристические сайты постоянно подвергаются атакам вредоносных ботов. Узнайте, как реализов…