Bekijk de volledige versie : ipset в прошивке энтузиастов
ryzhov_al
27-03-2013, 06:37
Пример блокировки входящего трафика с TOR-нод и трафика с определённых стран средствами ipset
Коллеги, начиная с ревизии r4958 в прошивке есть всё необходимое для работы ipset (http://habrahabr.ru/post/108691/) — изюмительного механизма перечисления кучи адресов или подсетей для iptables. Ниже представлен пример использования ipset для блокирования входящего на роутер трафика от TOR-нод и трафика из указанных вами стран. Транзитный трафик для клиетов за роутеров никак не затрагивает. Другими словами, заблокировав (в примере ниже) по ip-подсетям Китай, вы предотвратите попытке взломать ваш роутер с китайских ip-адресов, однако китайские сайты dx.com, chinawebshop и прочие будут по прежнему доступны с клиентских компьютеров.
$ cat /usr/local/sbin/post-firewall
#!/bin/sh
# Loading ipset modules
lsmod | grep "ipt_set" > /dev/null 2>&1 || \
for module in ip_set ip_set_nethash ip_set_iphash ipt_set
do
insmod $module
done
# Preparing folder to cache downloaded files
IPSET_LISTS_DIR=/tmp/ipset_lists
[ -d "$IPSET_LISTS_DIR" ] || mkdir -p $IPSET_LISTS_DIR
# Block traffic from Tor nodes
if [ "$(ipset --swap TorNodes TorNodes 2>&1 | grep 'Unknown set')" != "" ]
then
ipset -N TorNodes iphash
[ -e $IPSET_LISTS_DIR/tor.lst ] || wget -q -O $IPSET_LISTS_DIR/tor.lst http://torstatus.blutmagie.de/ip_list_all.php/Tor_ip_list_ALL.csv
for IP in $(cat $IPSET_LISTS_DIR/tor.lst)
do
ipset -A TorNodes $IP
done
fi
iptables-save | grep TorNodes > /dev/null 2>&1 || iptables -I INPUT -m set --match-set TorNodes src -j DROP
# Block incoming traffic from some countries. cn and pk is for China and Pakistan. See other countries code at http://www.ipdeny.com/ipblocks/
if [ "$(ipset --swap BlockedCountries BlockedCountries 2>&1 | grep 'Unknown set')" != "" ]
then
ipset -N BlockedCountries nethash
for country in pk cn
do
[ -e $IPSET_LISTS_DIR/$country.lst ] || wget -q -O $IPSET_LISTS_DIR/$country.lst http://www.ipdeny.com/ipblocks/data/countries/$country.zone
for IP in $(cat $IPSET_LISTS_DIR/$country.lst)
do
ipset -A BlockedCountries $IP
done
done
fi
iptables-save | grep BlockedCountries > /dev/null 2>&1 || iptables -I INPUT -m set --match-set BlockedCountries src -j DROP
На хиленьком DIR-320 деградации производительности роутера выявить не удалось:
http://s019.radikal.ru/i638/1303/f4/b4e2a9a4d5adt.jpg (http://radikal.ru/F/s019.radikal.ru/i638/1303/f4/b4e2a9a4d5ad.png.html)
несмотря на то, что в случае Китая, фильтруются, на минуточку…
$ cat /tmp/ipset_lists/cn.lst | wc -l
1943
…подсетей. Если бы эти подсети пришлось заводить в iptables построчно, то роутер бы стихами заговорил.
Подвох в том, что строчки набора ipset предварительно хэшируются, причём длина хэша интелектуально выбирается минимально необходимой, а в процессе фильтрации, соответственно, идёт поиск не по адресам\подсетям, а по хэшам.
ryzhov_al
27-03-2013, 11:16
Простите, что ipset никак не уймусь, но похоже, теперь проще простого «втащить» на роутер функционал PeerGuardian (http://en.wikipedia.org/wiki/PeerGuardian). Вот пример использования блэк-листа Bluetack level1 (http://www.iblocklist.com/list.php?list=bt_level1), блокирующего более 250 тыс. диапазонов (более 8 млн. ip адресов) фейкового пир-обмена:
#!/bin/sh
# Loading ipset modules
lsmod | grep "ipt_set" > /dev/null 2>&1 || \
for module in ip_set ip_set_iptreemap ipt_set
do
insmod $module
done
# PeerGuardian rules
if [ "$(ipset --swap BluetackLevel1 BluetackLevel1 2>&1 | grep 'Unknown set')" != "" ]
then
ipset --create BluetackLevel1 iptreemap
[ -e /tmp/bluetack_lev1.lst ] || wget -q -O - "http://list.iblocklist.com/?list=bt_level1&fileformat=p2p&archiveformat=gz" | \
gunzip | cut -d: -f2 | grep -E "^[-0-9.]+$" > /tmp/bluetack_lev1.lst
for IP in $(cat /tmp/bluetack_lev1.lst)
do
ipset -A BluetackLevel1 $IP
done
fi
iptables -I FORWARD -m set --match-set BluetackLevel1 src,dst -j DROP
«Взлетело» даже на DIR-320, правда занявши в свопе полтора мегабайта. Следственно, должно нормально «взлететь» на любом другом роутере с RAM 64Мб и более. Насколько низенько будет летать? Не знаю, я на четырёхмегабитном канале «тормозов» пока не замечаю. Заинтересованных приглашаю к тестированию.
ryzhov_al
01-04-2013, 14:33
«Вылизал» оба скрипта, приведённые выше. Добавил защиту от повторных срабатываний.
Скрипт из первого поста можно без каких-либо правок использовать в /usr/local/sbin/post-firewall, а вот второй настоятельно рекомендую использовать исключительно автономно. Хэширование 8 млн. адресов на RT-N66U выполняется ~25 минут.
/usr/local/sbin/post-firewall из первого примера выполняется:
~25 секунд на RT-N66U,
~95 секунд на DIR-320.
ryzhov_al
01-04-2013, 14:33
Вспомнил первое впечатление после перехода с Symbian на Android
— в последнем без учётной записи gmail делать нечего.
По этой же причине я не смог ужиться с Win8: в ней даже локальный
аккаунт заводится не очевидно, через отказ от Live ID.
Каждый второй виджет Metro'шного интерфейса ломится в интернет для обновления
своего содержимого, а скайп не установишь, не побывав в Магазине приложений.
Мне правда не нравится онлайновые сервисы, которые я не просил.
От Майкрософта мне нужна только работа скайпа.
Предлагаемый ниже скрипт блокирует на роутере все обращения на IP-адреса,
принадлежащие Майкрософту, оставляя работоспособным только скайп.
Это два набора ipset (http://wl500g.info/showthread.php?30870), последовательно:
запрещающих все IP Майкрософта,
разрешающих обращения к IP-адресам, необходимым для работы скайпа.
Формируем список подсетей Майкрософта:
wget -q -O - "http://list.iblocklist.com/?list=bt_microsoft&fileformat=p2p&archiveformat=gz" | \
gunzip | cut -d: -f2 | grep -E "^[-0-9.]+$" > microsoft.lst
Формируем список ip-адресов, необходимых для работы скайпа:
opkg install bind-dig bash
#!/opt/bin/bash
for ip in $(for i in {0..20} ; do dig +short dsn$i.d.skype.net; done | sort -u | grep -E "^[1-9]")
do
echo $ip >> skype.lst
done
Загружаем необходимые модули ipset:
for module in ip_set ip_set_nethash ip_set_iphash ipt_set
do
insmod $module
done
Заводим сеты и последовательно вносим в них сформированные списки:
ipset -N Microsoft iptreemap
for IP in $(cat microsoft.lst)
do
ipset -A Microsoft $IP
done
ipset -N Skype iptreemap
for IP in $(cat skype.lst)
do
ipset -A Skype $IP
done
Осталось добавить правила iptables для блокировки первого списка
и разблокировки второго:
iptables -I FORWARD -m set --set Microsoft src,dst -j DROP
iptables -I FORWARD -m set --set Skype src,dst -j ACCEPT
Приведённый выше синтаксис ipset адаптирован для asuswrt-merlin,
для энтузиасткой прошивки последние две строчки будут выглядеть так:
iptables -I FORWARD -m set --match-set Microsoft src,dst -j DROP
iptables -I FORWARD -m set --match-set Skype src,dst -j ACCEPT
Готовые скрипты для работы с сохранением настроек и автоматическим применением
этих правил после перезагрузки роутера\переподключения WAN приведены в архиве.
Для его использования необходимо в asuswrrt-merlin разрешить JFFS и выполнить:
сd /jffs
wget -O - http://files.ryzhov-al.ru/Routers/Block%20MS%2C%20enable%20Skype/block_ms_not_skype.tgz | tar -xvz
ryzhov_al
02-02-2015, 12:35
Нашёл одну, на мой взгляд, полезную вещь — ipset-dns (http://git.zx2c4.com/ipset-dns/about/), функционал которой сводится к тому, что утилита наполняет определённый сет теми ip-адресами, которые через неё пытаются резолвить. Утилита работает в паре с dnsmasq и внизу страницы по ссылке приведён отличный сценарий ей использования.
Сценарий относится к тому случаю, когда есть несколько соединений (у меня, скажем, провайдерский интернет и VPN поверх него), и есть несколько ресурсов (например, заблокированных или недоступных в стране), которые можно открыть только через VPN. Для dnsmasq указываем какие адреса надо резолвить через утилиту:
server=/netflix.com/127.0.0.1#39129
утилита собирает отрезолвленные ip'шники в ipset, и на основе этого сета мы направляем обращения к нужным хостам через VPN:
ip route add default via <VPN ip> table <ip-set-name>
У меня вопрос: способна ли прошивочная утилита ip работать с наборами ipset?
Функционал утилиты набрал некую критическую популярность и был включен в современные релизы dnsmasq. Нам, пользующим dnsmasq из прошивок, функционал кажется весьма полезным. Например, когда в прошлом году github на несколько суток попал в реестр блокированных ресурсов, мне пришлось узнавать диапазон адресов, принадлежащих GitHub Inc для того, чтобы направлять трафик к ним через VPN. Здесь же это можно было сделать более изящно, по доменному имени.
ryzhov_al
10-02-2015, 10:15
Коллеги, объясните где искать проблему. Пытаюсь заставить работать пример (http://git.zx2c4.com/ipset-dns/about/) из ipset-dns.
Создаю таблицу роутинга с именем «9»:
admin@RTN66U:/tmp/mnt/OPT/tmp# ip route list table 9
default via 10.8.0.5 dev tun11
где tun11 — сетевой интерфейс установленного соединения OpenVPN:
admin@RTN66U:/tmp/mnt/OPT/tmp# ifconfig tun11
tun11 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.8.0.6 P-t-P:10.8.0.5 Mask:255.255.255.255
...
Указываю, что пакеты с меткой 0х9 надо роутить по таблице с именем «9»:
admin@RTN66U:/tmp/mnt/OPT/tmp# ip rule list
0: from all lookup local
1000: from all fwmark 0x9 lookup 9
32766: from all lookup main
32767: from all lookup default
Пакеты помечаю по src/dst IP, входящих в определённый набор ipset:
admin@RTN66U:/tmp/mnt/OPT/tmp# iptables-save
...
*mangle
:PREROUTING ACCEPT [4570:1578092]
:INPUT ACCEPT [1427:381458]
:FORWARD ACCEPT [2852:1114839]
:OUTPUT ACCEPT [1177:372809]
:POSTROUTING ACCEPT [3993:1487906]
-A PREROUTING -m set --set youtube dst,src -j MARK --set-mark 0x9
COMMIT
...
Но ничего не работает. Беру любой адрес из состава сета:
admin@RTN66U:/tmp/mnt/OPT/tmp# ipset -L youtube
Name: youtube
Type: iphash
References: 1
Header: hashsize: 1024 probes: 8 resize: 50
Members:
173.194.32.165
173.194.32.166
173.194.32.167
...
и проверяю по какому пути будут уходить пакеты:
admin@RTN66U:/tmp/mnt/OPT/tmp# traceroute 173.194.32.165
traceroute to 173.194.32.165 (173.194.32.165), 30 hops max, 38 byte packets
1 5.145.192.1 (5.145.192.1) 0.563 ms 0.356 ms 0.344 ms
2 92-241-96-1.ip4.smoltelecom.ru (92.241.96.1) 0.432 ms 0.362 ms 0.377 ms
...
Как видно, пакеты не уходят в tun11, а убегают в ppp-соединение провайдера согласно основной таблицы роутинга.
Прошивка asuswrt-merlin 378.50, h/w NAT отключен, NF_CONNTRACK_MARK вкомпилен (https://github.com/RMerl/asuswrt-merlin/blob/master/release/src-rt/linux/linux-2.6/config_base#L378) в ядро.
AndreyPopov
10-02-2015, 11:42
а пакеты точно метятся?
tcdump проверяли?
ryzhov_al
10-02-2015, 13:09
а пакеты точно метятся?Кажется, нет. Дело скорее всего в этом. Добавляю правило для логирования пакетов:
admin@RTN66U:/tmp/mnt/OPT/tmp# iptables-save
...
*mangle
:PREROUTING ACCEPT [12283884:12390692819]
:INPUT ACCEPT [1184011:265667218]
:FORWARD ACCEPT [11062414:12109492553]
:OUTPUT ACCEPT [1161724:322878849]
:POSTROUTING ACCEPT [12216353:12431859229]
-A PREROUTING -m set --set youtube dst,src -j MARK --set-mark 0x9
-A PREROUTING -m set --set youtube dst,src -j LOG --log-prefix "MARK check "
COMMIT
...
Но не вижу "MARK=0x9" в syslog'е:
admin@RTN66U:/tmp/home/root# tail /tmp/syslog.log
...
Feb 10 15:54:41 kernel: MARK check <4>MARK check IN=br0 OUT= MAC=c8:60:00:e8:63:d0:94:de:80:b0:2b:88:08:00 <1>SRC=10.9.68.2 DST=173.194.71.93 <1>LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=3576 DF PROTO=TCP <1>SPT=49231 DPT=443 WINDOW=16135 RES=0x00 ACK FIN URGP=0
Feb 10 15:54:41 kernel: MARK check <4>MARK check IN=br0 OUT= MAC=c8:60:00:e8:63:d0:94:de:80:b0:2b:88:08:00 <1>SRC=10.9.68.2 DST=173.194.71.93 <1>LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=3585 DF PROTO=TCP <1>SPT=49231 DPT=443 WINDOW=16135 RES=0x00 ACK URGP=0
Feb 10 15:54:43 kernel: MARK check <4>MARK check IN=br0 OUT= MAC=c8:60:00:e8:63:d0:94:de:80:b0:2b:88:08:00 <1>SRC=10.9.68.2 DST=64.233.162.199 <1>LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=3707 DF PROTO=TCP <1>SPT=49228 DPT=80 WINDOW=16416 RES=0x00 ACK FIN URGP=0
Feb 10 15:54:43 kernel: MARK check <4>MARK check IN=br0 OUT= MAC=c8:60:00:e8:63:d0:94:de:80:b0:2b:88:08:00 <1>SRC=10.9.68.2 DST=64.233.162.199 <1>LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=3708 DF PROTO=TCP <1>SPT=49227 DPT=80 WINDOW=16416 RES=0x00 ACK FIN URGP=0
Вижу (https://github.com/RMerl/asuswrt-merlin/blob/50934942b9206eaa95b5fdd2e1075d517b48703c/release/src/router/rc/firewall.c#L4300), что в asuswrt маркировка пакетов используется только на ARM-девайсах с более свежим ядром. Надо мне не полениться и проверить как это работает на прошивки Padavan'а с ядром 3.х. Не получилось бы в итоге так, что RT-N14U будет служить роутером, а RT-N66U тупой точкой доступа:)
tcdump проверяли?Проверял: на месте и работает. Чем он в данном случае может помочь?
AndreyPopov
10-02-2015, 15:14
tcpdump'ом просто проверять пакеты метятся или нет - я это имел в виду.
включение в ядро CONNTRACK_MARK может быть необходимым, но недостаточным условием?
в /usr/lib вон есть libiptconnmark.so и libiptCONNMARK.so
кстати для --set-mark как мне кажется нужны не 0х9, а что-то типа 9/9 ?????
формат 0х9 вроде используется для TOS(QOS)?
по крайней мере когда я последний раз эксперимертировал с маркированием пакетов, то они у меня маркировались так:
iptables -t mangle -A OUTPUT -j MARK --set-mark 6/6
iptables -t mangle -A INPUT -j MARK --set-mark 6/6
iptables -t mangle -A PREROUTING -j MARK --set-mark 6/6
iptables -t mangle -A POSTROUTING -j MARK --set-mark 6/6
iptables -t mangle -A FORWARD -j MARK --set-mark 6/6
ryzhov_al
10-02-2015, 15:32
tcpdump'ом просто проверять пакеты метятся или нет - я это имел в виду.fwmarks действуют в пределах ядра и ничего в пакет не добавляют. Поэтому искать tcpdump'ом fwmarks бесполезно.
кстати для --set-mark как мне кажется нужны не 0х9, а что-то типа 9/9 ?????
формат 0х9 вроде используется для TOS(QOS)?Вы путаете Firewall marks (http://www.austintek.com/LVS/LVS-HOWTO/HOWTO/LVS-HOWTO.fwmark.html) и поле ToS.
AndreyPopov
10-02-2015, 15:40
может и путаю, давно с этим разбирался.
но вопрос тут не в этом, а в том, что синтаксис маркировки пакетов по --set-mark это просто целые числа, а для TOS используются битовые поля.