Установка и настройка Fail2ban

Для любого серверного сервиса - будь то веб-сайт или почта - необходима базовая защита от частых повторяющихся запросов, совершаемых с целью несанкционированного доступа. Злоумышленники, как правило, используют базы данных скомпрометированных учетных записей, содержащие логины и пароли. На их основе они осуществляют автоматизированный перебор, пытаясь получить доступ к различным сервисам. В логах это выглядит как множественные неуспешные попытки аутентификации, поступающие с одного или нескольких IP-адресов. Это подводит к очевидному решению: если с какого-то IP-адреса поступает слишком много неуспешных запросов аутентификации, его следует временно заблокировать. Для реализации такого механизма применяется Fail2ban. Данный инструмент анализирует логи по заранее определенным фильтрам и блокирует IP-адреса злоумышленников на определенный срок. В комплекте уже есть набор фильтров для наиболее распространенных сервисов, однако при необходимости можно создать собственные правила - например, для самописного приложения.

Установка

Чтобы установить fail2ban на debian/ubuntu нужно вызвать:

sudo apt install fail2ban

CentOS:

sudo yum install fail2ban

Arch Linux:

sudo pacman -S fail2ban

Запуск

После настройки необходимо убедиться, что служба Fail2ban запущена и настроена на автоматический запуск при старте системы. Для этого выполните команды:

sudo systemctl start fail2ban
sudo systemctl enable fail2ban

Первая команда запускает службу немедленно, вторая - добавляет ее в автозагрузку, чтобы Fail2ban автоматически запускался при каждом перезапуске сервера. Проверка статуса:

sudo systemctl status fail2ban

Настройка

Почта

Рассмотрим пример настройки Fail2ban для защиты почтового сервера со стандартной аутентификацией через Dovecot.
Сначала необходимо создать jail, в котором задается, что блокировать и как. Например, файл /etc/fail2ban/jail.d/dovecot.local может выглядеть так:

[dovecot]
enabled = true
port    = pop3,pop3s,imap,imaps
filter  = dovecot
logpath = /var/log/auth.log
maxretry = 1
bantime  = 360000
findtime = 600
action   = nftables[name=dovecot, port="pop3,pop3s,imap,imaps,smtp,smtps", protocol=tcp]

Исходя из этой конфигурации, Fail2ban будет искать в логе /var/log/auth.log неуспешные попытки аутентификации и блокировать соответствующие IP-адреса на 360 000 секунд. Фильтр dovecot описан в файле /etc/fail2ban/filter.d/dovecot.conf. Там можно изучить регулярные выражения и, при необходимости, создать собственный фильтр для специфических случаев.

SSH

Для SSH, вместе со сменой стандартного порта и настройкой аутентификации по PublicKey, можно аналогичным образом включить блокировку злоумышленников через fail2ban:

[sshd]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 1
bantime  = 360000
findtime = 600
action   = nftables[name=sshd, port=ssh, protocol=tcp]

Asterisk

Для Asterisk можно заблокировать неудачные попытки аутентификации SIP:

[asterisk]
enabled  = true
port     = sip,5060,5061
filter   = asterisk
logpath  = /var/log/asterisk/messages
maxretry = 1
bantime  = 360000
findtime = 600
action   = nftables[name=asterisk, port="sip,5060,5061", protocol=udp]

NGINX

Для неудачных попыток аутентификации через HTTP Basic Auth можно использовать такую настройку:

[nginx-http-auth]
enabled  = true
port     = http,https
filter   = nginx-http-auth
logpath  = /var/log/nginx/error.log
maxretry = 3
bantime  = 360000
findtime = 600
action   = nftables[name=nginx-http-auth, port="http,https", protocol=tcp]

Для защиты от ботов, сканирующих несуществующие страницы, можно использовать такую настройку:

[nginx-botsearch]
enabled  = true
port     = http,https
filter   = nginx-botsearch
logpath  = /var/log/nginx/access.log
maxretry = 1
bantime  = 360000
findtime = 600
action   = nftables[name=nginx-botsearch, port="http,https", protocol=tcp]

Если нужно заблокировать IP-адреса, превышающие лимиты запросов, заданные через limit_req в Nginx:

[nginx-limit-req]
enabled  = true
port     = http,https
filter   = nginx-limit-req
logpath  = /var/log/nginx/error.log
maxretry = 1
bantime  = 360000
findtime = 600
action   = nftables[name=nginx-limit-req, port="http,https", protocol=tcp]

