Настраиваем fail2ban под свои задачи

Крайне полезное серверное приложение Linux – настраиваем под себя

Настраиваем fail2ban под свои задачи

Про установку и запуск читаем здесь

Установка fail2ban на Linux

Для самостоятельной настройки нужно:

  • лог с данными
  • настроить фильтр (получение IP из лога)
  • действия (что делать с этими IP)
  • и джайл – связать фильтр и действие :)

Например, как это сделать для блокировки ботов-подборщиков логина и пароля в WordPress – читаем статью

Блокируем ботов-подборщиков через fail2ban

Или создаем свой вариант.

Делаем свой лог

Например в корневой папке web-server (в папках выше политика безопасности сервера не даст доступа нашему php-скрипту)

<?php
$root_webserver = '/var/www/user/data/www/';
// это корневая папка web server, а не DOCUMENT_ROOT сайта
$my_dir = $root_webserver.'_mylog';
if (! file_exists ($my_dir)){
   mkdir ($my_dir, 0777);
}
$file_var = $my_dir.'/test.log';
$size_log = filesize ($file_var); //при отсутствии файла будет false
$bot_info = date("Y-m-d H:i:s").' '.'192.168.1.1 и другая информация'.PHP_EOL; // перевод строки
if ( $size_log === FALSE || $size_log > 300000 ) { 
   // файла нет или он больше 300 000 байт - делаем новый
   file_put_contents($file_var, $bot_info, LOCK_EX);
}else{ // в остальных случаях дописываем в старый
   file_put_contents($file_var, $bot_info, FILE_APPEND | LOCK_EX);
}
?>

Дата и время должны записываться в лог в определенном формате, что бы фильтр fail2ban можно было настроить корректно (там потом будет анализ периода заходов бота). Основной стандартный формат ниже (но fail2ban понимает и другие варианты)

год-месяц-день часы:минуты:секунды

поэтому используем php –  date(“Y-m-d H:i:s”)

В результате этого колдунства у нас получилось:

  • в папке /var/www/user/data/www/  (на Вашем сервере может быть другой путь) появилась новая папка “_mylog
  • в этой папке файл “test.log” (общий лог для всех Ваших сайтов на VPS)
  • при превышении размера ~300kb – файл создается заново (или можно сделать ротацию логов)
  • переменную $bot_info можно собрать как удобнее – главное дата/время и IP

Итого мы имеет лог-файл с адресом вида (в который пишутся строки с IP-адресами ботов)

/var/www/user/data/www/_mylog/test.log

который мы и будет “скармливать” fail2ban

Делаем свой фильтр (что бы вытащить IP из лога)

  • Вопрос – может ли fail2ban работать без файла фильтра? 
  • Нет, не может. Приложению fail2ban необходимо получить IP-адрес из лога – а это как раз делает фильтр с помощью regex

Пишем свой фильтр. Свой фильтр можно создавать с названием myfilter.conf в папке filter.d/

Общая структура фильтра. В файле фильтра может быть два раздела:

  • [INCLUDES} – необязательно
    • before = common.conf
    • after = filtername.local
  • [Definition]
    • failregex = ….
    • ignoreregex = ….

Раздел [INCLUDES] указывает на файлы фильтров, которые читаются до или после этого файла. Файл common.conf считывается и помещается перед другими строками в этом файле, а файл filtername.local – после . Эти файлы устанавливают некоторые параметры, которые будут использоваться далее в конфигурации.

Раздел [Definition] указывает на выражения regex, которые нужно применить к файлу лога или исключить из обработки.

Формат выражения failregex:

  • должно начинаться с символа ^ – это означает для fail2ban, что будет анализироваться текст после формата даты Y-m-d H:i:s. Есть недокументированная возможность вместо символа ^ использовать свое выражения для формата даты (если в Вашем логе дата формируется по другому), cм. ошибку Debian # 491253
  • директива <HOST> – для определения IP-адреса в строке лога (для версии ниже 0.10 работает только для IP v4). Этот тэг <HOST> – внутренняя замена fail2ban регулярного выражения (?:::f{4,6}:)?(?P<host>\S+)

Итого вида failregex = ^ регулярное выражение <HOST> регулярное выражение

Правила, используемые вашей версией fail2ban, зависят от версии питона, используемого в системе.

# python -V
Python 2.7.13

У нас фильтр будет относительно простой, т.к. в логе уже собраны адреса IP только “вредителей”, не нужно дополнительно искать по условию regex текстовую строку с описанием ошибки. Нам нужно простое регулярное выражение, которое будет “видеть” IP в строках лога.

failregex = ^ <HOST>

Проверим, как работает фильтр (команда + лог + фильтр). Для проверки может быть в качестве фильтра использован или файл с фильтром или сам фильтр (в  кавычках)

fail2ban-regex /var/www/user/data/www/_mylog/test.log  '^ <HOST>'

удобно тестировать по одной строке.

Результат

Настраиваем fail2ban под свои задачи

  • 311 совпадений найдено
  • формат даты распознан

Итого наш вариант файла testfilter.conf для папки filter.d

[Definition]
failregex = ^ <HOST>
ignoreregex =

Проверяем полностью

fail2ban-regex /var/www/user/data/www/_mylog/test.log /etc/fail2ban/filter.d/testfilter.conf

Вот кстати, полный отчет fail2ban по обнаружению формата даты в логе

