Debian.pro/

Про Debian


ddos-атака на wordpress-ы. Посылаем их лесом при помощи fail2ban.

Приветствую.

Не так давно началась атака на wordpress большим ботнетом. На хабре про неё писали даже. . Сначала я похихикал, а потом увидел масштабы.. Мхым. Так вот. Мои виртуалки (которые в целом ddos-атаки переживают без какого-либо вмешательства) начали загибаться. Во-первых, ботнет немаленький, во-вторых перебирают пароли активно, а в-третьих (и это главное) операция авторизации в wp достаточно тяжелая. В итоге сервер встаёт колом уже при 10-20 rps авторизаций, а там счет на сотни.

Пришли ко мне с этой проблемой, думать пришлось недолго — сразу вспомнился fail2ban. В лоб я написал простейшую конфигурацию — «если хост делает запросы вида POST /wp-login.php — его нужно забанить». В конфиге fail2ban выставлен лимит в 3 запроса за 10 минут (и бан на 10 минут, емнип) — этого вполне хватит — нормальный человек вообще больше одного запроса не сделает.

Так что здесь я оставлю состряпанный на коленке конфиг для fail2ban (а включив его вы уже сможете придумать более хитрый способ отсекать ботнет). Но я у себя оставлю эту конфигурацию (не потеряется и кушает меньше многих альтернативных вариантов + настройка действует сразу на все wp-блоги на сервере — а у меня много shared-серверов).

Для начала поставим fail2ban:

root@server:~# apt-get update; apt-get install fail2ban

Создадим конфиг для парсера. В файл /etc/fail2ban/filter.d/wp-ddos.conf пишем такое:

[Definition]
failregex = <HOST> .*POST /wp-login.php

Здесь приведен regexp, который сматчится в стандартный формат nginx-лога. Если у вас другой формат — пишите в комментариях пример строчки из лога, напишу вам другой regexp.

И добавим настройку для fail2ban — в конец файла /etc/fail2ban/jail.conf дописываем такое:

[wp-ddos]
enabled = true
port = 80,443
protocol = tcp
filter = wp-ddos
logpath = /var/log/nginx/access.log

И рестартим fail2ban:

root@server:~# /etc/init.d/fail2ban restart

Ну а дальше смотрим в iptables -L (или iptables -L -n) и наслаждаемся.

Подробнее про fail2ban я вот здесь писал.


Комментарии (17):

  1. wilful :

    Привет!

    А ты не используешь системы схожие с Cheef, Puppet, CFengine, etc.
    Я использую Puppet для контроля над серверами и в частности правил iptables, но пока не выдумал способа для корреляции f2b и iptables… Может у тебя есть рецепт?

  2. Chef я не использую.

    А зачем для него рецепты? Пусть себе пишет в iptables, да пишет.
    А вообще там как-то так:
    *filter
    :INPUT ACCEPT [6864:554156]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [6825:710138]
    :fail2ban-ssh — [0:0]
    :fail2ban-wp-ddos — [0:0]
    -A INPUT -p tcp -m multiport —dports 80,443 -j fail2ban-wp-ddos
    -A INPUT -p tcp -m multiport —dports 22 -j fail2ban-ssh
    -A fail2ban-ssh -j RETURN

    COMMIT

    А содержимое цепочки fail2ban-wp-ddos пусть игнорирует

  3. wilful :

    Проблема в том, что я не знаю как модулем puppetlabs firewall выставить игнорирование нужных цепочек (: А вручную лень прописывать правила, очень уж удобный модуль. По-этому и спросил, может уже приходилось тебе с такой проблемой столкнуться.

  4. Напишите авторам модуля тогда лучше =)
    Я думаю, они с подобной проблемой уже сталкивались.

  5. yukra :

    У меня на работе нет fail2ban, потому что Cpanel имеет cphulk, но cphulk работает только при авторизации. Поэтому мы разложили в .htaccess такое:
    ================

    Order Deny,Allow
    Deny from all
    #Allow from 123.45.67.8

    ================
    И разослали инструкции с просьбой указать свои ip.

  6. yukra :

    Блин, тэги попортились. Ссылка на нашу инструкцию _://help.logol.ru/topics/htaccess-deny/

  7. FLy :

    а вот здесь
    [wp-ddos]
    enabled = 80

    опечатка? true наверное имелось ввиду

  8. Уху, есть такое. Поправил.

    Спасибо.

  9. Походу fail2ban забанил гуглоробота)
    Стали приходить письма о недоступности сайта.

  10. Влад :

    Ну либо гуглоробот ломился туда, куда не надо, либо regexp неправильно написали (или формат лога от дефолтного сменили)

  11. Kiborg85 :

    Добрый день.
    А подскажите как выловить такое регулярное выражение «HTTP/1.1″ 401″
    пробовал так:
    ^ — * HTTP/1.1″ 401
    ^ — * HTTP/1.0» 401
    но не срабатывает
    а в примерах нахожу ещё точки, ^ этот знак…. и не знаю как оно реагирует на кавычки

  12. failregex = .*HTTP/1.1\» 401\»

    как-то так пробуйте.

    ^ = начало строки.
    . = 1 любой символ

  13. Kiborg85 :

    Спасибо.
    Уже сам научился :)
    ^ — .* HTTP/1.[1|0]» 401.*$
    Уже и первые результаты есть. Работает.
    Хорошая статься по этому поводу https://toster.ru/q/212086

  14. Да не за что )

  15. Роман :

    а как настроить такое?
    из лога access.log
    мойсат.su 61.91.251.235 «POST /login.php HTTP/1.1»
    такое выражение не срабатывает .*POST /login.php
    Пытаюсь при неправильном вводе логина и пароля после нескольких попыток банить ip

  16. fail2ban-regex access.log " .*POST /wp-login.php"
    что говорит?

  17. бле. регулярку из статьи возьмите, форматировать лень.

Написать комментарий