Fail2ban — это инструмент для защиты сервера от брутфорс-атак (подбора паролей) и других автоматизированных вредоносных действий.
Чаще всего утилита используется для защиты SSH от брутфорса паролей. А также для анализа логов и блокировки тех, кто подбирает пароли или просто выполняет слишком много запросов к какому-либо ресурсу. Утилита может защитить также почтовые ящики от перебора паролей.
Сегодня установим fail2ban в Ubuntu 22.04 и защитим SSH и Nginx.
Установка fail2ban в Ubuntu
Установим пакет:
sudo apt update && sudo apt install -y fail2banЕсли у вас Debian 12, то дополнительно дружим systemd и python, чтобы Fail2Ban мог читать journal systemd.
sudo apt install -y python3-systemdЗапускаем сервис и включаем автозагрузку:
sudo systemctl enable --now fail2banПроверяем статус:
sudo systemctl status fail2ban
Настройка fail2ban
Выполним первоначальную настройку fail2ban.
jail.conf — конфигурационный файл по умолчанию, который не нужно трогать. Как только пакет fail2ban обновится, этот файл перезапишется.
jail.local — создадим рядом этот файл и будем вносить настройки в нём.
Если настроек много, можно их разместить как drop-in файлы в директории jail.d.
sudo cd /etc/fail2ban
sudo touch jail.localРедактируем jail.local и вносим первоначальные настройки в блоке [DEFAULT]:
[DEFAULT]
# IP-адреса, которые НИКОГДА НЕ БАНИМ (добавьте свои IP)
ignoreip = 127.0.0.1/8 ::1 ВАШ_IP_1 ВАШ_IP_2
# Время блокировки (1 час = 3600 сек, 'm' - минуты, 'h' - часы)
bantime = 1h
# Время поиска (смотрим попытки за последние 10 минут)
findtime = 10m
# Количество ошибок для блокировки
maxretry = 5- ignoreip — вносим сюда список IP адресов-исключений, которые не должны баниться
- bantime — время блокировки (1 час = 3600 сек, 'm' - минуты, 'h' - часы)
- findtime — в каком диапазоне времени ищем
- maxretry — допустимое количество ошибок в выбранном диапазоне, с которого начинаем блокировать
В данном примере по умолчанию после пятой ошибки за последние 10 минут блокируем IP адрес нарушителя на 1 час. Свои IP адреся не блокируем никогда.
Защищаем SSH
Защитим SSH от перебора паролей:
[sshd]
enabled = true
mode = aggressive
port = ssh
logpath = /var/log/auth.log
maxretry = 3
bantime = 2h- enabled — включение/отключение защиты
- mode = aggressive — агрессивный режим, ловит больше ошибок SSH включая ошибки при аутентификации по ключу
- port — порт SSH (ssl — это 22 )
- logpath — путь до лога, для Ubuntu/Debian это /var/log/auth.log
- maxretry — блокируем после третьей попытки
- findtime — не указываем, используем значение из секции [DEFAULT]
- bantime — время блокировки
Вместо logpath можно указать на journal systemd:
- backend = systemd
Если вы сменили номер порта, то укажите его вместо ssl:
- port = 2222
Здесь при попытке аутентификации по SSH при третьем неверном пароле за последние 10 минут производится блокировка на 2 часа.
Перезапускаем fail2ban:
sudo systemctl restart fail2banПроверим что jail SSH активен:
sudo fail2ban-client status sshdStatus for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:Защищаем Nginx
Fail2Ban поставляется с несколькими предустановленными фильтрами для Nginx. Настроим:
- nginx-botsearch — для сканеров
- nginx-http-auth — для brute-force на HTTP Basic Auth
- nginx-limit-req — для настройки request Limit
Настройка nginx-botsearch:
[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 30- enabled — включение/отключение защиты
- port = http,https — это 80 и 443
- logpath — путь до лога access Nginx
- maxretry — блокируем после третьей попытки
- findtime — не указываем, используем значение из секции [DEFAULT]
- bantime — время блокировки
Настройка nginx-http-auth:
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 30- enabled — включение/отключение защиты
- port = http,https — это 80 и 443
- logpath — путь до лога error Nginx
- maxretry — блокируем после третьей попытки
- findtime — не указываем, используем значение из секции [DEFAULT]
- bantime — время блокировки
Следующее правило поможет в какой-то степени защититься от DDoS атак. Настройка nginx-limit-req:
[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 30- enabled — включение/отключение защиты
- port = http,https — это 80 и 443
- logpath — путь до лога error Nginx
- maxretry — блокируем после третьей попытки
- findtime — не указываем, используем значение из секции [DEFAULT]
- bantime — время блокировки
Но это ещё не всё, нужно настроить сами лимиты. Редактируем /etc/nginx/nginx.conf. В секцию http добавляем:
http {
***
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
***Создаётся зона mylimit с интенсивностью 10 запросов в секунду. Проверяется 10 последних минут.
Настраиваем лимит для виртуального домена в разделе server → location или просто в server:
server {
***
limit_req zone=mylimit burst=20 nodelay;
limit_req_status 429;
***Вместе с ранее созданной зоной настройка задаёт лимит 10 запросов в секунду при всплеске 20 запросов. При превышении лимита клиенту дополнительно возвращается ошибка 429.
Перезапускаем fail2ban и nginx:
sudo systemctl restart fail2ban
sudo systemctl restart nginxПроверим что jail nginx-botsearch активен:
sudo fail2ban-client status nginx-botsearchStatus for the jail: nginx-botsearch
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/nginx/access.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:Проверим что jail nginx-http-auth активен:
sudo fail2ban-client status nginx-http-authStatus for the jail: nginx-http-auth
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/nginx/error.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:Проверим что jail nginx-limit-req активен:
sudo fail2ban-client status nginx-limit-reqStatus for the jail: nginx-limit-req
|- Filter
| |- Currently failed: 13
| |- Total failed: 628
| `- File list: /var/log/nginx/error.log
`- Actions
|- Currently banned: 1
|- Total banned: 43
`- Banned IP list: 5.187.88.20Даже первые кандидаты забанились, пока я писал статью.
