Вариант с использованием IPSET совместно с IPTABLES.
Все будет выполнено на шелл скриптах. Устанавливаем необходимое:
1 2 |
apt update & apt upgrade apt-get install ipset libnet-cidr-perl jq curl wget ipcalc grep gzip |
Теперь пишем наш скрипт /etc/RU/block_noRU_geoip.sh для создания и обновления IPSET:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
#!/bin/sh echo "[start]" # --- Тут не забудьте проверить правильность пути расположения программ IPTABLES=/sbin/iptables IPSET=/sbin/ipset WGET=/usr/bin/wget EGREP=/bin/egrep GREP=/bin/grep CAT=/bin/cat SED=/bin/sed CURL=/usr/bin/curl GZIP=/bin/gzip IPCALC=/usr/bin/ipcalc JQ=/usr/bin/jq BDDIR=/etc/RU timestamp=$(date "+%Y-%m") FILE=$BDDIR/$timestamp-ipcalc.ipv4 FIPSET=$BDDIR/$timestamp-ipset_ru.ipv4 echo "[1]" # --- Получаем список ip для России cd $BDDIR #1#$WGET -q "https://download.db-ip.com/free/dbip-country-lite-$timestamp.csv.gz" -O- | \ #1# $GZIP -cd >$timestamp-dbip-country-lite.csv && $CAT $timestamp-dbip-country-lite.csv | \ #1# $GREP ',RU' | $SED 's/\,RU//g' | $SED 's/\,/-/g' | $GREP '\.' > $FILE #2#$WGET -q "http://www.ipdeny.com/ipblocks/data/countries/ru.zone" -O $FIPSET $CURL -k http://stat.ripe.net/data/country-resource-list/data.json?resource=ru | $JQ -c '.data.resources.ipv4[]' | $SED 's/\"//g' > $FIPSET #1#if [ -f $FILE ]; then #1# if [ -s $FILE ]; then #1# echo "[2]" #1# /usr/bin/perl -MNet::CIDR=range2cidr -lne 'print for range2cidr $_' $FILE > $FIPSET # --- Переносим список ip сетей в ipset с именем таблиицы "russia_ru", а старый список в таблицу "russia_old" if [ -f $FIPSET ]; then if [ -s $FIPSET ]; then echo "[3]" $IPSET create russia_run hash:net echo "[4]" $IPSET create russia_old hash:net echo "[5]" $IPSET flush russia_old echo "[6]" $IPSET swap russia_run russia_old echo "[7]" for ippermitir in $($CAT $FIPSET) do $IPSET add russia_run $ippermitir done echo "[8]" # --- На всякий случай добавляем серые сети ... можно не делать если Вам это не нужно $IPSET add russia_run 10.0.0.0/8 $IPSET add russia_run 172.16.0.0/12 $IPSET add russia_run 192.168.0.0/16 fi fi #1# fi #1#fi echo "[stop]" exit 0 |
Обращаем внимание, что в скрипте есть закомментированные строки в виде #1# или #2# – это разные источники списка ip адресов и соответственно их обработки для ipset.
Если Вам импонируют другие источники кроме RIPE, то предварительно закомментировав строку $CURL -k http://stat.ripe.net/data/country-resource-list/data.json?resource=ru | $JQ -c '.data.resources.ipv4[]' | $SED 's/\"//g' > $FIPSET
, раскомментируйте все #1# или #2# комментарии в зависимости от выбранного источника.
Проверить, что у нас все загрузилось правильно, можно командой
1 |
# ipset list |
Использование
Теперь применяем наш список из IPSET в IPTABLES … в нашем случае для запрета всех пакетов с ip отсутствующих в таблице russia_ru для UDP SIP
1 |
# iptables -I INPUT -i eth0 -p udp -m multiport --dports 5000:50000 -m set ! --match-set russia_run src -j DROP |
Обращаем внимание, что команда установит в самое начало списка наше правило, но это не всегда требуется, а иногда и вредно … вот пример заголовка моего файла конфигурации для iptables
-A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -s 127.0.0.0/8 -j ACCEPT
-A INPUT -p gre -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i eth0 -s 10.0.0.0/8 -p udp -m udp –dport 5000:50000 -j ACCEPT
-A INPUT -i eth0 -s 172.16.0.0/12 -p udp -m udp –dport 5000:50000 -j ACCEPT
-A INPUT -i eth0 -p udp -m multiport –dports 5000:50000 -m set ! –match-set russia_run src -j LOG –log-prefix “BAD_SIP_No_Russia-IPSET: ” –log-level 6
-A INPUT -i eth0 -p udp -m multiport –dports 5000:50000 -m set ! –match-set russia_run src -j DROP
…
Журнал
Пишем журнал сетевого экрана, создать конфигурационный файл для rsyslog (считаем, что он у вас уже установлен в системе).
1 |
touch /etc/rsyslog.d/10-iptables.conf |
Открываем его любым текстовым редактором, например, nano и вносим туда следующие строчки:
1 2 |
:msg, contains, "IPTables-Dropped: " -/var/log/iptables.log & ~ |
Сохраняем изменения в файле. Первая строчка говорит rsyslog, что нужно искать в логе фразу “IPTables-Dropped: “, и когда он её находит, то переносит в файл /var/log/iptables.log
Вторая строчка просто дает понять rsyslog, чтобы найденные строки, подходящие под условия, не дублировались в основной лог /var/log/messages.
Перезапускаем rsyslog:
1 |
service rsyslog restart |
Все, подготовительный этап, позволяющий писать лог iptables в отдельный файл мы сделали.
Правило запрещающее входящий доступ к 443 порту сервера и отправляющее запись в журнал:
1 |
iptables -A INPUT -i venet0 -p tcp -m multiport --dports 443 -m set ! --match-set russia_run src -j LOG --log-prefix "IPTables-Dropped: " --log-level 4 |
Источник: https://otito.pro/Firewall/GEOIP_DEBIAN-11_2
https://pc.ru/articles/iptables-pishem-v-log-vse-otfiltrovannye-pakety
https://serveradmin.ru/debian-nastroyka-servera/