от Vladsun(24-10-2006)

рейтинг (12)   [ добре ]  [ зле ]

Printer Friendly Вариант за отпечатване

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 идентификация >>