Проверка работы

Проверить статистику конкретного jail можно командой:

fail2ban-client status dovecot

Пример вывода:

Status for the jail: dovecot
|- Filter
|  |- Currently failed: 0
|  |- Total failed: 30
|  `- Journal matches:  _SYSTEMD_UNIT=dovecot.service
`- Actions
   |- Currently banned: 30
   |- Total banned: 60
   `- Banned IP list:   81.30.107.168 81.30.107.33 81.30.107.159 81.30.107.194 81.30.107.189 81.30.107.40 81.30.107.145 81.30.107.119 81.30.107.195 81.30.107.185 81.30.107.149 81.30.107.43 81.30.107.174 81.30.107.38 81.30.107.21 81.30.107.109 81.30.107.49 81.30.107.24 81.30.107.67 81.30.107.29 81.30.107.177 81.30.107.104 81.30.107.94 81.30.107.205 81.30.107.201 81.30.107.160 81.30.107.115 81.30.107.89 81.30.107.146 81.30.107.64

По приведенной выше настройке jail блокировка осуществляется через firewall nftables. Однако это не единственный вариант: Fail2ban поддерживает различные методы блокировки и даже позволяет использовать собственные shell-скрипты.

Проверить список заблокированных IP-адресов в nftables можно командой:

nft list ruleset

Пример вывода:

table inet f2b-table {
    set addr-set-dovecot {
        type ipv4_addr
        elements = { 81.30.107.21, 81.30.107.24,
                 81.30.107.29, 81.30.107.33,
                 81.30.107.38, 81.30.107.40,
                 81.30.107.43, 81.30.107.49,
                 81.30.107.64, 81.30.107.67,
                 81.30.107.89, 81.30.107.94,
                 81.30.107.104, 81.30.107.109,
                 81.30.107.115, 81.30.107.119,
                 81.30.107.145, 81.30.107.146,
                 81.30.107.149, 81.30.107.159,
                 81.30.107.160, 81.30.107.168,
                 81.30.107.174, 81.30.107.177,
                 81.30.107.185, 81.30.107.189,
                 81.30.107.194, 81.30.107.195,
                 81.30.107.201, 81.30.107.205 }
    }

    chain f2b-chain {
        type filter hook input priority filter - 1; policy accept;
        tcp dport { 25, 110, 143, 465, 993, 995 } ip saddr @addr-set-dovecot reject
    }
}

Fail2ban создает отдельную цепочку (chain), которая подключается к общей схеме фильтрации на раннем этапе обработки пакетов. Эта цепочка проверяет входящие соединения: если IP-адрес клиента содержится в списке addr-set-dovecot, запросы на указанные в jail порты блокируются.

Разблокировка

Для ручной разблокировки IP-адреса с помощью Fail2ban нужно ввести следующую команду:

sudo fail2ban-client set sshd unbanip 81.30.107.205

Если нужно разблокировать всех:

sudo fail2ban-client set sshd unban --all

Для разблокировки через nftables:

sudo nft delete element inet f2b-table addr-set-dovecot { 81.30.107.205 }

Проверка после разблокировки:

sudo fail2ban-client status sshd

IP-адрес, который был забанен, больше не будет в списке Banned IP list.

Вывод

Даже с простой конфигурацией Fail2ban позволяет эффективно защититься от примитивных атак: брутфорс-атак, массовых попыток аутентификации, спама и от сканирования файлов веб-приложений. Это особенно полезно для небольших серверов, где администрирование ведется вручную, и нет возможности внедрять сложные системы защиты. Для энтузиастов и владельцев собственных сайтов или почтовых серверов Fail2ban это удобный, простой и надежный инструмент. Он прост в установке и настройке, поддерживает универсальную систему фильтров, а при необходимости легко расширяется - можно добавлять свои правила, использовать разные методы блокировки или интегрировать его с другими средствами защиты. Однако Fail2ban не стоит рассматривать как универсальное решение для всех задач. В больших и нагруженных системах он может оказаться недостаточно гибким или эффективным. Кроме того, при слишком строгих настройках существует риск ложных срабатываний, когда блокируются обычные пользователи. Тем не менее, Fail2ban можно рассматривать как первый шаг в системе безопасности: доступное средство, которое способно заметно снизить количество попыток взлома и избавить администратора от ручного мониторинга логов.