2026-09-16
Защита сервера через Fail2ban + GeoIP-фильтрация на Ubuntu

Защита сервера через 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 на практике

Идеальная комбинация:

  1. GeoIP блокирует входящий трафик из стран, которых у вас нет.
  2. Fail2ban банит по поведению — от тех, кто остался (сканирование, перебор).
  3. 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.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *