← Назад к альманаху
🛡️

Fail2ban и безопасность

Два уровня защиты: встроенные лимиты Xray и системный Fail2ban с банами через UFW. Разбираем, как это работает и как настроить.

Зачем нужен Fail2ban в контексте прокси

Прокси-сервер, доступный из интернета, постоянно подвергается сканированию и попыткам подбора. Даже если сам протокол устойчив к атакам, тысячи неудачных подключений создают шум и нагрузку. Fail2ban автоматически банит IP-адреса, которые превышают порог неудачных попыток, на уровне фаервола — до того, как они дойдут до Xray.

В 3x-ui есть два независимых механизма: встроенный (на уровне Xray) и системный (Fail2ban + UFW). Они дополняют друг друга.

Уровень 1: встроенные лимиты Xray

В настройках клиента можно задать limitIp — максимальное число одновременных IP. Если клиент подключается с большего числа адресов, Xray временно блокирует новые соединения. Это не бан на уровне фаервола, а ограничение внутри самого прокси.

Преимущество: работает без внешних зависимостей. Ограничение: защищает только от «расшаривания» аккаунта, но не от сканеров, которые стучатся на порт без валидных учётных данных.

Лог для Fail2ban

3x-ui пишет попытки подключения в /var/log/x-ui/3xipl.log. Формат строк пригоден для разбора фильтром Fail2ban.

Уровень 2: системный Fail2ban

Fail2ban читает лог 3x-ui и при превышении порога вызывает действие — обычно бан через UFW или iptables. В отличие от встроенного лимита, здесь IP блокируется на уровне фаервола: пакеты отбрасываются ещё до Xray.

Джейл 3x-ipl

[3x-ipl]
enabled = true
filter = 3x-ipl
action = 3x-ipl
logpath = /var/log/x-ui/3xipl.log
maxretry = 1
findtime = 32
bantime = 30m

maxretry = 1 означает, что достаточно одной неудачной попытки для бана (если фильтр ловит именно «неудачную попытку»). findtime = 32 — окно в секундах.

Джейл nginx-scanner

Если перед панелью стоит Nginx, имеет смысл добавить джейл для сканеров веб-уязвимостей. Он читает /var/log/nginx/access.log и банит IP, которые запрашивают типичные сканерские пути (/.env, /wp-login.php, //xmlrpc.php и т.д.) с кодами 301/302/400/401/403/404.

Джейл recidive

Recidive — «джейл для джейлов». Он читает /var/log/fail2ban.log и банит IP, которые уже были забанены несколько раз в течение длительного периода (например, 30 дней). Это отсекает «настойчивых» нарушителей, которые возвращаются после разбана.

Бан через UFW, а не iptables

По умолчанию Fail2ban использует iptables. Если на сервере уже есть UFW (что типично для Ubuntu), лучше перенаправить баны туда, чтобы не дублировать правила и видеть всё в одном месте.

[DEFAULT]
banaction = ufw
banaction_allports = ufw

В Debian/Ubuntu есть готовый action.d/ufw.conf, который выполняет ufw insert 1 reject from <ip>. Проверить, что бан попал в UFW: ufw status | grep <ip> — должно быть REJECT.

Рекомендации по настройке

Практический эффект: после включения nginx-scanner и recidive количество повторных попыток с одних и тех же IP резко падает. Сканеры, которые раньше возвращались каждые несколько минут, получают бан на сутки и больше.

⚠️ О статусе VPN

Использование VPN в России разрешено, но не является желательным. Fail2ban — стандартная практика администрирования, не связанная с правовым статусом прокси. Защита сервера от несанкционированного доступа не является чем-то специфическим для VPN.