Владельцы VPS в 2025 году живут в условиях постоянного давления на инфраструктуру. Подбор паролей, автоматические сканеры, черви, боты, пробующие SSH и панели администрирования — всё это давно перешло из «теоретических рисков» в рутину. Fail2Ban стал базовым инструментом для защиты, но у него есть ограничение: он реагирует только на заранее заданные шаблоны и не понимает контекст.
Здесь на сцену выходит Python — простой, гибкий и идеальный язык для автоматизации безопасности. Вместе с Fail2Ban он превращает защиту сервера из статической в интеллектуальную.
Этот материал — подробное практическое руководство. Мы разберём, как связать Python с Fail2Ban, расширить его возможности, анализировать логи умнее и автоматизировать реакции на угрозы.
Почему нужна именно связка Python + Fail2Ban
Fail2Ban отлично справляется с типичным брутфорсом: неправильно введённые пароли, частые запросы, подозрительные шаблоны в логах. Но современные атаки стали умнее:
- боты меняют паттерны поведения;
- атаки растягиваются во времени, чтобы не попасть под стандартные лимиты;
- запросы формируются так, что попадают в «серую зону» логов;
- IP часто подменяются (ротация через прокси или TOR).
Fail2Ban остаётся фундаментом, но Python даёт гибкость:
можно анализировать логи как угодно, делать свои правила, работать с данными быстрее.
У Python есть три ключевых преимущества:
- Полный контроль над логикой — можно писать фильтры, которые Fail2Ban не понимает.
- Возможность тяжелой обработки данных: подсчёт, корреляция, временные окна.
- Интеграция с API: Telegram, базы данных, внешние сервисы.
Fail2Ban остаётся системой исполнения наказаний, Python — мозгом.
Сценарии, которые решает Python
1. «Тихий» брутфорс, растянутый на сутки
Fail2Ban не увидит, если IP делает 1 неверный логин в 30 минут. Python — увидит.
2. Анализ подозрительных User-Agent
Старые боты часто маскируются, но повторяют одни и те же строки. Python легко найдет их паттерны.
3. Логика на основе геолокации
Например: блокировать всё, что не из разрешённых стран. Fail2Ban не умеет в геоданные. Python — умеет.
4. Корреляция событий
Если nginx, ssh и fail2ban логируют активность с одного IP, Python может объединить это в одно решение: бан.
5. Реакция на аномалии
Не только «5 ошибок подряд», но и: «подозрительно много 401/403 за короткое время», «много POST без реферера», «запросы к админке из бразильского дата-центра».
Базовый Fail2Ban: фундамент, без которого ничего не работает
Даже если вы собираетесь всё улучшать Python-скриптами, классический Fail2Ban нужно настроить правильно.
Установка
Ubuntu / Debian:
sudo apt update
sudo apt install fail2banБазовые настройки
Файл:
/etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
findtime = 10m
maxretry = 5
bantime = 1hFail2Ban будет банить IP, которые за 10 минут дали 5 неправильных попыток.
Теперь — расширяем возможности.
Добавляем Python как внешний фильтр
Fail2Ban умеет запускать external actions — внешние сценарии. Это позволяет передавать данные в Python-скрипт при каждом бане.
Пример action-файла
Файл:
/etc/fail2ban/action.d/python-notify.conf
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = /usr/bin/python3 /opt/fail2ban/python-ban-handler.py <ip> <failures>
actionunban =Когда Fail2Ban забанит IP, он вызовет Python:
python-ban-handler.py 192.168.0.55 7Теперь создадим сам Python-скрипт.
Python-скрипт, который фиксирует брутфорс-активность
Файл:
/opt/fail2ban/python-ban-handler.py
#!/usr/bin/env python3
import sys
import datetime
import requests
ip = sys.argv[1]
fails = sys.argv[2]
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Записываем в локальный лог
with open("/var/log/custom-bans.log", "a") as f:
f.write(f"{timestamp} - BAN: {ip} ({fails} attempts)\n")Теперь каждое событие блокировки будет аккуратно фиксироваться.
Telegram-уведомления о подозрительной активности
Добавим нотификации.
В конец Python-скрипта:
token = "ВАШ_TG_TOKEN"
chat_id = "ВАШ_CHAT_ID"
msg = f"Fail2Ban заблокировал {ip}\nНеверных попыток: {fails}"
requests.get(f"https://api.telegram.org/bot{token}/sendMessage",
params={"chat_id": chat_id, "text": msg})Теперь вы моментально узнаете, что сервер кто-то атакует.
Интеллектуальный анализ логов на Python (то, чего Fail2Ban не умеет)
Теперь — самое интересное: создаём Python-скрипт, который сам анализирует логи ssh/nginx, выявляет аномалии и отдаёт Fail2Ban команду «забанить IP».
Концепция
- Python читает лог каждые 5 минут
- Извлекает IP
- Считает, сколько попыток было
- Если порог превышен — выполняет бан через Fail2Ban
Пример мини-аналитики логов SSH
#!/usr/bin/env python3
import re
import subprocess
from collections import Counter
logfile = "/var/log/auth.log"
pattern = r"Failed password.*from\s+(\d+\.\d+\.\d+\.\d+)"
with open(logfile) as f:
data = f.read()
ips = re.findall(pattern, data)
counter = Counter(ips)
THRESHOLD = 20 # свой порог
for ip, count in counter.items():
if count > THRESHOLD:
subprocess.run(["fail2ban-client", "set", "sshd", "banip", ip])Этот скрипт банит IP, которые ведут себя на порядок агрессивнее обычного.
Обнаружение атак на web-приложение (nginx + Python)
Fail2Ban работает с nginx, но его фильтры простые.
Python позволяет анализировать веб-логи осмысленно.
Например:
- 100 запросов к /wp-login.php
- 30 POST-запросов из одного IP
- много 403 или 404 подряд
- обход robots.txt
Пример:
import re
from collections import defaultdict
import subprocess
log = "/var/log/nginx/access.log"
pattern = r"(\d+\.\d+\.\d+\.\d+)\s.*\s\"(POST|GET)\s(.+?)\".*\s(\d{3})"
suspicious = defaultdict(int)
with open(log) as f:
for line in f:
m = re.search(pattern, line)
if not m:
continue
ip, method, path, code = m.groups()
# правило: частые 404 или попытки входа
if code == "404" or "login" in path:
suspicious[ip] += 1
for ip, score in suspicious.items():
if score > 50:
subprocess.run(["fail2ban-client", "set", "nginx", "banip", ip])Геолокационная фильтрация на Python
Если сервер обслуживает только Россию, Казахстан и Беларусь,
всё остальное можно жёстко ограничить.
import geoip2.database
import subprocess
reader = geoip2.database.Reader('/usr/share/GeoIP/GeoLite2-Country.mmdb')
allowed = {"RU", "KZ", "BY"}
def geo_check(ip):
try:
r = reader.country(ip)
return r.country.iso_code in allowed
except:
return False
ip = "192.20.15.8"
if not geo_check(ip):
subprocess.run(["fail2ban-client", "set", "ssh", "banip", ip])Интеграция: как связать Python и Fail2Ban в единую систему
Теперь у нас:
- Fail2Ban банит основы
- Python анализирует логи глубже
- Python вызывает Fail2Ban через fail2ban-client
- Python отправляет уведомления
- Python ведёт собственный лог банов
Так мы получаем уровень защиты, который раньше был возможен только на корпоративных системах IDS/IPS.
Как запускать Python-скрипты автоматически
Лучший вариант — systemd-таймер.
Создаём сервис
/etc/systemd/system/python-analyzer.service
[Unit]
Description=Python log analyzer
[Service]
ExecStart=/usr/bin/python3 /opt/fail2ban/analyzer.pyСоздаём таймер
/etc/systemd/system/python-analyzer.timer
[Unit]
Description=Run analyzer every 5 minutes
[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.targetЗапускаем:
systemctl enable --now python-analyzer.timerЗаключение
Fail2Ban остаётся надёжным инструментом против брутфорса, но его сила — в связке с Python.
Python может:
- анализировать логи глубже;
- выявлять сложные сценарии атак;
- делать геофильтрацию;
- отправлять уведомления;
- объединять данные из разных источников;
- принимать решения, которые Fail2Ban не способен обработать.
Такой подход превращает обычную VPS в устойчивую систему, способную адаптироваться к угрозам и реагировать на них автоматически — как это делают компании с полноценными системами кибербезопасности.
Читайте в блоге:
- Настройка Fail2ban на Ubuntu 24.04 LTS и защита от брутфорса
- Fail2ban и UFW: настройка базовой защиты сервера Ubuntu 24.04 LTS
- Безопасность сервера с Ubuntu 24.04: fail2ban, nftables и управление службами

