LINUX-BG   Адрес : http://www.linux-bg.org
Използване на IPSET, IPTABLES и IPMARK
От: Vladsun
Публикувана на: 24-10-2006
Адрес на статията: http://www.linux-bg.org/cgi-bin/y/index.pl?page=article&id=advices&key=386924398
1. Увод

Статията има за цел да популяризира използване на мощния инструмент за филтриране в iptables - ipset. Благодаря на Наско (atanas __точка__ tsonkov (a) gmail __точка__ com) за насоката, която ми даде в една моя предишна статия.
Обяснения по отношение на IPMARK и съответнияt начин на ползването му съвместно с tc можете да намерите в Оптимизация на iptables и tc правила.
Повече информация за възможностите на ipset можете да намерите в http://ipset.netfilter.org или "man ipset".
Предимството при ползване на ipset, съвместно с iptables, се изразява в повишената производителност при едни и същи системни ресурси. Това се дължи на факта, че ipset използва хеширане за да определи дали даден адрес (src/dst) на конкретен пакет се намира в определено множество или не. При iptables това става с линейно търсене, което е много неефективно.
Предимствата при използване на ipmark, съвместно с tc, са разгледани в гореспоменатата статия.

2. Инсталация

Следвайте инструкциите дадени в http://ipset.netfilter.org/install.html и традиционното пачване с PoM - ./runme IPMARK. При мен след няколко опита всичко (iptables, ipset и ipmark) мина добре с ядро 2.6.15.7. След успешния опит не съм правил проверка, дали с други, по-нови ядра компилацията минава добре.

3. Приложение

3.1. Разделяне/маркиране на международен и български трафик

В скриптове използвани с тази цел, които съм виждал, не се използва IPSET (освен в примерите на Наско). Веднага давам пример как да стане това:
Примерен код
 # Init iptables
 # eth0 - external interface
 # eth1 - internal interface
 
 iptаbles -F -t filter
 iptаbles -F -t nat
 iptаbles -F -t mangle
 iptаbles -F -t raw
 
 iptаbles -X -t filter
 iptаbles -X -t nat
 iptаbles -X -t mangle
 iptаbles -X -t raw
 
 iptаbles -Z -t filter
 iptаbles -Z -t nat
 iptаbles -Z -t mangle
 iptаbles -Z -t raw
 
 # Init ipset
 ipset -F
 ipset -X
 
 #Set default policy for chain FORWARD to DROP
 iptаbles -P FORWARD DROP
 
 #Create empty user defined chains
 iptаbles -N TRAF_IN -t mangle
 iptаbles -N TRAF_OUT -t mangle
 
 iptаbles -N BG_IN -t mangle
 iptаbles -N BG_OUT -t mangle
 
 iptаbles -N INT_OUT -t mangle
 iptаbles -N INT_IN -t mangle
 
 # Mark all packets MARK 1
 iptаbles -A FORWARD -t mangle -j MARK --set-mark 1
 
 iptаbles -t mangle -A FORWARD -i eth1 -o eth0 -j TRAF_OUT
 iptаbles -t mangle -A FORWARD -i eth0 -o eth1 -j TRAF_IN
 # Local traffic is considered BG
 iptаbles -t mangle -A FORWARD -i eth1 -o eth1 -j BG_IN
 iptаbles -t mangle -A FORWARD -i eth1 -o eth1 -j BG_OUT
 
 
 ipsеt -N BG_NETS nethash
 for i in `cat /etc/bgnets`; do
 ipsеt -A BG_NETS $i
 done
Първо инициализирахме iptables таблиците и ipset списъците. След това създадохме вериги за входящ/изходящ трафик, съответно международен/български трафик.
Създадохме адресен списък на префиксите на мрежите в българското Интернет пространство.
Следващата стъпка е да маркираме трафика на всеки отделен потребител. Нека имаме случай с една С-клас мрежа:
Примерен код
$ipt="iptables"
 $ips="ips"
 
 #####################################################################################################################
 #       BG Traffic
 #####################################################################################################################
 
 $ipt -t mangle -A TRAF_IN -m set --set BG_NETS src -j BG_IN
 $ipt -t mangle -A TRAF_OUT -m set --set BG_NETS dst -j BG_OUT
 
 $ipt -A BG_IN -t mangle -d 90.0.0.0/24 -j IPMARK --addr=dst --and-mask=0xff --or-mask=0x10100
 $ipt -A BG_OUT -t mangle -s 90.0.0.0/24 -j IPMARK --addr=src --and-mask=0xff --or-mask=0x10200
 
 # Global BG traffic
 $ipt -A BG_OUT -t mangle -j RETURN
 $ipt -A BG_IN -t mangle -j RETURN
 
 #####################################################################################################################
 #       International Traffic
 #####################################################################################################################
 
 $ipt -A TRAF_IN -t mangle -m mark --mark 1 -j INT_IN
 $ipt -A TRAF_OUT -t mangle -m mark --mark 1 -j INT_OUT
 
 $ipt -A INT_IN -t mangle -d 90.0.0.0/24 -j IPMARK --addr=dst --and-mask=0xff --or-mask=0x10300
 $ipt -A INT_OUT -t mangle -s 90.0.0.0/24 -j IPMARK --addr=src --and-mask=0xff --or-mask=0x10400
 
 # Global INT traffic
 $ipt -A INT_OUT -t mangle -j RETURN
 $ipt -A INT_IN -t mangle -j RETURN
