Каждый системный администратор и разработчик знает это неприятное чувство: вы только что арендовали свежий VDS, подключились по SSH, развернули рабочее окружение, а уже через 15 минут системный журнал заполняется тысячами записей от ботнетов. Автоматизированные сканеры круглосуточно бороздят диапазоны IP-адресов облачных провайдеров, методично перебирая пароли к SSH-порту и засыпая веб-сервер запросами в поисках забытых конфигурационных файлов .env, открытых админок phpMyAdmin и уязвимых скриптов CMS.
Обычный статический фаервол (UFW или iptables) бессилен против атак на открытые публичные порты 22, 80 и 443 — ведь они обязаны быть доступны из внешнего мира. Именно здесь на сцену выходит Fail2ban — проверенный временем сервис активной защиты, который анализирует системные логи в реальном времени и динамически банит IP-адреса нарушителей на уровне сетевого экрана.
Однако в современных дистрибутивах Linux (включая Ubuntu 24.04 LTS) настройки по умолчанию претерпели радикальные изменения. Если бездумно скопировать устаревшие инструкции из интернета пятилетней давности, служба Fail2ban либо откажется запускаться из-за отсутствия классического файла логов, либо заблокирует самого администратора при первой случайной ошибке ввода пароля. В этом практическом руководстве мы разберём правильную архитектуру Fail2ban, настроим фильтры для SSH и Nginx, включим пожизненную блокировку рецидивистов и реализуем мгновенные информативные уведомления в Telegram.
1. Анатомия атак: что происходит на VDS в первые 10 минут после выдачи IP
Существует опасное заблуждение: «Мой сервер никому не известен, у него нет домена, поэтому атаковать его пока некому». В реальности злоумышленникам не нужны доменные имена. Специализированные кластеры сканеров (Shodan, Censys, а также приватные ботнеты) непрерывно сканируют всё пространство адресов IPv4.
Как только виртуальный сервер получает публичный IP-адрес, он попадает под прицел автоматизированных скриптов:
- Брутфорс SSH (порт 22): Боты используют словари из сотен тысяч распространённых логинов (
root,admin,test,user,ubuntu,oracle) и типовых паролей. Частота подбора может достигать 20–100 попыток в секунду с сотен распределённых IP-адресов. Это не только создаёт угрозу взлома при слабом пароле, но и паразитно нагружает процессор шифрованием SSH-хэндшейков. - Веб-разведка и фаззинг (порты 80/443): Сканеры шлют тысячи запросов к несуществующим путям:
/.env,/wp-config.php.bak,/phpmyadmin/,/.git/config,/actuator/env. Цель — обнаружить забытые резервные копии, токены API к базам данных и ключи доступа к облачным хранилищам. - Атаки на исчерпание пула воркеров (L7 DoS): Мусорный трафик забивает соединения веб-сервера Nginx и пул процессов PHP-FPM или Node.js, из-за чего реальные посетители сайта начинают получать ошибки
502 Bad Gatewayи504 Gateway Time-out.
💡 Как быстро оценить масштаб проблемы на вашем сервере
Перед началом настройки вы можете проверить доступность внешних портов с помощью нашего бесплатного инструмента Сканер открытых портов онлайн, а в консоли сервера выполнить команду аудита попыток авторизации:
# В дистрибутивах с rsyslog:
grep "Failed password" /var/log/auth.log | wc -l
# В Ubuntu 24.04 (через journalctl):
journalctl -u ssh -u sshd | grep "Failed password" | wc -l
Число в несколько тысяч за сутки — стандартная картина для любого сервера без активной фильтрации.
2. Установка Fail2ban на Ubuntu 24.04 и ловушка с systemd-journald
В Ubuntu 24.04 LTS разработчики Canonical отказались от предустановленного классического демона rsyslog. Файл /var/log/auth.log, на который десятилетиями опирались инструкции по Fail2ban, теперь попросту отсутствует по умолчанию. Все события безопасности регистрируются в бинарном хранилище systemd-journald.
Если установить Fail2ban стандартным способом и указать в конфигурации logpath = /var/log/auth.log, служба упадет с ошибкой Failed to initialize any backend for Jail 'sshd'.
Чтобы система работала быстро и надёжно, правильнее всего научить Fail2ban читать события напрямую из systemd через модуль Python. Выполним установку пакетов:
sudo apt update
sudo apt install -y fail2ban python3-systemd
Пакет python3-systemd предоставляет высокопроизводительные биндинги к системному журналу, позволяя Fail2ban анализировать события без промежуточных текстовых файлов и лишних операций ввода-вывода (I/O) на диске.
⚠️ Фундаментальное правило работы с конфигурацией Fail2ban
Никогда не редактируйте файл /etc/fail2ban/jail.conf напрямую! Этот файл поставляется разработчиками пакета и перезаписывается при каждом обновлении системы (apt upgrade), что приведёт к потере всех ваших правок. Все персональные настройки необходимо вносить строго в файл /etc/fail2ban/jail.local, который имеет наивысший приоритет и дополняет базовые директивы.
3. Базовая конфигурация jail.local: защита от самобана (ignoreip) и инкрементальный бан
Самый страшный кошмар системного администратора при настройке фаервола — случайно заблокировать собственный IP-адрес и потерять доступ к серверу. Поэтому настройка jail.local всегда начинается с определения белого списка доверенных сетей в директиве ignoreip.
Узнать свой текущий внешний IP-адрес можно с помощью утилиты Мой IP адрес и данные клиента, а если вы используете корпоративный VPN или статический пул адресов, рассчитать маску подсети поможет наш Калькулятор подсетей IPv4 CIDR.
Создадим чистый конфигурационный файл /etc/fail2ban/jail.local:
sudo nano /etc/fail2ban/jail.local
Вставим эталонную секцию [DEFAULT] с современным механизмом экспоненциального увеличения срока бана (bantime increment):
[DEFAULT]
# Белый список: локалхост, ваш статический IP и корпоративная подсеть VPN
ignoreip = 127.0.0.1/8 ::1 198.51.100.42 10.8.0.0/24
# Использование системного журнала systemd для Ubuntu 24.04
backend = systemd
# Базовое время блокировки: 1 час (3600 секунд)
bantime = 1h
# Окно наблюдения: если за 15 минут совершено maxretry нарушений -> бан
findtime = 15m
# Количество неудачных попыток до применения санкций
maxretry = 5
# Экспоненциальный рост времени бана для повторных нарушителей
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 5w
# Метод блокировки: использование ufw / nftables
banaction = ufw
banaction_allports = ufw
Рассмотрим ключевые параметры и их влияние на безопасность сервера:
| Директива | Значение | Инженерное назначение |
|---|---|---|
ignoreip |
IP/подсети |
Адреса, которые Fail2ban никогда не заблокирует ни при каких обстоятельствах. Защищает от потери доступа. |
backend |
systemd |
Прямое чтение журнала systemd в памяти без ожидания записи на диск и без зависимости от устаревшего rsyslog. |
bantime.increment |
true |
Активирует алгоритм «умного наказания»: первый бан длится 1 час, второй — 2 часа, третий — 4 часа, вплоть до 5 недель (bantime.maxtime). |
banaction |
ufw |
Интеграция с системным фаерволом Ubuntu. Правила вставляются нативно через правила UFW без засорения сырых цепочек iptables. |
4. Защита SSH и пожизненный бан ботнетов в джейле recidive
Теперь активируем джейл для службы SSH и подключим специальный джейл recidive, который отслеживает постоянных нарушителей, периодически возвращающихся к атакам после истечения стандартного срока блокировки.
Добавим в конец /etc/fail2ban/jail.local следующие секции:
# Защита службы SSH от брутфорса
[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 3
findtime = 10m
bantime = 24h
# Рецидивисты: повторный бан для тех, кого уже банили 3 раза за день
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = %(banaction_allports)s
bantime = 90d
findtime = 1d
maxretry = 3
Как работает связка [sshd] и [recidive]:
- Если бот совершает 3 неудачные попытки входа за 10 минут, джейл
[sshd]мгновенно блокирует доступ к порту 22 на 24 часа. - Если после разбана этот же IP-адрес снова попадает под санкции любого джейла (SSH или Nginx) 3 раза в течение суток, джейл
[recidive]отправляет нарушителя в глубокий бан на 90 дней сразу по всем сетевым портам (banaction_allports).
Это полностью отбивает интерес автоматизированных ботнетов к вашему серверу, освобождая сетевой стек и ресурсы процессора.
5. Защита веб-сервера Nginx: фильтры от 404-сканеров, утечек .env и атак на CMS
Веб-сервер Nginx ежедневно принимает сотни вредоносных запросов, генерирующих HTTP-коды 404 Not Found и 403 Forbidden. Стандартных фильтров Fail2ban часто недостаточно, чтобы отсечь специфические угрозы: сканирование скрытых файлов конфигурации и подбор паролей к панелям управления.
Создадим кастомный фильтр для перехвата сканеров уязвимостей. Создайте файл /etc/fail2ban/filter.d/nginx-malicious-probes.conf:
sudo nano /etc/fail2ban/filter.d/nginx-malicious-probes.conf
Добавим регулярные выражения для отслеживания типичных сигнатур атак в логах Nginx:
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD).*(/\.env|/\.git|/phpmyadmin|/pma|/setup\.php|/xmlrpc\.php|/wp-config|/actuator|/eval-stdin\.php).* HTTP/.*" (400|403|404)
^<HOST> -.*"(GET|POST).*(\.\./|/etc/passwd|/proc/self).* HTTP/.*" 403
ignoreregex =
Теперь подключим этот фильтр и защиту от HTTP 404 флуда в нашем /etc/fail2ban/jail.local:
# Защита Nginx от поиска скрытых файлов и админок
[nginx-malicious-probes]
enabled = true
port = http,https
filter = nginx-malicious-probes
logpath = /var/log/nginx/*access.log
maxretry = 2
findtime = 10m
bantime = 48h
# Защита от агрессивных 404-сканеров контента
[nginx-404-flood]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/*access.log
maxretry = 10
findtime = 1m
bantime = 24h
💡 Почему логфайлы Nginx указываются через маску
Конструкция logpath = /var/log/nginx/*access.log позволяет Fail2ban одновременно отслеживать как общий лог access.log, так и логи отдельных виртуальных хостов (например, example.com.access.log), автоматически подхватывая ротацию логов при срабатывании logrotate.
6. Интеграция с Telegram: bash-скрипт с отправкой карточки нарушителя
Знать, что сервер находится под защитой — хорошо. Но видеть в режиме реального времени, кто именно атаковал ваш VDS, из какой страны пришёл запрос и какой порт подвергся нападению — бесценно для оценки безопасности инфраструктуры.
Настроим отправку структурированных оповещений в Telegram через легковесный action-скрипт. Для этого потребуется Telegram-бот (создаётся через @BotFather) и ваш персональный chat_id (можно узнать через @userinfobot).
Создадим исполняемый скрипт оповещений /usr/local/bin/fail2ban-telegram.sh:
sudo nano /usr/local/bin/fail2ban-telegram.sh
Вставим следующий код скрипта:
#!/bin/bash
# Скрипт отправки уведомлений Fail2ban в Telegram
# Аргументы: $1 = JAIL, $2 = IP, $3 = FAILURES
TELEGRAM_BOT_TOKEN="123456789:ABCdefGHIjklMNOpqrSTUvwxYZ"
TELEGRAM_CHAT_ID="987654321"
JAIL_NAME="$1"
IP_ADDR="$2"
FAIL_COUNT="$3"
HOSTNAME=$(hostname)
# Получаем информацию о стране и ASN через быстрый JSON API (ip-api.com)
IP_INFO=$(curl -s --max-time 3 "http://ip-api.com/json/$IP_ADDR?fields=country,city,isp,as,status")
COUNTRY=$(echo "$IP_INFO" | grep -o '"country":"[^"]*' | cut -d'"' -f4)
CITY=$(echo "$IP_INFO" | grep -o '"city":"[^"]*' | cut -d'"' -f4)
ISP=$(echo "$IP_INFO" | grep -o '"isp":"[^"]*' | cut -d'"' -f4)
[ -z "$COUNTRY" ] && COUNTRY="Не определена"
[ -z "$CITY" ] && CITY="—"
[ -z "$ISP" ] && ISP="Неизвестный провайдер"
MESSAGE="🚨 <b>[Fail2ban] Блокировка IP-адреса</b>\n"
MESSAGE+="🖥 Сервер: <code>$HOSTNAME</code>\n"
MESSAGE+="🔒 Джейл: <code>$JAIL_NAME</code>\n"
MESSAGE+="🚫 Нарушитель: <code>$IP_ADDR</code>\n"
MESSAGE+="📊 Попыток: $FAIL_COUNT\n"
MESSAGE+="🌍 Локация: $COUNTRY, $CITY\n"
MESSAGE+="🏢 Провайдер (ISP): $ISP\n"
MESSAGE+="⏰ Время: $(date '+%Y-%m-%d %H:%M:%S MSK')"
curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
-d "chat_id=$TELEGRAM_CHAT_ID" \
-d "parse_mode=HTML" \
--data-urlencode "text=$MESSAGE" > /dev/null 2>&1
exit 0
Сделаем скрипт исполняемым:
sudo chmod +x /usr/local/bin/fail2ban-telegram.sh
Теперь создадим конфигурационный файл действия Fail2ban /etc/fail2ban/action.d/telegram-notify.conf:
sudo nano /etc/fail2ban/action.d/telegram-notify.conf
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = /usr/local/bin/fail2ban-telegram.sh <name> <ip> <failures>
actionunban =
Чтобы активировать отправку оповещений, подключите действие в секцию [DEFAULT] файла /etc/fail2ban/jail.local:
action = %(action_)s
telegram-notify
Перезапустим службу Fail2ban для применения всех созданных правил:
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
7. Шпаргалка команд fail2ban-client: мониторинг, аудит и ручной разбан
Для повседневного администрирования утилита fail2ban-client предоставляет полный набор инструментов проверки статуса, тестирования фильтров и управления списками блокировок.
| Задача | Команда CLI | Описание результата |
|---|---|---|
| Список активных джейлов | fail2ban-client status |
Показывает количество работающих джейлов (sshd, recidive, nginx-...) |
| Статистика конкретного джейла | fail2ban-client status sshd |
Выводит число перехваченных попыток и список заблокированных IP прямо сейчас. |
| Ручной разбан IP-адреса | fail2ban-client set sshd unbanip IP |
Мгновенно снимает блокировку с указанного адреса в джейле sshd. |
| Разбан во всех джейлах разом | fail2ban-client unban IP |
Удаляет IP из всех списков блокировок (полезно, если случайно забанили коллегу). |
| Тестирование регулярного выражения | fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-malicious-probes.conf |
Проверяет, сколько совпадений найдено в существующем логе без реальной блокировки. |
Также полезно проверять статус правил на уровне системного фаервола UFW:
sudo ufw status numbered
Вы увидите правила с префиксом [fail2ban-...], расположенные в самом верху таблицы маршрутизации, что гарантирует сброс вредоносных пакетов ещё до их попадания в сокеты веб-сервера.
🎯 Разверните защищённый VDS для высоконагруженных проектов
Чистый IPv4, аппаратная фильтрация сетевого мусора на уровне ядра дата-центра, скоростные NVMe накопители и максимальный SLA доступности. Подберите надёжный сервер у проверенных облачных провайдеров.
Развернуть безопасный VDS в Selectel →Рекомендуемые VDS-провайдеры
Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с
Timeweb Cloud
Мощные VDS с выделенным чистым IPv4, аппаратной защитой от DDoS на уровне L3/L4, NVMe накопителями и мгновенной установкой готовых дистрибутивов Ubuntu 24.04 LTS.
Selectel
Отказоустойчивая инфраструктура в дата-центрах Tier III с приватными сетями vLAN, BGP-маршрутизацией и гибкой изоляцией сетевых портов на уровне аппаратного фаервола.
Beget
Удобное управление виртуальными серверами, изолированные подсети, автоматические бэкапы и дружелюбная панель с быстрым доступом к VNC-консоли при авариях.