ipset
IPset это утилита командной строки, которая используется для администрирования базы под названием IP и находиться внутри ядра Linux. Набор IP может хранить IP-адрес, номера портов сети (TCP / UDP), MAC – адрес, имена интерфейсов или их комбинации в пути, что обеспечивает скорость молнии при совмещении записи против набора. Это ассоциативное приложение Правила iptables для брандмауэра в Linux, который позволяет нам с правилами установок быстро и легко заблокировать набор IP-адреса.
Утилита ipset дает возможность написать правило, только одно, а не использовать много однотипных правил iptables что позволяет ускорить работу iptables.
ipset представляет из себя модуль ядра ip_set, ряд вспомогательных библиотек и утилиту ipset для задания параметров.
# aptitude install ipset
Создается список:
ipset -N dropips iphash
, где dropips — название списка, iphash — тип списка, служит для хранения IP-адресов, хэширования предотвращает добавление в список дублирующих IP-адресов. Существуют типы списков для работы с ip-адресами, подсетями, портами, mac-адресами.
Добавляются IP-адреса в список:
ipset -A dropips 192.168.95.7
или считывать из файла при помощи скрипта
IST="/usr/sbin/ipset" # IPSET $IST -N dropips iphash $CAT $PATH/ipset.txt | ( while read ip; do $IST -A dropips $ip done ); $IPT -A INPUT -m set --match-set dropips src -j DROP # END IPSET
Создается правило для использования списка:
iptables -A INPUT -m set --match-set dropips src -j DROP
-m set указывает на использование модуля ipset, –set dropips указывает список IP-адресов, src указывает на то, что сверять нужно только IP-источника. Таким образом, будут отбрасываться все пакеты с IP-адресов, указанных в списке dropips.
Просмотреть список ipset
# ipset -L
ipset v2.5.0: Error from kernel: Protocol not available
Устранение ошибки для Debian Wheezy, Ubuntu 11.10. Модуль ядра для ipset нужно установить с помощью module-assistant.
# aptitude install ipset netfilter-extensions-source xtables-addons-source # uname -a Linux spar 3.0.0-1-amd64 #1 SMP Sat Aug 27 16:21:11 UTC 2011 x86_64 GNU/Linux # aptitude install linux-headers-3.0.0-1-all-amd64 # cd /usr/src # tar xjf netfilter-extensions.tar.bz2
Компиляция модуля. m-a a-i сокращение от module-assistant auto-install.
# module-assistant prepare # m-a a-i netfilter-extensions
# module-assistant prepare # module-assistant auto-install xtables-addons-source
Повышение производительности netfilter, использование ipset
iptables — интерфейс к файрволу Linux (netfilter). При большом количестве правил iptables нагрузка может быть достаточно высокой и создавать проблемы. В этой заметке я постараюсь описать, что влияет на производительность iptables и как ее повысить.
Основная причина нагрузки
Для начала: из-за чего вообще возникает нагрузка при большом количестве правил? Из-за того, что каждому сетевому пакету, обрабатываемому ядром, приходится проходить сравнение по всему списку правил каждой цепочки. Приведу схему, которая отражает цепочки netfilter и порядок прохождения по ним пакетов:
На схеме видно через какие цепочки пройдет тот или иной пакет и можно оценить нагрузку. Возьмем одно простейшее правило:
-A INPUT -s 10.1.1.1/32 -p tcp —dport 25 -j DROP
Это правило указывает файрволлу отбрасывать все пакеты с IP-адреса 10.1.1.1 на порт 25 локальной машины. Таблицу (-t) я не указываю, поэтому будет использоваться дефолтная (-t filter), что нам и нужно. Понятно, что действие DROP выполняется далеко не всегда. Однако, сравнение IP-адреса источника будет проходить любой входящий на локальную машину пакет. А если таких правил тысяча?
Что делать?
Теперь подумаем, как можно ускорить работу файрволла. Первый ответ очевиден — сокращать количество правил. Но вряд ли удастся серьезно оптимизировать записи, особенно если они изначально составлялись грамотно. Где-то вместо правил на несколько IP-адресов можно написать одно правило на подсеть. Где-то вместо правил на несколько портов можно использовать -m multiport и —dports / —sports a,b,c (a,b,c — номера портов). И так далее.
Ветвление правил, дополнительные цепочки
А есть еще второй вариант — использование ветвлений правил. Суть его в том, что однотипные правила группируются в отдельную цепочку, а в основной цепочке остается одно правило, которое перенаправляет пакет в отдельную цепочку в зависимости от какого-то общего признака пакетов. Приведу пример. Имеются три правила:
-A INPUT -s 10.1.1.1/32 -p icmp -j ACCEPT
-A INPUT -s 10.1.1.2/32 -p icmp -j ACCEPT
-A INPUT -s 10.1.1.3/32 -p icmp -j ACCEPT
Что объединяет эти правила? Одинаковый протокол — icmp. Вот по этому признаку и стоит сгруппировать правила. Вообще в данном случае эффективнее использовать ipset, но об этом дальше. Для группировки необходимо создать новую цепочку, а затем создать правило, которое будет отправлять пакеты в эту цепочку.
Создать цепочку PROT_ICMP:
iptables -N PROT_ICMP
Определить правила в этой цепочке:
-A PROT_ICMP -s 10.1.1.1/32 -j ACCEPT
-A PROT_ICMP -s 10.1.1.2/32 -j ACCEPT
-A PROT_ICMP -s 10.1.1.3/32 -j ACCEPT
Как видите, протокол (-p) в этой цепочке мы уже не проверяем, т.к. отправлять в эту цепочку будем только ICMP пакеты. И наконец отправить все пакеты ICMP в эту цепочку:
-A INPUT -p icmp -g PROT_ICMP
Теперь входящий пакет, если он не ICMP, будет проходить лишь через одно правило вместо трех.
ipset
А теперь предположим следующую ситуацию:
-A INPUT -s 10.1.1.1/32 -j DROP
-A INPUT -s 10.1.1.2/32 -j DROP
-A INPUT -s 10.1.1.3/32 -j DROP
Несколько однотипных правил, но сгруппировать их или сделать дополнительную цепочку не представляется возможным. В таких случаях, когда необходимо делать проверку по большому количеству IP-адресов и/или портов, на помощь приходит ipset. ipset представляет из себя модуль ядра ip_set, ряд вспомогательных библиотек и утилиту ipset для задания параметров. Наверняка есть в репозиториях вашего дистрибутива, так что с установкой не должно быть проблем.
Используется следующим образом:
* Создается список:
ipset -N dropips iphash
dropips — название списка, iphash — тип списка. Типы списков можно посмотреть в man ipset, они есть на любой вкус — для работы с ip-адресами, подсетями, портами, mac-адресами. iphash служит для хранения IP-адресов, использование хэширования предотвращает добавление в список дублирующих IP-адресов.
* Добавляется IP-адрес в список:
ipset -A dropips 10.1.1.1
* Создается правило для использования списка:
iptables -A INPUT -m set —set dropips src -j DROP
-m set указывает на использование модуля ipset, —set dropips указывает список IP-адресов, src указывает на то, что сверять нужно только IP-источника. Таким образом, будут отбрасываться все пакеты с IP-адресов, указанных в списке dropips.
В статье я не стал описывать тюнинг сетевых параметров ядра, а сделал упор на рациональную организацию правил файрволла. Информации о тюнинге очень много можно найти в сети, это различные net.*mem*, в случае большого количества соединений и использования conntrack — параметры net.netfilter.nf_conntrack_max, net.netfilter.nf_conntrack*timeout и т.д.
Спасибо за внимание.
Спасибо ivlis за указание на опечатки.
Что такое IPSet
Опубликовано: 16.06.2017
инструмент для работы с большим количеством IP-адресов и сетевых портов в брандмауэре netfilter. По сути, это список в специальном формате, который передается последнему при настройке.
Пример утилит, которые могут использоваться с ipset — iptables (Ubuntu / Debian), firewalld (CentOS / Red Hat).
Пример команд для создания списка и внесения в него 2-х сетей:
ipset -N newlist nethash
ipset -A newlist 192.168.1.0/24
ipset -A newlist 192.168.2.0/24
Пример для применения созданного списка в iptables:
iptables -I INPUT -m set —match-set newlist src -j DROP
* в данном случае будут блокироваться все входящие запросы от сетей, перечисленных в списке newlist.
Официальная man-страница для IPSet на сайте netfilter.
Встречается в статьях
Инструкции:
Блокируем много IP адресов с помощью ipset и iptables
Вопросы борьбы со спамерами, ботами и прочей нечистью всегда актуальны. Хорошо когда список небольшой, с помощью iptables это решается элементарно, но вот когда адресов пару тысяч … тут уже приходится не сладко.
И тут на помощь к нам приходит ( барабанная дробь ) ipset .
Ipset позволяет использовать большие таблицы IP и MAC адресов, подсетей, номеров портов совместно с iptables (подключение производится через одно правило, в таблице используется хэширование). Возможно быстрое обновление списка целиком.
Официальная страница — ipset.netfilter.org.
ipset представляет из себя модуль ядра ip_set, ряд вспомогательных библиотек и утилиту ipset для задания параметров.
Установка тривиальна, во всех современных дистрибутивах присутствует пакет с одноименным названием.
Модуль ядра можно проверить командой:
# modprobe ipt_set
В Debian 7 и выше:
# apt-get install ipset
В Debian squeeze есть пакет xtables-addons, контент которого дублирует netfilter-extensions, установка:
# aptitude install xtables-addons-source xtables-addons-common # m-a -v -t auto-install xtables-addons
В Gentoo соответственно проверить ядро на присутствие модуля, и установить пакет:
# emerge --ask --verbose ipset
CentOS / RHEL (используйте EPEL репозиторий):
# yum install ipset
Списки блокировок .
Где брать? Как отформотировать для использования?
Первое — список для удобства должен состоять только из ip адресов — по одному в строке, в любом текстовом файле.
Не так давно писал про Denyhosts, итогом работы является обновляемый список адресов в файле /etc/hosts.deny, выглядит вот так:
. ALL: 222.186.15.139 ALL: 98.210.197.168 .
Тут надо просто выбросить первые 5 символов, вот так например:
# cat /etc/hosts.deny | sed 's/ALL: //' >> denyhosts_blacklists.list
Если необходимо отсортировать уникальные (удалить дубликаты):
# sort denyhosts_blacklists.list | uniq > sorted_blacklists.listХорошие, обновляемые, готовые к использованию списки можно взять на форуме stopforumspam.com, будьте внимательны — есть суточное ограничение на количество скачиваний.
/…./
Блокируем .
В 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
*** После создания set нам необходимо пропустить его через какую-либо цепочку фильтра iptables.
Вспомним путь прИхождения внешнего пакета в правилах iptables, сверху вниз:
-t raw PREROUTING -t mangle PREROUTING -t nat PREROUTING -t mangle INPUT -t filter INPUT
Или смотрим картинку.
Цепочка INPUT обрабатывает запросы, которые идут непосредственно на машину с iptables. Если надо блокировать трафик, который проходит от клиента к серверу через данную машину транзитно, то нужно использовать FORWARD, а то и PREROUTING.
Пример с INPUT :
** Правило не добавляем ( -A ), а вставляем ( -I ) в начало цепочки INPUT правил.
# iptables -v -I INPUT -m set --match-set blacklist src -j DROP DROP all opt -- in * out * 0.0.0.0/0 -> 0.0.0.0/0 match-set blacklist src
Т.е. мы подключили модуль set ( -m set ), потом указали какое совпадение set использовать ( —match-set blacklist ). src — это флаг, который показывает какие ip сравнивать с set, src ( source — источник ) или dst ( destination — назначение ) . Если нужно проверить и src и dst , то флаг задается так src,dst .
Посмотрим цепочку INPUT, на предмет нашего правила ipset (часть вывода):
# iptables -L INPUT -n -v --line-numbers Chain INPUT (policy DROP 189 packets, 12489 bytes) num pkts bytes target prot opt in out source destination 1 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set blacklist src 2 108K 2115M ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 3 18702 1834K ACCEPT all -- eth1 * 0.0.0.0/0 0.0.0.0/0 4 3266 331K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 5 23 920 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID 6 0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02 ctstate . .
Хорошо видно, что наше правило (1) встало на первое место, т.е. пакеты при прохождении не минуют наш blacklist set .Пример с FORWARD и логированием:
# iptables -v -I FORWARD -m set --match-set blacklist src -j DROP DROP all opt -- in * out * 0.0.0.0/0 -> 0.0.0.0/0 match-set blacklist src # iptables -v -I FORWARD -m set --match-set blacklist src -j LOG --log-prefix "DROP blacklist entry" DROP all opt -- in * out * 0.0.0.0/0 -> 0.0.0.0/0 match-set blacklist src
** Замечание — почему логирование стоит вторым в инсерте правил? .. потому что мы вставляем правило в начало цепочки, и, казуса, что пакет не дошёл до правила с логированием не случится, в случае если правила мы добавляем, то очередность должна быть обратной, всегда смотрите и проверяйте правила прохождения пакетов:
# iptables -L FORWARD -n -v --line-numbers Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 match-set blacklist src LOG flags 0 level 4 prefix "DROP blacklist entry" 2 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set blacklist src 3 983 55096 TCPMSS tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:0x06/0x02 TCPMSS clamp to PMTU 4 19889 2051K ACCEPT all -- eth1 ppp0 0.0.0.0/0 0.0.0.0/0 5 19375 11M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW,RELATED,ESTABLISHED 6 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
… — все в порядке: сначала в LOG (1), потом в DROP (2), потом остальные правила.
/../
Удалять правила можно вот так:
# iptables -D INPUT -m set --match-set blacklist src -j DROP # iptables -D FORWARD -m set --match-set blacklist src -j DROP # iptables -D FORWARD -m set --match-set blacklist src -j LOG --log-prefix "DROP blacklist entry"
** Логи ipset и iptables искать в логах ядра, потому что это «ядерные» модули.
Я использую syslog-ng, kernel логи ловлю в отдельном файле:
Посмотреть через некоторое время, кто попал в сети можно так:
# grep "DROP blacklist entry" /var/log/syslog-ng/kernel.log
Если не знаете где логи можно грубо (может парсить долго!):
# grep -r "DROP blacklist entry" /var/log/*
Все что осталось, — это написать скрипт, который забирает из файла список блокировок.
Каталог для нашего скрипта (можно использовать любой):
# mkdir /etc/blacklist
Скачиваем список ip адресов и распаковываем его (можно автоматизировать, добавив задание в cron):
# cd /etc/blacklist # wget http://www.stopforumspam.com/downloads/listed_ip_1.zip # unzip listed_ip_1.zip
Примерный вариант скрипта:
#!/bin/bash echo -n "Applying blacklist to IPSET. " ipset -N blacklist iphash xfile=$(cat /etc/blacklist/listed_ip_1.txt) for ipaddr in $xfile do ipset -A blacklist $ipaddr done echo ". Done" echo -n "Applying blacklist to Netfilter. " iptables -v -I INPUT -m set --match-set blacklist src -j DROP iptables -v -I INPUT -m set --match-set blacklist src -j LOG --log-prefix "DROP blacklist entry" echo ". Done"
////**** Вариант скрипта предварительный, хотя много нового в нем не будет, но подправлю позже чуть.
…
upd: Замечание по правилу iptables — если firewall настроен как положено, (политики DROP), и открыты только нужные порты, следует указать более конкретное правило, для конкретного порта:
iptables -I INPUT -m set --match-set blacklist src -p TCP --destination-port 80 -j REJECT iptables -I INPUT -m set --match-set blacklist src -p TCP --destination-port 80 -j LOG --log-prefix "DROP blacklist entry INPUT"
… вот что теперь я наблюдаю у себя в логах:
. /var/log/syslog-ng/kern.log:Sep 28 22:44:02 HGATE kernel: [71402.569028] DROP blacklist entry INPUTIN=ppp0 OUT= MAC= SRC=218.6.12.99 DST=88.87.92.60 LEN=48 TOS=0x08 PREC=0x60 TTL=114 DF PROTO=TCP SPT=61453 DPT=80 WINDOW=8192 RES=0x00 SYN URGP=0 /var/log/syslog-ng/kern.log:Sep 29 01:14:18 HGATE kernel: [80411.694498] DROP blacklist entry INPUTIN=ppp0 OUT= MAC= SRC=79.134.234.200 DST=88.87.92.60 LEN=60 TOS=0x08 PREC=0x60 TTL=57 DF PROTO=TCP SPT=54571 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0 /var/log/syslog-ng/kern.log:Sep 29 01:37:20 HGATE kernel: [81792.214677] DROP blacklist entry INPUTIN=ppp0 OUT= MAC= SRC=176.8.88.134 DST=88.87.92.60 LEN=48 TOS=0x08 PREC=0x60 TTL=123 DF PROTO=TCP SPT=58019 DPT=80 WINDOW=8192 RES=0x00 SYN URGP=0
Можно посмотреть сколько заблокированных (посчитаем количество линий в файле) IP адресов:
# wc -l /etc/blacklist/listed_ip_7.txt 68611 /etc/blacklist/listed_ip_7.txt
Посмотреть на наш ipset и его размер:
# ipset --list -terse Name: blacklist Type: hash:ip Revision: 0 Header: family inet hashsize 4096 maxelem 65536 Size in memory: 142800 References: 0