С това всичките необходими действия за маркиране на upload/download, български/международен трафик за всако отделно ИП от една С-клас мрежа. С необходимите филтри и класове в tc (както е описано в дадената по-горе статия) цялата система за ограничаване на трафика е завършена.

3.2. Контрол върху Интернет достъпа

В тази част ще разгледаме как да контролираме Интернет достъпа на всеки потребител. Отново ще използваме ipset:
Примерен код
#####################################################################################################################
 #        FORWARD Chain
 #####################################################################################################################
 # Accept packets between local nets
 $ipt -A FORWARD -i eth1 -o eth1 -j ACCEPT
 
 $ips -N FW_90_0_0_0 ipmap --network 90.0.0.0/24
 
 $ipt -A FORWARD -m set --set FW_90_0_0_0 src -j ACCEPT
 $ipt -A FORWARD -m set --set FW_90_0_0_0 dst -j ACCEPT
Създадохме адресен списък, който за момента е празен и достъпът до Интернет на всички ИП-та от тази мрежа е забранен.
Разрешаването на достъпа до Интернет за ИП от тази мрежа става чрез една единствена команда:
Примерен код
$ips -А FW_90_0_0_0 90.0.0.XXX
Един "трик" използван от много Интернет доставчици е да пренасочват порт 80 към техен Web сървер за да покажат тяхна страница на потребителя приканващ го към подновяване на абонамента. Това пак става изключително лесно с използването на IPSET:
Примерен код
### Always allow our servers ###
 $ips -N PRE_ACCEPT iphash
 $ips -A PRE_ACCEPT 90.0.0.1 ### ISP's WWW server
 
 $ipt -t nat -A PREROUTING -i eth1 -m set --set PRE_ACCEPT dst -j ACCEPT
 
 $ips -N PRE_90_0_0_0 ipmap --network 90.0.0.0/24
 
 $ipt -t nat -N WARNPAGE
 $ipt -t nat -A WARNPAGE -p tcp --dport 80 -j DNAT --to 90.0.0.1:80
 $ipt -t nat -A WARNPAGE -j DROP
 
 ### Account check ###
 $ipt -t nat -A PREROUTING -i eth1 -m set --set PRE_90_0_0_0 src -j WARNPAGE
Този път действието за "разрешаване" на ИП е обратно - трябва да го няма в списъка PRE_90_0_0_0. За забрана използваме:
Примерен код
$ips -А PRE_90_0_0_0 90.90.0.ХХХ


3.3. MAC/IP филтриране

IPSET позволява създаване на списък от IP/MAC чифтове. По този начин можем да контролираме (в известна степен) коректното използване на Интернет достъпа от всеки потребител. В примера отново е използвано пренасочване на трафика за порт 80 към дефинирана от вас страница.
Примерен код
#####################################################################################################################
 #        PREROUTING Chain
 #####################################################################################################################
 
 $ips -N MACS_90_0_0_0 macipmap --network 90.0.0.0/24
 
 ### MAC/IP check ###
 $ipt -t nat -N MACIPS
 
 $ipt -t nat -A PREROUTING -i eth1 -s 90.0.0.0/24 -j MACIPS
 
 $ipt -t nat -A MACIPS -i eth1 -m set --set MACS_90_0_0_0 src -j RETURN
 
 $ipt -t nat -A MACIPS -m limit --limit 1/m --limit-burst 2 -j LOG --log-level info --log-prefix ' ### MAC-IP ### '
 $ipt -t nat -A MACIPS -j WARNPAGE

Във файла /var/log/messages ще намерите съобщенията за несъответстващите IP/MAC чифтовете. Добавяне на MAC/IP чифт става по следния начин:
Примерен код
$ips -A MACS_90_0_0_0 90.0.0.IP%MAC

В статията не са разгледани възможностите на IPSET за създаване на адресни списъци свързани със списъци на портове. Това оставям на вас :P.


<< Домашната безжична мрежа и ADSL на БТК | Достъп до уеб ресурси чрез Х.509 идентификация >>

Авторите на сайта, както и техните сътрудници запазват авторските права върху собствените си материали публикувани тук, но те са copyleft т.е. могат свободно да бъдат копирани и разпространявани с изискването изрично да се упоменава името на автора, както и да се публикува на видно място, че те са взети от оригиналния им URL-адрес на този сървър (http://www.linux-bg.org). Авторските права на преводните материали принадлежат на техните автори. Ако с публикуването тук на някакъв материал неволно са нарушени нечии права - след констатирането на този факт материалът ще бъде свален.

All trademarks, logos and copyrights mentioned on this site are the property of their respective owners.
Linux is copyright by Linus Torvalds.
© Линукс за българи ЕООД 2007
© Slavei Karadjov 1999 - 2006

All rights reserved.

Изпълнението отне: 1 wallclock secs ( 0.18 usr + 0.01 sys = 0.19 CPU)