Мини Вики. Чтоб ничего не забыть!

Блокируем много IP адресов


Роскомнадзор действует очень жестко, облагая провайдеров штрафами. Поэтому перечить ему не стоит. Будем иполнять требования государственных органов, а именно: блокировать доменные имена из запрещенного списка, а так же список IP адресов.

Хорошо когда список небольшой, с помощью iptables это решается элементарно, но вот когда адресов пару десятков тысяч ... тут уже приходится не сладко.

И тут на помощь к нам приходит ipset.
Ipset позволяет использовать большие таблицы IP и MAC адресов, подсетей, номеров портов совместно с iptables (подключение производится через одно правило, в таблице используется хэширование). Возможно быстрое обновление списка целиком.

Официальная страница - ipset.netfilter.org.
ipset представляет из себя модуль ядра ip_set, ряд вспомогательных библиотек и утилиту ipset для задания параметров. Установка тривиальна, во всех современных дистрибутивах присутствует пакет с одноименным названием.

Модуль ядра можно проверить командой:

# modprobe ipt_set

Устанавливаем:

# yum install ipset

Блокируем.

В ipset нет таблиц, а есть set различных типов. Типы позволяют задавать ip адреса из определенной подсети (ipmap тип), связки ip адресов с MAC адресами (macipmap), порты из заданного диапазона (portmap), набор ip адресов или сетей (iphash, nethash), разные комбинации этих set-ов, или даже хранить ip адреса в set только определенное время (iptree). Более подробно советую посмотреть man ipset(8).

Для нашей задачи подходит тип iphash. Создаем (N -new) set с именем blacklist, и смотрим его содержимое:

# ipset -N blacklist iphash
# ipset -L blacklist
Name: blacklist
Type: hash:ip
Revision: 0
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16480
References: 0
Members:

Добавляем (A - add) ip адреса blacklist и смотрим (L - list) содержимое set:

# ipset -A blacklist 192.168.0.211
# ipset -A blacklist 10.10.0.23
# ipset -L blacklist
Name: blacklist
Type: hash:ip
Revision: 0
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16512
References: 0
Members:
10.10.0.23
192.168.0.222

Удаляем ip адреса из blacklist set (D - delete):

# ipset -D blacklist 192.168.0.222
# ipset -L blacklist
Name: blacklist
Type: hash:ip
Revision: 0
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16512
References: 0
Members:
10.10.0.23

Проверяем, есть ли ip в blacklist set (T - test):

# ipset -T blacklist 10.10.0.23
10.10.0.23 is in set blacklist.

Удаляем все ip адреса из blacklist set (F - flush):

# ipset -F blacklist

Удаляем сам set (X):

# ipset -X blacklist

Для того чтобы добавить весь список адресов в сет, нам придется воспользоваться скриптом. Мой выглядит так:

#!/bin/sh
IPS="ipset"
# очищаем все цепочки правил
$IPS -F blacklist
$IPS -X blacklist
$IPS -N blacklist iphash
cat /usr/rkn/ip.list | while read str; do
$IPS -A blacklist ${str}
done

После создания set нам необходимо пропустить его через какую-либо цепочку фильтра iptables. Вспомним путь прИхождения внешнего пакета в правилах iptables, сверху вниз:

-t raw PREROUTING
-t mangle PREROUTING
-t nat PREROUTING
-t mangle INPUT
-t filter INPUT

Я делал так:

#iptables -A FORWARD -m set --match-set blacklist src -j DROP

Т.е. мы подключили модуль set (-m set), потом указали какое совпадение set использовать (--match-set blacklist). src - это флаг, который показывает какие ip сравнивать с set, src (source - источник) или dst (destination - назначение).