Останнім часом дуже засмучує, коли дивлюсь звіт від 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 допоміг зробити ваш сервер ще трохи захищенішим!