Блог лаборанта

Списки IP адресов

Подборка заготовок (примеров/кусков кода) и рабочих Bash скриптов

Актуально для Debian и ему подобных VDS/VPS систем. При необходимости, применимо в большинстве других дистрибутивов, разумеется, с внесением необходимых изменений. Bash скрипты можно запускать в тч через планировщик заданий. Как настроить планировщик - тема достойная изучения предметной статьи.

Доверенные сети

Организация доступа в обход фильтрации iptables и/или фильтрация доступа из различных подсетей, может понадобиться в ряде случаев. К публичному web серверу можно открыть приоритетный доступ для подсетей ПС (Поисковых Систем). К приватному серверу можно открыть доступ только для доверенных сетей. Для тестирования и настройки систем безопасности можно временно давать доступ определенным сетям в обход блокировок в iptables. Могут возникнуть и другие причины использовать Ipset.

Типичный случай: Ipset + Fail2ban + Iptables, где Ipset будет работать в правилах доступа для списков ip и/или подсетей.

Вы конечно уже расставили всякие капканы для злодеев в Fail2ban + Iptables. Скорее всего в iptables еще будут создаваться правила запрета, по определенным признакам, в тч источнику трафика. Значит есть потенциальный риск забанить то, что банить не следует.

Допустим, хотим все сети Google в отдельный список и разрешающее правило для списка доверенных сетей, чтобы избавить трафик от дальнейшей фильтрации и в бан не отправлять, чего туда не надо отправлять.

Проверим наличие необходимых программных пакетов:

$ ipset version
ipset v6.38, protocol version: 6
$ jq --version
jq-1.5-1-a5b5cbe

В нашем случае, установка дополнительных программных пакетов не требуется.

Срочно гуглить и ставить ipset и jq, если их нет в вашей системе.

$ sudo apt install ipset

Данные сетей официально заявленных Google, будем получать в формате json и для удобства обработки установим jq.

Используя jq, можно с легкостью парсить, фильтровать, мапить и преобразовывать JSON-структуру данных.

Установите jq из репозитория вашего дистрибутива Linux.

$ sudo apt install jq

Создаваемые файлы для решения задачи, будут зависимы друг от друга, по этому создаем рабочий каталог и работаем только в нем.

$ mkdir ~/ipscripts
$ cd  ~/ipscripts

Список всех подсетей Google

$ nano gjson
#!/bin/bash
############
# google networks jq json parser
# © hflab.ru, 2022
############
# проверяем 1-й параметр
if [ ! -n "$1" ]; then
  echo "Error: param  is emty"
  echo "eg: $0 bot "
  echo "eg: $0 google "
  exit 1
fi
# проверяем 2-й параметр
if [ ! -n "$2" ]; then
  echo "Error: parameter  is emty"
  echo "eg: $0 $1 ipv4"
  exit 1
fi
# проверяем параметры и определяем источник
if [[ "$1" == "bot" ]]; then
        source="https://developers.google.com/search/apis/ipranges/googlebot.json"
elif [[ "$1" == "google" ]]; then
        source="https://www.gstatic.com/ipranges/goog.json"
else
        echo "Error: parameter  is invalid"
        exit 1
fi
# проверяем параметры и определяем ipv
if [[ "$2" == "ipv4" ]]; then
        prefix=ipv4Prefix
elif [[ "$2" == "ipv6" ]]; then
        prefix=ipv6Prefix
else
        echo "Error: parameter  is invalid"
        exit 1
fi
# делаем запрос и получаем данные
list=$(curl -sS "$source" | jq -r ".prefixes[].$prefix")
# сохраняем полученные данные
echo "$list" >> gjson_tmp
echo "Список подсетей сохранен в gjson_tmp"
exit 0
$ chmod +x gjson

При запуске скрипту передаются два обязательных параметра. В первом параметре всего два варианта либо подсети Google Bot или остальные подсети Google. Второй параметр указывает на версию ipv4

Для того чтобы при получения всех подсетей не прогонять скрипт с разными параметрами несколько раз, создадим сценарий запуска в отдельном файле, в котором напишем инструкции обработки полученных данных. Результат выполнения - сохранение списка всех подсетей Goole и Google Bot в ipset

$ nano google-ips

#!/bin/bash
############
# google networks jq json parser 
# © hflab.ru, 2022
############
today=`date '+%y-%m-%d %H:%M'`;
echo $today > googlenets
./gjson bot ipv4
echo "bot ipv4 done"
./gjson google ipv4
echo "google ipv4 done"
cat ./gjson_tmp | sort -u -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n >> googlenets
echo "googlenets done"
echo ""
if ! /usr/sbin/ipset -quiet -name list googlenets >/dev/null;
then /usr/sbin/ipset -quiet -exist create googlenets hash:net;
fi
for ip in $(cat ./googlenets | sort -u -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n);
do
/usr/sbin/ipset --test googlenets $ip || /usr/sbin/ipset add googlenets $ip -exist
done
echo "googlenets list complite"
echo ""
ipset list googlenets  | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n
echo ""
exit 0
$ chmod +x google-ips

Далее создаем разрешающее правило iptables: если протокол и порты назначения tcp 80,443 и источник есть в googlenets и ставим его вше всех запрещающих правил чтобы гугл всегда мог посетить сайты на этом сервере. Чтобы знать, когда и откуда Google делает запросы на сайты, будем писать отдельный лог. Для этого, над только что созданным правилом создаем правило для записи лога.

