Защита сервера через Fail2ban + GeoIP-фильтрация на Ubuntu
Публичные серверы постоянно «долбят» боты: перебор SSH, эксплойты веб-приложений, флуд. Два простых и эффективных способа отсечь их — Fail2ban (блокировка по поведению) и GeoIP/DankHosts (блокировка по стране/списку). Разберём настройку обоих на Ubuntu.
Часть 1. Fail2ban — блокируем по поведению
Fail2ban следит за логами, считает неудачные попытки и при превышении порога банит IP через firewall (iptables/nftables) на заданное время.
Шаг 1. Установка
sudo apt update && sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
Шаг 2. Базовая конфигурация
Создайте локальный конфиг /etc/fail2ban/jail.local (он перекрывает jail.conf):
[DEFAULT]
# Время бана: 1 час (86400 - сутки)
bantime = 3600
# Число попыток до бана
maxretry = 4
# Окно подсчёта
findtime = 600
# Банящий backend
banaction = iptables-multiport
banaction_allports = iptables-allports
# Игнорировать свои адреса
ignoreip = 127.0.0.1/8 192.168.0.0/16
Шаг 3. Включаем защиты
Секции в /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
[proftpd]
enabled = false # выключите, если нет FTP
Список доступных фильтров (сколько килонастроек внутри):
fail2ban-client dstatus sshd
ls /etc/fail2ban/filter.d/
Шаг 4. Проверка
sudo fail2ban-client status sshd
Покажет активные баны. Просмотр текущих:
sudo fail2ban-client get sshd banned
sudo iptables -L f2b-sshd -n
Снятие бана вручную:
sudo fail2ban-client set sshd unbanip 185.220.101.42
Часть 2. GeoIP — блокируем нежелательные страны
Если к серверу подключаются только из России/СНГ, разумно резать весь остальной мир на входе в SSH/веб. Два подхода.
Вариант A. Через nftables + geoip2-модуль (современный)
В Ubuntu 22.04+ nftables умеет GeoIP нативно через geoip (ядро 5.11+):
sudo modprobe nft_geoip
table inet filter {
set geo_block {
type ipv4_addr
elements = { 1.2.3.4, 5.6.7.8 } # пример - реально генерим списком
}
chain input {
type filter hook input priority filter; policy accept;
ip daddr geoip country CN drop
ip daddr geoip country RU accept
}
}
Модуль
nft_geoipтребует пакетlinux-modules-extra. На типовых VDS редко включён.
Вариант B. Через GeoIP DB + iptables + cron (универсальный)
Самое популярное: скачиваем базу стран в IP-список, заливаем в nftables/iptables, обновляем по cron.
Ставим утилиту сборки:
sudo apt install -y curl ipset gzip
sudo mkdir -p /etc/geoip
Скрипт /usr/local/bin/geoip-block.sh:
#!/bin/bash
# Генерация списка запрещённых подсетей (пример - RU + KG + KZ разрешены):
GEO_URL="https://github.com/herrbischoff/country-ip-blocks/raw/master/ipv4/country_banned"
DROP_LIST="/etc/geoip/banned.txt"
curl -fsSL "$GEO_URL" -o "$DROP_LIST"
# Загрузка в nftables (пример через ipset + iptables)
ipset destroy geo-banned 2>/dev/null || true
ipset create geo-banned hash:net
while read -r net; do
[[ "$net" =~ ^[0-9]+.[0-9]+.[0-9]+.[0-9]+/[0-9]+$ ]] && ipset add geo-banned "$net"
done < "$DROP_LIST"
# iptables правило блокирует входящие из этих подсетей
iptables -I INPUT -m set --match-set geo-banned src -j DROP
Запускаем:
chmod +x /usr/local/bin/geoip-block.sh
sudo /usr/local/bin/geoip-block.sh
sudo crontab -e
# Добавить: 0 3 * * * /usr/local/bin/geoip-block.sh
Перед массовой блокировкой убедитесь, что ваш IP не попал в список (проверьте терминал с другого ПК).
Часть 3. Комбо: Fail2ban + GeoIP на практике
Идеальная комбинация:
- GeoIP блокирует входящий трафик из стран, которых у вас нет.
- Fail2ban банит по поведению — от тех, кто остался (сканирование, перебор).
- rate-limit в nginx защищает от флуда приложений, которые fail2ban не видит.
nginx rate-limit (дополнительный барьер)
# /etc/nginx/conf.d/rate-limit.conf
limit_req_zone $binary_remote_addr zone=apilogin:10m rate=5r/s;
server {
location /login {
limit_req zone=apilogin burst=10 nodelay;
}
}
Тест после настройки
# Проверить, что SSH-порт недоступен из заблокированной страны
# (из другого канала/ВПН)
ssh admin@1.2.3.4 # должно «зависнуть»
Тонкости и подводные камни
- Fast-перебор с многих IP — Fail2ban банит по одному IP. Если атакующий использует программу типа Хydra из-под VPN — баны не помогут. Нужен rate-limit.
- Cloudflare-прокси — если сайт за Cloudflare, fail2ban увидит IP Cloudflare, а не посетителя. Add filter для
CF-Connecting-IPили настраивайте баны на уровне Cloudflare. - Ложные баны — не баним себя: обязательно
ignoreipвашего офисного IP/подсетей. - GeoIP-списки не идеальны — компании спокойно берут IP в соседних странах. География — фильтр грубой очистки, не панацея.
- Сменный IP у вас — если у вас динамический IP, не добавляйте свой регион в DROP без исключения
ignoreip. - nftables geoip — модуль может отсутствовать на дефолтном ядре, проверяйте
modinfo nft_geoip.
Шпаргалка
# Fail2ban
sudo apt install -y fail2ban
fail2ban-client reload
fail2ban-client status sshd
fail2ban-client set sshd unbanip 1.2.3.4
# GeoIP
chmod +x /usr/local/bin/geoip-block.sh
/usr/local/bin/geoip-block.sh
(crontab -l; echo "0 3 * * * /usr/local/bin/geoip-block.sh") | crontab -
Проверено на: Ubuntu 22.04/24.04.
Дата: Сентябрь 2026.