Deltahost
Deltahost
Facebook
Facebook
Irpin Bike
Веломагазин
Strava
Strava

🏠 Oleksandr Rudenko blog

🚷 Блокування sshd за GeoIP у iptables

03.12.2025 | Олександр

Останнім часом дуже засмучує, коли дивлюсь звіт від logwatch. Кількість ботів, які намагаються брутфорсити систему постійно зростає, хоч і вжиті певні заходи від них. Аналізуючи IP ботів, зрозуміло, що більшисть них лізуть із запоребрика та інших не зовсім притомних країн. Тож виникла ідея, схожа на обмеження для вебсервера, капнути в сторону GeoIP & iptables. Швидко був знайден працюючий алгоритм, тому ділюсь стислим HOWTO для Ubuntu.

Встановлення необхідних пакетів:

# apt install \
    xtables-addons-common \
    geoip-bin \
    libtext-csv-xs-perl \
    libmoosex-types-netaddr-ip-perl \
    gunzip \
    wget

Далі треба створити скрипт, який буде тягнути базу GeoIP, перетворювать у бінарний формат, та перезапускати iptables. Трохи нижче він буде використан для запуску за розкладом: /etc/iptables/db-ip2xt_geoip.sh:

#!/bin/bash

# Database directory
mkdir -p /usr/share/xt_geoip

# Download the latest database
MON=$(date +%m)
YR=$(date +%Y)
wget https://download.db-ip.com/free/dbip-country-lite-${YR}-${MON}.csv.gz -O /usr/share/xt_geoip/dbip-country-lite.csv.gz
gunzip /usr/share/xt_geoip/dbip-country-lite.csv.gz

# Build the database
PWD=`pwd`
cd /usr/share/xt_geoip
if [ -e '/usr/lib/xtables-addons/xt_geoip_build' ] ; then perl /usr/lib/xtables-addons/xt_geoip_build ; fi
if [ -e '/usr/libexec/xtables-addons/xt_geoip_build' ] ; then perl /usr/libexec/xtables-addons/xt_geoip_build ; fi
cd $PWD

# Clean up the downloaded CSV
rm /usr/share/xt_geoip/dbip-country-lite.csv

# Restart iptables
iptables -F ; iptables -X ; ip6tables -F ; ip6tables -X
if rmmod xt_geoip ; then modprobe xt_geoip ; else echo "Error restarting xt_geoip" >&2 ; fi
systemctl restart netfilter-persistent

Корегуєм права на файл:

chmod 755 /etc/iptables/db-ip2xt_geoip.sh

Тепер можна його запустити, сформував початкову базу, також автоматизуєм оновлення, додаванням строки у /etc/crontab:

59 23 1 * * root /etc/iptables/db-ip2xt_geoip.sh >/dev/null 2>&1

Коли база сформована, час «різати» ботів. В моїй схемі крім обмеження по країнам, ще присутній додатковий захист від підбору, через обмеження в часі спроб. В прикладі обмежен доступ з усіх країн, окрім NL та UA. Правка файлів фаєрвола: /etc/iptables/rules.v4, /etc/iptables/rules.v6:

:SSH_BLOCK - [0:0]

-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j SSH_BLOCK
# A1 - Anonymous Proxy, A2 - Satellite Provider
#-A SSH_BLOCK -m geoip --src-cc A1,A2 -j DROP
-A SSH_BLOCK -m geoip ! --src-cc NL,UA -j LOG --log-prefix "block ssh by country: "
-A SSH_BLOCK -m geoip ! --src-cc NL,UA -j DROP
-A SSH_BLOCK -m recent --name block --update --hitcount 2 --seconds 300 -j LOG --log-prefix "block ssh: "
-A SSH_BLOCK -m recent --name block --update --hitcount 2 --seconds 300 -j DROP
-A SSH_BLOCK -m recent --name block --set -j ACCEPT

Тут закоментарен блок блокування проксі та супутникових провайдерів, є і така можливість.

Час перезапустити фаєрвол та згодом подивитись результат роботи:

systemctl restart netfilter-persistent

Далі, для перевірки роботи декілька корисних команд:

1) Дивимся лічильники в фаєрволі, чи щось попадає під правила:

iptables -L -v -n -t filter

2) Дивимся записи в log-файлі по блокуванням:

grep 'block ssh by country' /var/log/syslog

3) І саме цікаве — перелік IP паганців за країною:

for i in `grep 'block ssh by country' /var/log/syslog | sed -r 's/.+ SRC=//' | sed -r 's/ .+//'` ; do \
    echo -n "$i " ; geoiplookup $i | sed -r 's/.+: //' ; \
done | sort | uniq | grep -v 'resolve'

Таким нехитрим методом, можна закрити будь який сервіс від небажаних сусідів. Наприклад, можна навідь ICMP закрити для всієї хробачої держави.

Сподіваюсь, цей HOWTO допоміг зробити ваш сервер ще трохи захищенішим!


Коментарі

⬆️ Наверх сторінки