# Создание фильтра для Fail2ban
Fail2ban — приложение, позволяющее контролировать подключения к вашему серверу, отслеживать повторяющиеся попытки входа и блокировать определённые IP-адреса на основе заданных правил.
По умолчанию в Fail2ban встроено несколько фильтров, позволяющих обеспечить базовую защиту большинству веб-интерфейсов вашего сервера: ssh, веб-серверы и т.д.
Но иногда возникают ситуации, когда атака на сервер ведётся более изобретательно, и стандартные шаблоны Fail2ban с ней не справляются. В этом случае можно самостоятельно написать фильтр, который будет отслеживать конкретные паттерны в поведении ботов и блокировать их.
В этой инструкции мы создадим новый фильтр для защиты SSH-подключения.
Для начала работы нам понадобится подготовленный к работе сервер с установленным приложением Fail2ban.
# Признаки атаки
Основной признак попыток взлома вашего сервера — «подозрительная активность» в логах SSH-подключения. Это могут быть регулярные попытки подключения с разных IP-адресов, запросы к различным портам сервера, запросы на получение ключей и т.д.
Прочитать логи ssh-подключения можно с помощью команды:
journalctl -u ssh | tail -20
Она выведет на экран 20 последних записей из лога SSH-подключения. Как правило, этого количества данных бывает достаточно, чтобы визуально определить попытку взлома сервера.
Мы разберём создание фильтра на примере одной из строк из лога ssh-подключения:
Mar 30 14:41:25 host_name sshd[2909]: Disconnected from invalid user ramon 178.128.19.209 port 54288 [preauth]
Нам нужно создать правило, которое будет находить все подобные строки в логах и блокировать указанный здесь IP.
# Создание правила
Начнём с определения правила, по которому будут блокироваться IP. Для этого нам нужно описать строку, в которой фигурирует интересующий нас IP.
Строка, которую мы взяли за основу:
Mar 30 14:41:25 host_name sshd[2909]: Disconnected from invalid user ramon 178.128.19.209 port 54288 [preauth]
Она состоит из временной метки Mar 30 14:41:25
, указания имени хоста, обозначения процесса (в данном случае sshd
) и собственно описания события Disconnected from invalid user ramon 178.128.19.209 port 54288 [preauth]
.
Из итоговой строки можно убрать временную метку и обозначение процесса — Fail2ban по умолчанию воспринимает большинство временных меток и игнорирует их при обработке правил. Это упрощает нам задачу.
Остаётся такой вариант строки: Disconnected from invalid user ramon 178.128.19.209 port 54288 [preauth]
.
Теперь необходимо оставить основной текст, который не будет меняться от одного сообщения к другому, и заменить только переменные, в нашем случае это IP, имя пользователя и порт, по которому происходит подключение. Заменим порт и имя пользователя на выражения, означающие «Любое значение», поскольку они нам не важны. Значение IP-адреса заменим на указание того, что это и есть хост, который нужно заблокировать. В итоге получится следующая строка:
Disconnected from invalid user [A-Z]+ <HOST> port [0-9]+ \[preauth\]
Это и есть готовое выражение, на основании которого мы будем производить фильтрацию логов.
# Создание фильтра
Теперь нужно создать фильтр — текстовый файл, в котором будут указаны правила фильтрации. В нашем случае это будет одна строка.
Создаём файл в директории, где размещаются все фильтры Fail2ban:
sudo vim /etc/fail2ban/filter.d/new_filter.conf
Содержимое файла будет следующим:
[Definition]
failregex = Received disconnect from <HOST> port [0-9]+:11: (Bye Bye)? \[preauth\]
Блок [Definition]
здесь определяет исполняемую часть файла. Вариант написания этого блока (с заглавной буквы) также очень важен для синтаксиса программы.
В строке failregex =
указываем наше правило, созданное на предыдущем шаге. Здесь можно указывать несколько правил, по которым будет производиться отбор. Разделять правила в таком случае нужно пустой строкой.
Если мы хотим добавить какой-то IP-адрес в список игнорируемых, то можно указать его ниже, добавив параметр ignoregex =
.
Основное правило создано, теперь проверим, как оно работает.
# Проверка правила
Для проверки работы созданных правил в Fail2ban существует встроенный инструмент regex
. Общий вид команды выглядит следующим образом:
sudo fail2ban-regex <log_file> <filter_file> <ignore_file>
Здесь последовательно указаны пути к файлам лога, который будем анализировать, путь к файлу, где содержится фильтр и путь к файлу, в котором указаны исключения из правила. Если исключения и правила мы указываем в одном и том же файле, то дважды прописываем путь к нему.
Также в этой строке можно указывать не только путь к файлу с правилом, но и непосредственно само правило, заключённое в одинарные кавычки.
Далее введите команду:
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/new_filter.conf
Если мы всё сделали правильно, на выходе будет примерно следующая информация:
# Output
Lines: 16622 lines, 0 ignored, 2738 matched, 13884 missed
[processed in 1.27 sec]
Здесь мы видим количество проанализированных строк, проигнорированных, совпавших и пропущенных, а также время, которое программа потратила.
Эта запись означает, что наш фильтр настроен правильно, можно переходить к созданию jail’а на основе фильтра.
# Создание jail
Мы не будем добавлять новый фильтр в наш основной jail, а создадим новый в общей папке:
sudo vim /etc/fail2ban/jail.d/new_jail.conf
Содержимое jail’а будет следующим:
[myservice]
enabled = true
port = all
filter = myservice
logpath = /var/log/auth.log
maxretry = 5
findtime = 60
bantime = 600
Основные параметры, указанные здесь, совпадают со стандартными параметрами jail’ов, которые мы описывали в инструкции по настройке Fail2ban:
- [myservice] — название нашего jail’а;
- enabled — указание на активность jail’а (включён/выключен);
- port — здесь указываются порты, для которых будет работать наш фильтр. Можно указать словами или прописать конкретные значения (http, https, all, 22…);
- filter — здесь указываем название нашего фильтра (имя файла до .conf), в нашем случае это
new_filter
; - logpath — это путь к файлу с логами, которые будет анализировать фильтр, указываем путь к логам /var/log/auth.log;
- maxretry, findtime, bantime — параметры для поиска и бана — количество попыток, вызывающее срабатывание, время, за которое производится поиск и время бана. Здесь они указаны в секундах, но можно указывать часы, дни и недели, добавляя после значения h, d и w соответственно.
После указания всех нужных параметров и сохранения текстового файла работу можно считать законченной — фильтр создан и готов к началу применения. Осталось только перезагрузить Fail2ban и проверить, что jail определился:
sudo systemctl restart fail2ban
fail2ban-client status
Вторая команда должна вывести в консоль список всех активных jail’ов.
Если вы хотите посмотреть на статус работы конкретного jail’а, можно добавить его имя в строку запроса статуса:
sudo fail2ban-client status new_filter
#Output
Status for the jail: new_filter
|- Filter
| |- Currently failed: 0
| |- Total failed: 1707
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 409
|- Total banned: 410
`- Banned IP list:
Готово! Фильтр настроен и работает. С момента запуска он заблокировал более 400 IP-адресов, удовлетворяющих нашему правилу. Это значит, что на сервер велась атака, и она успешно отражена.