Date template hits:
|- [# of hits] date format
| [311] Day(?P<_sep>[-/])MON(?P=_sep)Year[ :]?24hour:Minute:Second(?:.Microseconds)?(?: Zone offset)?
| [0] (?:DAY )?MON Day 24hour:Minute:Second(?:.Microseconds)?(?: Year)?
| [0] Year(?P<_sep>[-/.])Month(?P=_sep)Day 24hour:Minute:Second(?:,Microseconds)?
| [0] Day(?P<_sep>[-/])Month(?P=_sep)(?:Year|Year2) 24hour:Minute:Second
| [0] Month/Day/Year:24hour:Minute:Second
| [0] Month-Day-Year 24hour:Minute:Second.Microseconds
| [0] TAI64N
| [0] Epoch
| [0] Year-Month-Day[T ]24hour:Minute:Second(?:.Microseconds)?(?:Zone offset)?
| [0] ^24hour:Minute:Second
| [0] ^<Month/Day/Year2@24hour:Minute:Second>
| [0] ^Year2MonthDay ?24hour:Minute:Second
| [0] MON Day, Year 12hour:Minute:Second AMPM
| [0] ^MON-Day-Year2 24hour:Minute:Second

Делаем JAIL (файл, в котором укажем лог и необходимые действия)

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

Тюрьму (“JAIL”) будем делать нестандартную. Обычно используется вариант вида “пять одинаковых адресов IP за период” – и в бан на 15 мин.

Можно сделать расширенный вариант – если в логе есть три раза один и тот же IP – то это точно “вредитель”.

Баним его сразу на 30 дней (и время обнаружения тоже 30 дней). Не забываем установить время хранения IP в базе хотя бы 31 день. Период хранения IP  адреса в базе находится в файле fail2ban.conf. Необходимо создать и использовать файл fail2ban.local, в котором мы изменим время хранения.

# 31 days
dbpurgeage = 2678400

Настраиваем fail2ban под свои задачи

Т.к. файл логов периодически начинает вестись с нуля – какие-то IP будут из бана возвращаться через месяц. При наборе очередных 3 попыток – опять бан. Это будет работать и для любителей делать 10 запросов в секунду. Тоже будут заблокированы на 30 дней.

[test]
enabled  = true 
filter   = testfilter
logpath  = /var/www/user/data/www/_mylog/test.log
# 30 days
bantime = 2592000
findtime = 2592000
maxretry = 3

Перезапускаем fail2ban

смотрим в логах /var/log/fail2ban.log

Настраиваем fail2ban под свои задачи

вот всё и заработало:

  • Jail ‘test’ создан
  • лог-файл добавлен
  • наши параметры добавлены
  • jail ‘test’ запущен
  • три обнаружения и бан

Посмотрим, что у нас там в “клетке” набралось

sudo iptables -L -n

да, через серверную утилиту iptables

Настраиваем fail2ban под свои задачи

Да, всё хорошо – вот они “вредители” с блоком на 30 дней.

А потом начинается “дискотека” в логе fail2ban – забаненные пытаются еще раз что-то сделать нехорошее.

Настраиваем fail2ban под свои задачи

За 20 секунд – 19 попыток… В среднем 1 раз в секунду.

И все они закончились на входе на сервер (на уровне netfilter), ни до Apache, ни до WordPress запросы уже не дошли.

Долговременный бан для тупых ботов

Например, по умолчанию боты, которые пытаются сломать SSH – блокируются на 10 мин (со временем обнаружения 10 мин и 5 попытками).

Потом netfilter выводит их из бана. Результат ниже.

Настраиваем fail2ban под свои задачи

Через 1 минуту после снятия блокировки бот занялся подбором…

Нехорошо. Как с этим бороться?

Можно увеличить сразу время бана для таких ботов. А можно пойти другим путем.

У fail2ban есть же свой лог :)

tail -f /var/log/fail2ban.log

/var/log/fail2ban.log – вот этот его собственный лог мы еще раз отдадим на анализ в fail2ban:

  • три попадания IP в бан
  • период – сутки
  • бан для такого IP – на месяц

в результате совсем “тупые” боты будут блокированы на 30 дней.

пишем фильтр fail2ban_f.conf:

  • первое выражение regex ищет IP-адреса, которые получили Ban
  • второе выражение regex исключает из списка баны, полученные уже правилом {fail2ban}
[Definition] 
failregex = ^.*?fail2ban\.actions.*?Ban\s+<HOST>$
ignoreregex = ^.*?fail2ban\.actions.*?\[fail2ban\]\sBan

и джайл fail2ban_d.conf

[fail2ban] 
enabled = true 
filter = fail2ban_f 
# block all ports
action = iptables-allports[name=FAIL2BAN] 
logpath = /var/log/fail2ban.log
maxretry = 3
# 1 day 
findtime = 86400 
# 30 days
bantime = 2592000

Проверяем и запускаем.

ВАЖНО

При ограниченных ресурсах VPS возможно получение ошибок вида “iptables: Memory allocation problem”.

Это желающих сломать (например SSH) больше, чем место под правила блокировок в iptables. Т.е. работает такой себе хороший ботнет с большим количеством IP.

Смотрим:

cat /proc/user_beancounters

Параметр numiptent определяет количество правил iptables, которые мы можем создать.
Колонка held показывает текущее значение.
Колонка maxheld показывает максимальное пиковое значение.
Колонки barrier и limit должны совпадать и определяют максимально доступное для нас значение.
Колонка failcnt содержит число ошибочных обращений. Если оно содержит не 0, возможно, выделенных нам ресурсов уже не хватает. Когда held=limit и возникает упомянутое выше сообщение. В этом случае можно написать хостеру тикет с просьбой увеличить значение numiptent.

Но результат работы jail [fail2ban] того стоит, 30 дней побудут в бане

Настраиваем fail2ban под свои задачи

 

 


Вы можете сохранить ссылку на эту страницу себе на компьютер в виде htm файла