-A INPUT -m set --match-set googlenets src -j LOG --log-prefix "ACCESS GOOGLE: " --log-level 6
-A INPUT -p tcp -m tcp -m multiport --dports 80,443 -m set --match-set googlenets src -j ACCEPT

Позаботьтесь о том, чтобы эти правила применились в текущей конфигурации и при старте сети. Кстати есть важный нюанс окотором стоит обязательно упомянуть. Списки Ipset должны быть созданы и загружены раньше правил Iptables. Если при старте не будут найдены списки указанные в правилах Iptables - последствия будут печальными.

Сохраняем правила и списки

$ sudo ipset save > /etc/ipset.up.rules
$ sudo iptables-save > /etc/iptables.up.rules

Ставим в очередь при старте сети

$ sudo nano /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
        pre-up ipset restore < /etc/ipset.up.rules
# The primary network interface
allow-hotplug eth0
iface eth0 inet static
        address X.X.X.Y/Z
        gateway X.X.X.X
        dns-nameservers X.X.X.X Y.Y.Y.Y
        post-up iptables-restore < /etc/iptables.up.rules
        # dns-* options are implemented by the resolvconf package, if installed

Где:

        address X.X.X.Y/Z
        gateway X.X.X.X
        dns-nameservers X.X.X.X Y.Y.Y.Y

Параметры сети. При такой конфигурации, перед стартом локальной петли загрузятся сохраненные списки Ipset. Затем, после старта сетевого адаптера, загрузятся сохраненные правила Iptables.

Сохраняем конфиг и перезапускаем сеть:

$ sudo systemctl restart networking

Проверяем правила.

$ iptables -L

Далее создаем правим конфиг rsyslog

$ sudo nano /etc/rsyslog.d/10-custom.conf
:msg,contains,"GOOGLE" /var/log/iptables-google.log
:msg,contains,"GOOGLE" stop
$ sudo systemctl restart rsyslog

Теперь iptables будет писать отдельный лог для подклчений из сетей Google в файл /var/log/iptables-google.log

При длительном логировании рекомендуется настроить ротацию.

Запускаем скрипт google-ips

$ sudo ./google-ips
Список подсетей сохранен в gjson_tmp
bot ipv4 done
Список подсетей сохранен в gjson_tmp
google ipv4 done
googlenets done
done
8.8.4.0/24 is in set googlenets.
8.8.8.0/24 is in set googlenets.
8.34.208.0/20 is in set googlenets.
8.35.192.0/20 is in set googlenets.
*.*.*.*
216.73.80.0/20 is in set googlenets.
216.239.32.0/19 is in set googlenets.
googlenets list complite

Name: googlenets
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 9368
References: 1
Number of entries: 150
Members:
8.8.4.0/24
8.8.8.0/24
8.34.208.0/20
8.35.192.0/20
*.*.*.*
216.73.80.0/20
216.239.32.0/19

Если все вышеописанное сделано верно, то вывод строки Number of entries: 150 - фактически означает, что 150 подсетей Google первым правилом iptables разрешен доступ к сайту. Значение (количество подсетей) можно менять в ./google-ips, поставив # (знак решетки) в начале одной из строк:

./gjson bot ipv4
#./gjson google ipv4
Скрипт google-ips можно запускать вручную или добавить в планировшик Cron для автоматического запуска по расписанию.

Аналогично можно приоритетно разрешить подключения любым хостам и подсетям, в тч других ПС.

Альтернативный способ получить нужные подсети:

https://bgpview.io/search/Google#results-v4

Список подсетей Яндекс

https://yandex.ru/ips
nslookup -q=TXT _spf-ipv4.yandex.ru 8.8.8.8
Server:		8.8.8.8
Address:	8.8.8.8#53

Non-authoritative answer:
_spf-ipv4.yandex.ru	text = "v=spf1 ip4:213.180.223.192/26 ip4:37.9.109.0/24 ip4:37.140.128.0/18 ip4:5.45.192.0/19 ip4:5.255.192.0/18 ip4:77.88.0.0/18 ip4:87.250.224.0/19 ip4:93.158.136.48/28 ip4:95.108.130.0/23 ip4:95.108.192.0/18 ip4:141.8.132.0/24 ip4:5.45.254.0/25 ~all"

Список подсетей Телеграм

https://core.telegram.org/resources/cidr.txt

Извлечь список всех IP указав подсеть и маску

Если возникнет необходимость, вот годный скрипт с форума https://www.linux.org.ru/forum/development/12685463?cid=12686844 Результаты его работы применимы для дальнейшей обработки в зависимости от поставленной задачи.

$  nano ipmask2iplist
#!/bin/bash
dec2abcd () {
    local dec="$1" abcd
    for i in {3..0}; do
        (( abcd[i] = dec / 256 ** i,
           dec %= 256 ** i ))
    done
    echo "${abcd[3]}.${abcd[2]}.${abcd[1]}.${abcd[0]}"
}

IFS='./' read a d c d m <<< "$1"

(( ip = a * 256 ** 3 + b * 256 ** 2 + c * 256 + d,
   hosts = 2 ** (32 - m),
   mask = 2 ** 32 - hosts,
   net = ip & mask ))

for (( host = net + 1; host < net + hosts - 1; host++ )); do
    dec2abcd "$host"
done
exit 0
$ chmod +x ipmask2iplist

Пример запроса и вывода результата

$ ./ipmask2iplist 192.168.12.56/22
192.0.12.1
192.0.12.2
*.*.*.*
192.0.15.253
192.0.15.254

Читать продолжение: Блокировка по спискам IP адресов.

Навигация