Настройка на LinkSys приоритета голосового трафика с помощью утилиты tc c ограничением исходящего трафика с помощью iptablesИсходные данные: в качестве роутеров удаленных подразделений используются LinkSYSы WRT54GL, имеющие подключение на wan-порту к сети провайдера и в конечном итоге через технологическую сеть провайдера к cisco центрального офиса компании. На wan-порту (интерфейс vlan1) поднят GRE-тоннель чтобы обеспечить нахождение удаленных подразделений в единой корпоративной сети компании и возможности маршрутизирования и управления трафиком самостоятельно без вмешательства провайдера.
Внутренняя сеть удаленного подразделения поднята на интерфейсе br0, хотя может быть поднята и на vlan0, объединяющим 4 порта RJ45. Особого значения это не имеет.
Задача: выделить голосовой трафик в приоритетный класс, чтобы обеспечить стабильность голосовой связи независимо от нагруженности каналов и ограничить трафик из удаленных подразделений в центральный оффис, так как в случае вспышек "грипа" они забивают пакетами офисную cisco 2821
Первоначально планировал установить правила фильтрации на внешнем интерфейсе роутера, то есть на wan-порту, что само по себе является более логичным. Однако такая схема оказалась неработоспособной. Возможно вследствие того, что GRE-инкапсуляция пакетов осуществляется прежде их классификации и маркировки утилитой tc. Привязка фильтрации к интерфейсу br0 в полной мере обеспечила достижение поставленной задачи, поэтому дальше разбираться с фильтрацией на wan-порту не стал.
1. Для осуществления фильтрации трафика на LinkSYS-ах, работающих под управлением прошивки OpenWRT rc5, скачиваем с http://downloads.openwrt.org/whiterussian/rc5/packages/ и устанавливаем пакеты:
tc_2.6.11-050330-1_mipsel.ipk
kmod-sched_2.4.30-brcm-3_mipsel.ipk
root@OpenWrt:~# wget http://192.168.1.2/Packages5/tc.ipk
Connecting to 192.168.1.2[192.168.1.2]:80
tc.ipk 100% |*****************************| 66468 00:00 ETA
root@OpenWrt:~# wget http://192.168.1.2/Packages5/kmod_sched.ipk
Connecting to 192.168.1.2[192.168.1.2]:80
kmod_sched.ipk 100% |*****************************| 74664 00:00 ETA
root@OpenWrt:~# ipkg install kmod_sched.ipk
Installing kmod-sched (2.4.30-brcm-3) to root...
Configuring kmod-sched
Successfully terminated.
root@OpenWrt:~# ipkg install tc.ipk
Installing tc (2.6.11-050330-1) to root...
Configuring tc
Successfully terminated.
root@OpenWrt:~#
2. Подключаем модули, необходимые для работы утилиты tc
root@OpenWrt:/lib/modules/2.4.30# ls
cls_fw.o ip_gre.o sch_dsmark.o sch_sfq.o tun.o
cls_route.o ppp_async.o sch_gred.o sch_tbf.o wl.o
cls_rsvp.o ppp_generic.o sch_hfsc.o sch_teql.o wlcompat.o
cls_rsvp6.o pppoe.o sch_htb.o slhc.o
cls_tcindex.o pppox.o sch_ingress.o switch-adm.o
cls_u32.o sch_cbq.o sch_prio.o switch-core.o
diag.o sch_csz.o sch_red.o switch-robo.o
root@OpenWrt:~#
root@OpenWrt:/lib/modules/2.4.30# insmod cls_u32
Using /lib/modules/2.4.30/cls_u32.o
root@OpenWrt:/lib/modules/2.4.30# insmod cls_route
Using /lib/modules/2.4.30/cls_route.o
root@OpenWrt:~# insmod sch_sfq
Using /lib/modules/2.4.30/sch_sfq.o
root@OpenWrt:/lib/modules/2.4.30# insmod sch_htb
Using /lib/modules/2.4.30/sch_htb.o
root@OpenWrt:/lib/modules/2.4.30#
3. Пишем скрипт фильтрации пакетов
3.1. Добавляем дисциплину обработки очереди
root@OpenWrt:~# tc qdisc add dev br0 root handle 1: htb default 20
dev vlan1 - Указываем устройство br0, к которому мы подключаем дисциплину обработки очереди.
В данном случае:
root - Указываем, что это корневая дисциплина, то есть для исходящего трафика. В случае входящего необходимо использовать ingress
handle 1:0 - Задаем дескриптор в форме старший номер:младший номер. Младший номер для любой дисциплины обработки очереди должен равняться нулю.
htb - Указываем тип дисциплины обработки очереди, который мы хотим подключить.
Дисциплина HTB (Hierarchical Token Bucket) использует идею токенов. Благодаря классовости, поддержки технологии заема полосы пропускания, HTB позволяет организовывать сложное и тонкое управление трафиком.
Важной составляющей дисциплины HTB является механизм заема полосы пропускания. Подклассы начинают занимать часть полосы пропускания у своих родительских классов, только когда трафик превышает значение, заданное параметром rate.
Выбор дисциплины – дело личное. Не имея глубоких познаний в данной области, htb показалась мне наиболее приемлемой.
3.2. Создаем классы.
root@OpenWrt:~# tc class add dev br0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit burst 32k
root@OpenWrt:~# tc class add dev br0 parent 1:1 classid 1:10 htb rate 32kbit ceil 128kbit burst 16k
root@OpenWrt:~# tc class add dev br0 parent 1:1 classid 1:20 htb rate 96kbit ceil 128kbit burst 16k
root@OpenWrt:~#
dev vlan1 - Указываем устройство, к которому мы подключаем новый класс.
parent 1:1 - Указываем дескриптор родителя, к которому мы подключаем данный класс.
classid 1:1 - Задаем уникальный дескриптор для данного класса. Младший номер должен быть отличным от нуля.
htb - Классовые дисциплины обработки очередей требуют, чтобы все подклассы были одного типа с родителями. Поэтому у дисциплины обработки очереди HTB классы будут тоже HTB.
rate 128kbit, ceil 128bit - параметры класса.
3.2. Распределяем трафик по классам, с помощью tc filter
root@OpenWrt:~# tc filter add dev br0 protocol ip parent 1:0 prio 1 u32 match ip dst 172.116.25.7 flowid 1:10
отправляем весь трафик у которого получатель 172.116.25.7 в класс 1:10.
Здесь:
dev br0 - Указываем устройство, к которому мы подключаем фильтр.
parent 1:1 - Указываем дескриптор родителя, к которому мы подключаем данный фильтр
protocol ip - Задаем протокол, с которым будет работать фильтр. prio 5 - Параметр prio позволяет присвоить классифицированному этим фильтром трафику приоритет.
u32 - Задаем классификатор, в данном случае это u32.
В итоге скрипт фильтрации пакетов будет вглядеть следующим образом:
tc qdisc add dev br0 root handle 1: htb default 20
tc class add dev br0 parent 1: classid 1:1 htb rate 128kbit ceil 128kbit burst 32k
tc class add dev br0 parent 1:1 classid 1:10 htb rate 64kbit ceil 128kbit burst 16k
tc class add dev br0 parent 1:1 classid 1:20 htb rate 64kbit ceil 128kbit burst 16k
tc filter add dev br0 protocol ip parent 1:0 prio 1 u32 match ip dst 172.116.25.167/32 flowid 1:10
Здесь 172.116.25.167 - адрес голосового сервера в центральном офисе.
Таким образом мы поделили канал шириной 128kb пополам. При наличии голосового трафика максимальная ширина полосы для него будет 64kb. При отсутствии трафика класса 10, вся полоса в 128kb будет предоставлена трафику класса 20.
По дальнейшим наблюдениям определил, что пиковая загрузка голосовым трафиком не превышает 31kb. То есть можно было бы отдать голосу 32kb. Но данная величина в каждом конкретном случае, скорее всего, зависит от типа используемых голосовых шлюзов.
4. В целях ограничения исходящего из удаленных подразделений трафика добавляем правила iptables, позволяющие пользователям подразделений ходить только на конкретные сервера и сети:
iptables -A FORWARD -s 10.0.0.0/8 -d 10.51.4.0/24 -j ACCEPT #Разрешаем всем сетям центрального офиса ходить на все хосты удаленного подразделения
iptables -A FORWARD -s 10.51.4.0/24 -d 192.168.116.16/30 -j ACCEPT
iptables -A FORWARD -s 10.51.4.0/24 -d 172.116.25.0/24 -j ACCEPT
iptables -A FORWARD -s 10.51.4.0/24 -d 10.25.50.0/24 -j ACCEPT
iptables -A FORWARD -s 10.51.4.0/24 -d 10.25.60.1/32 -j ACCEPT
iptables -A FORWARD -s 10.51.4.0/24 -d 10.25.21.1/32 -j ACCEPT
iptables -A FORWARD -s 10.51.4.0/24 -d 10.70.9.50/32 -j ACCEPT
iptables -A FORWARD -s 10.51.4.0/24 -d 10.7.7.0/24 -j ACCEPT
iptables -A FORWARD -s 10.51.4.0/24 -j DROP
5. Рисуем скрипты активации правил фильтрации S96tc и S99iptables для каждого подразделения и
закачиваем данные скрипты на LinkSYSы
root@OpenWrt:~# cd /etc/init.d
root@OpenWrt:/etc/init.d# wget http://192.168.1.2/podrazdelenie_XX/S96tc
Connecting to 192.168.1.2 [192.168.1.2]:80
S99tc 100% |*****************************| 1150 00:00 ETA
root@OpenWrt:/etc/init.d# wget http://192.168.1.2/podrazdelenie_XX/S99iptables
Connecting to 192.168.1.2 [192.168.1.2]:80
S99tc 100% |*****************************| 1150 00:00 ETA
root@OpenWrt:/etc/init.d# root@OpenWrt:/etc/init.d# chmod 755 ./S96tc root@OpenWrt:/etc/init.d# chmod 755 ./S99iptables root@OpenWrt:/etc/init.d# nvram commit
6. Загружаем наши сервисы и проверяем фильтрацию трафика в период наличия голосового трафика и работу активных правил iptables
root@OpenWrt:/etc/init.d# ./S96tc
Using /lib/modules/2.4.30/cls_u32.o
Using /lib/modules/2.4.30/sch_htb.o
Using /lib/modules/2.4.30/sch_sfq.o
root@OpenWrt:/etc/init.d# ./S99iptables root@OpenWrt:/etc/init.d#
root@OpenWrt:/etc/init.d# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 10.0.0.0/8 10.51.4.0/24
ACCEPT all -- 10.25.4.0/24 192.168.116.16/30
ACCEPT all -- 10.51.4.0/24 172.116.25.0/24
ACCEPT all -- 10.51.4.0/24 10.25.50.0/24
ACCEPT all -- 10.51.4.0/24 10.25.60.1
ACCEPT all -- 10.51.4.0/24 10.25.21.1
ACCEPT all -- 10.51.4.0/24 10.70.6.50
ACCEPT all -- 10.51.4.0/24 10.7.7.0/24
DROP all -- 10.51.4.0/24 anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
root@OpenWrt:/etc/init.d#
Проверяем активные правила фильтрации и их работу:
root@OpenWrt:/etc/init.d# tc -s class ls dev br0 class htb 1:1 root rate 128000bit ceil 128000bit burst 32Kb cburst 1759b Sent 62305183 bytes 258924 pkts (dropped 0, overlimits 0) rate 19352bit 26pps lended: 7145 borrowed: 0 giants: 0 tokens: 3159493 ctokens: 161649
class htb 1:10 parent 1:1 prio 0 rate 64000bit ceil 128000bit burst 16Kb cburst 1759b Sent 15375316 bytes 195889 pkts (dropped 0, overlimits 0) rate 18792bit 25pps lended: 195889 borrowed: 0 giants: 0 tokens: 3150985 ctokens: 161649
class htb 1:20 parent 1:1 prio 0 rate 64000bit ceil 128000bit burst 16Kb cburst 1759b Sent 46929867 bytes 63035 pkts (dropped 16442, overlimits 0) rate 544bit lended: 55890 borrowed: 7145 giants: 0 tokens: 3139348 ctokens: 156972
root@OpenWrt:/etc/init.d#
7. Готово. Проверяем, анализируем, тестируем.
|