Для любого серверного сервиса - будь то веб-сайт или почта - необходима базовая защита от частых повторяющихся запросов, совершаемых с целью несанкционированного доступа. Злоумышленники, как правило, используют базы данных скомпрометированных учетных записей, содержащие логины и пароли. На их основе они осуществляют автоматизированный перебор, пытаясь получить доступ к различным сервисам. В логах это выглядит как множественные неуспешные попытки аутентификации, поступающие с одного или нескольких 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]
[dovecot]
- названиеjail
, может быть любым.enable
- включен или выключен.port
- порты, за которыми будет следить Fail2ban.filter
- имя фильтра, с помощью которого Fail2ban ищет ошибки в логах, например ошибки аутентификации. В стандартной поставке у Fail2ban уже есть набор стандартных фильтров, в том числе фильтр для Dovecot. Фильтр основан на регулярных выражениях, которые анализируют содержимое логов.logpath
- файл, где хранятся логи приложения.maxretry
- количество неудачных попыток аутентификации, после которых IP-адрес блокируется. В данном примере установлено значение 1, так как почта используется только автором, а пароли хранятся вpass
. Если сервис используют несколько пользователей, рекомендуется увеличить это значение, чтобы избежать блокировок при случайных ошибках.bantime
- время, на которое IP-адрес добавляется в бан-лист (в секундах).findtime
- временной интервал, за который учитываются неудачные попытки. Параметрыmaxretry
иfindtime
работают вместе: IP-адрес блокируется, если за периодfindtime
было сделаноmaxretry
неудачных попыток.action
- способ блокировки; в данном случае используется firewallnftables
.
Исходя из этой конфигурации, 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
Currently failed
- количество неуспешных попыток аутентификаций за времяfindtime
.Total failed
- общее количество неуспешных попыток аутентификаций за все время работы Fail2ban.Journal matches
- источник логов, используемых для анализа. В данном примере Fail2ban получает данные не из/var/log/auth.log
, а напрямую изsystemd-journald
. Это связано с тем, что у некоторых стандартных фильтров выше приоритет, чем у пользовательских настроек. Чтобы изменить такое поведение, необходимо внести правки в сам фильтр.Currently banned
- количество IP-адресов, которые в данный момент находятся в блокировке (bantime
еще не истек).Total banned
- общее количество IP-адресов, которые когда-либо попадали в бан за время работы Fail2ban.Banned IP list
- список IP-адресов, находящихся в блокировке в текущий момент.
По приведенной выше настройке 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 можно рассматривать как первый шаг в системе безопасности: доступное средство, которое способно заметно снизить количество попыток взлома и избавить администратора от ручного мониторинга логов.