DukeNukem3D Posted March 24, 2008 Posted March 24, 2008 Итак ситуация: сеть, на 4000 абонентов примерно, планируется вводить безлимитку. Технология ethernet, во внешку выходят через PPPoE. Нужно подрезать пропускную способность. Гуглил неделю - все манулы какие-то мутные, так и не определился что лучше. Объясните доступно чем shaper отличается от shaperd, или может вообще что-то другое использовать? например вот это http://roback.cc/howtos/bandwidth.php Строится всё на debian linux Еще один вопрос меня мучает - как грамотно ограничить число TCP сессий для определенного IP используя iptables? Заранее благодарен. Вставить ник Quote
c4n Posted March 24, 2008 Posted March 24, 2008 Хороший блин вопрос. Тоже долго копал по шейперам в linux. У меня юзеры по pptp цепляются. В ppp-up.local прописал правила с case выбором по ip, прописанному в билинге. Правда только на входящий трафик от сервера к юзеру работает. На исходящий в инет интерфейс сервака повесил правила с приоритетами на разные виды трафа. Работает вроде нормально. На freebsd пайпами можно шейпать входящий и исходящий. Но руки все никак не доходят. По iptables тоже интересно, самому хотелось бы знать как ограничить число сессий. Вставить ник Quote
disappointed Posted March 24, 2008 Posted March 24, 2008 (edited) >Строится всё на debian linux У нас шейпится на etch. Работает отлично. Всё вешается на интерфейсы скриптом из ip-up.d. Выбирает из БД скорость и ставит через tc qdisc шейп. На исходящую в инет ставлю полисинг дроп. Пример нужен? Edited March 24, 2008 by disappointed Вставить ник Quote
Nickuz Posted March 24, 2008 Posted March 24, 2008 Пример нужен? Если не сложно :-) Вставить ник Quote
disappointed Posted March 24, 2008 Posted March 24, 2008 #!/usr/bin/perl use DBI; require("/usr/local/dt_billing/bin/dbaccess.pm"); my $framed_ip = $ENV{'PPP_REMOTE'}; my $iface = $ENV{'PPP_IFACE'}; my $sql = $dbh->prepare("SELECT speed_rate, login FROM inet_dynamic_ip_services WHERE framed_ip = '$framed_ip'"); $sql->execute; my @res = $sql->fetchrow_array; my $speed_rate = $res[0]; my $speed_rate_up = $res[0]; my $burst = $speed_rate; my $burst_up = $speed_rate_up; my $login = $res[1]; if (($speed_rate == "0") or ($speed_rate == "")) { exit(1); } system ("/sbin/tc qdisc del dev ".$iface." root"); system ("/sbin/tc qdisc add dev ".$iface." root tbf rate ".$speed_rate."kbit latency 100ms burst ".$burst."kbit"); system ("/sbin/tc qdisc del dev ".$iface." handle ffff: ingress"); system ("/sbin/tc qdisc add dev ".$iface." handle ffff: ingress"); system ("/sbin/tc filter add dev ".$iface." parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate ".$speed_rate_up."kbit burst ".$burst_up."kbit drop flowid :1"); Примерно так. Вставить ник Quote
AlKov Posted March 24, 2008 Posted March 24, 2008 ....skip..Примерно так. А приоритеты по типам трафика не пытались сделать? Например, на веб-серфинг - макс., закачки "подрезать" и т.п..Если есть такое, то было бы очень интересно взглянуть на примерчик реализации. Вставить ник Quote
c4n Posted March 24, 2008 Posted March 24, 2008 У меня приоритеты только на исходящем интерфейсе. Первый класс для linage чтоб не лагало ). Потом все остальное. DEV_OUT=$INTERFACE IP=$3 QLEN_OUT=10 RATE_OUT=450 MTU_OUT=1400 TCP="match ip protocol 6 0xff" UDP="match ip protocol 17 0xff" DPORT="match ip dport" SPORT="match ip sport" SRC="match ip src" DST="match ip dst" U32="protocol ip u32" ip link set dev $DEV_OUT qlen $QLEN_OUT mtu $MTU_OUT tc qdisc add dev $DEV_OUT root handle 1: htb default 13 tc class add dev $DEV_OUT parent 1: classid 1:1 htb rate ${RATE_OUT}kbit tc class add dev $DEV_OUT parent 1:1 classid 1:10 htb rate $[RATE_OUT/4]kbit ceil 128kbit prio 0 tc class add dev $DEV_OUT parent 1:1 classid 1:11 htb rate $[RATE_OUT/4]kbit ceil 100kbit prio 1 tc class add dev $DEV_OUT parent 1:1 classid 1:13 htb rate 48kbit prio 3 #-----------FILTERS--------------- tc filter add dev $DEV_OUT parent 1:0 prio 0 $U32 $TCP $DPORT 7777 0xffff classid 1:10 tc filter add dev $DEV_OUT parent 1:0 prio 0 $U32 $TCP $DPORT 2106 0xffff classid 1:10 tc filter add dev $DEV_OUT parent 1:0 prio 0 $U32 $UDP $DPORT 7777 0xffff classid 1:10 tc filter add dev $DEV_OUT parent 1:0 prio 0 $U32 $UDP $DPORT 2106 0xffff classid 1:10 tc filter add dev $DEV_OUT parent 1:0 prio 1 $U32 $DPORT 53 0xffff classid 1:11 tc filter add dev $DEV_OUT parent 1:0 prio 1 $U32 $TCP $DPORT 80 0xffff classid 1:11 tc filter add dev $DEV_OUT parent 1:0 prio 1 $U32 $TCP $DPORT 443 0xffff classid 1:11 tc filter add dev $DEV_OUT parent 1:0 prio 1 $U32 $TCP $DPORT 3128 0xffff classid 1:11 tc filter add dev $DEV_OUT parent 1:0 prio 1 $U32 $TCP $DPORT 21 0xffff classid 1:11 tc qdisc add dev $DEV_OUT parent 1:10 handle 10: sfq perturb 10 tc qdisc add dev $DEV_OUT parent 1:11 handle 11: sfq perturb 10 tc qdisc add dev $DEV_OUT parent 1:13 handle 13: sfq perturb 10 Вставить ник Quote
rsst Posted March 24, 2008 Posted March 24, 2008 (edited) А кто и как решает проблему приоритезации пользователей подключающихся по VPN (PPTP)? Т.е. например пометровщикам высший приоритет, безлимитчикам пониже и т.п.? Скажу сразу, я эту проблему решил, но интересно как поступают другие? Применительно к Linux... Edited March 24, 2008 by rsst Вставить ник Quote
DukeNukem3D Posted March 25, 2008 Author Posted March 25, 2008 (edited) Отлично! Методом логических пертрубаций усвоил одно - придется повозиться с tc ручками, а уж потом нафигачить скрипт, который будет эту беду автоматизировать. Синтезировав полученную здесь и в гугле информацию делаю следующее: Удаляю все интерфейсы ранее созданные, определяю корневой класс: tc qdisc del dev eth0 root tc qdisc add dev eth0 root handle 1 cbq bandwidth 100Mbit avpkt 1000 cell 8 tc class change dev eth0 root cbq weight 10Mbit allot 1514 Создаю класс для определенного клиента: tc class add dev eth0 parent 1: classid 1:10 cbq bandwidth 100Mbit rate 128Kbit weight 12Kbit prio 8 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded tc qdisc add dev eth0 parent 1:10 handle 10 tbf rate 128Kbit buffer 10Kb/8 limit 15Kb mtu 1500 tc filter add dev eth0 parent 1:0 protocol ip prio 100 u32 match ip dst 10.10.80.24 classid 1:10 И еще для одного в целях эксперимента tc class add dev eth0 parent 1: classid 1:11 cbq bandwidth 100Mbit rate 128Kbit weight 12Kbit prio 8 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded tc qdisc add dev eth0 parent 1:11 handle 11 tbf rate 128Kbit buffer 10Kb/8 limit 15Kb mtu 1500 /tc filter add dev eth0 parent 1:0 protocol ip prio 100 u32 match ip dst 10.10.80.22 classid 1:11 Всё работает просто великолепно, скорость шейпится, но как всегда в *nix есть какое-то "но". В данном случае заключается оно в следующем: Смотрим что там у нас с tc творится: # tc class show dev eth0 class cbq 1:11 parent 1: leaf 11: rate 128000bit (bounded) prio no-transmit class cbq 1: root rate 100000Kbit (bounded,isolated) prio no-transmit class cbq 1:10 parent 1: leaf 10: rate 128000bit (bounded) prio no-transmit class tbf 10:1 parent 10: class tbf 11:1 parent 11: # tc qdisc show dev eth0 qdisc cbq 1: root rate 100000Kbit (bounded,isolated) prio no-transmit qdisc tbf 10: parent 1:10 rate 128000bit burst 10Kb lat 320.0ms qdisc tbf 11: parent 1:11 rate 128000bit burst 10Kb lat 320.0ms # tc filter show dev eth0 filter parent 1: protocol ip pref 100 u32 filter parent 1: protocol ip pref 100 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 100 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:10 match 0a0a5018/ffffffff at 16 filter parent 1: protocol ip pref 100 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:11 match 0a0a5016/ffffffff at 16 Теперь вопрос - как бы теперь по-грамотному убрать всё то, что относится к определенному клиенту, допустим к 10.10.80.24 (flowid 1:10) и в какой последовательности? Если думать логически то сначала надо почистить filter, затем qdisc и, в последнюю очередь class. Я попробовал пойти таким путем, предварительно почитав ман как обычно, но оно меня ругает и посылает: # tc filter replace dev eth0 flowid 1:11 Unknown filter "flowid", hence option "1:11" is unparsable Пробовал и так и сяк, кучу аргументов прописывал - ругает и посылает в /dev/ass.. disappointed, проанализировав твой скрипт делаю вывод - ты удаляешь вообще интерфейс который основной так system ("/sbin/tc qdisc del dev ".$iface." root"); а затем создаешь по новой и определяешь классы с нуля. А нельзя ли рулить отдельными дочерними классами? Судя по ману по tc можно, но до меня не доходит в каком порядке выстроить аргументы, чтобы tc их скушало. Или я принципиально неправильно пытаюсь удалить дочерние классы, начиная с фильтра? Вот такова затыка. И о птичках: Ограничил число сессий так: iptables -I FORWARD -p tcp --syn -j DROP -m connlimit --connlimit-above 1 -s 10.10.80.24 В итоге бедный сосед кроме как в аську нигде толком посидеть и не смог :) вобщем результат достигнут. Edited March 25, 2008 by DukeNukem3D Вставить ник Quote
DukeNukem3D Posted March 25, 2008 Author Posted March 25, 2008 (edited) А вот получилось qdisc удалить tc qdisc del dev eth0 parent 1:10 однако class и filter остались и удалить их не получается class делаю так: tc class del dev eth0 classid 1:10 RTNETLINK answers: Device or resource busy фигли ему надо то от меня )) Edited March 25, 2008 by DukeNukem3D Вставить ник Quote
disappointed Posted March 29, 2008 Posted March 29, 2008 > А нельзя ли рулить отдельными дочерними классами? Судя по ману по tc можно. Я же вешаю tc qdisc на ppp+. И каждый ppp это отдельный интерфейс. tc может только в пределах _одного_ интерфейса классифицировать. Просто ставлю тбф и всё. Отлично шейпит исходящий к абоненту. Входящий от абона на ппп просто полисится дропом. Приоритезацию делаю примерно как выше указано. Зворачиваю весь входящий трафик из интернета на ifb девайс и на нём всё рулю. Нужно ещё процентов 5 аплинка оставлять на бурст, не менее, иначе у меня трафик выбегает иногда до дропа у аплинкера. Недопустимо. Начинается замирание tcp сессий у абонов. Лучше пожертвовать запасом. Подрезаются качки скриптом, раз в полчаса выбирающим по подписчикам обьёмы из базы горячей детальки за последние два часа. Если не уложился в n% от тарифного максимально возможного обьёма за это время, то пропорционально снижаю скорость на лету через tc. Я ещё коэф. коррекции ввёл. Подстаривал порог сработки чтобы дифференцировать качков как можно точнее. Ещё инкрементируется счётчик попаданий под такой "алгоритм", пока не заюзал но думается его использовать для более точного выявления качков, и более сильного и быстрого их зарезания. Всё что написал близко к сердцу не принимайте. Просто нам на малых обьёмах нереально по-другому коф. мультиплексирования полосы удержать. Либо качество пострадает либо мы в нуле будем. Вставить ник Quote
DukeNukem3D Posted March 31, 2008 Author Posted March 31, 2008 Видишь ли терминальные устройства удалены от серверов, которые наши ррр интерфейсы организуют, а шэйпить нам надо основываясь на внешних IP адресах. Ну ладно это уже наши внутренние проблемы, принципиально всё понятно. Всем большое спасибо! Вставить ник Quote
DukeNukem3D Posted March 31, 2008 Author Posted March 31, 2008 Мне пришла в голову мысля вот какая: Пометим пакеты (входящий и исходящий): #iptables -t mangle -A FORWARD -s <abon_ip> -j MARK --set-mark 1 #iptables -t mangle -A FORWARD -s ! <abon_ip> -d <abon_ip> -j MARK --set-mark 1 Определим шейпер - девайсы, классы, очереди: (это нужно сделать как для входящего так и исходящего интерфейсов) #tc qdisc add dev eth0 root handle 1: cbq bandwidth 100Mbit avpkt 1000 cell 8 #tc class change dev eth0 root cbq weight 10Mbit allot 1514 #tc class add dev eth0 parent 1: classid 1:1 cbq bandwidth 100Mbit rate 64Kbit weight 6Kbit prio 8 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded #tc qdisc add dev eth0 parent 1:1 handle 1 tbf rate 64Kbit buffer 1Kb/8 limit 15Kb mtu 1500 То есть tc будет теперь реагировать на mark пакета, а марк пакету ставит iptable Вот пожалуй куда проще марк брать из базы с пользователями и пихать его в айпитабло скриптом, чем в колбаску из команд tc - кроме того и не надо пересоздавать ничего. Вставить ник Quote
DukeNukem3D Posted April 7, 2008 Author Posted April 7, 2008 Подумали посидели тут и решили что можно еще проще! Сначала удалим весь мусор: andreyv:/usr/local/sbin# unlimit.sh #!/bin/bash # tc qdisc del dev eth0 root # tc qdisc add dev eth0 root handle 10: cbq bandwidth 100Mbit avpkt 1000 mpu 64 tc class change dev eth0 root cbq weight 10Mbit allot 1514 # А ща автоматизируем на каждого клиента: andreyv:/usr/local/sbin# unlimit_handle.sh #!/bin/bash # handle=$1 ip=$2 # tc class add dev eth0 parent 10: classid 10:$handle cbq bandwidth 100Mbit rate 128Kbit weight 12Kbit prio 8 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded tc qdisc add dev eth0 parent 10:$handle handle $handle tbf rate 128Kbit buffer 10Kb/8 limit 15Kb mtu 1500 tc filter add dev eth0 parent 10:0 protocol ip prio 100 u32 match ip dst $ip classid 10:$handle PS: мне кажется должно быть максимально понятно и просто, без лишних прослоек так сказать. Тестил - работает вполне прилично. Ваши замечания может? Вставить ник Quote
DukeNukem3D Posted April 7, 2008 Author Posted April 7, 2008 А вот вариант если хотим на основании mangle из iptables. andreyv:/home/duke# cat /usr/local/sbin/unlimit_handle.sh #!/bin/bash # handle=$1 # iptables -t mangle -A FORWARD -s $ip -j MARK --set-mark $handle iptables -t mangle -A FORWARD -s ! $ip -d $ip -j MARK --set-mark $handle tc class add dev eth0 parent 10: classid 10:$handle cbq bandwidth 100Mbit rate 128Kbit weight 12Kbit prio 8 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded tc qdisc add dev eth0 parent 10:$handle handle $handle tbf rate 128Kbit buffer 10Kb/8 limit 15Kb mtu 1500 tc filter add dev eth0 parent 10:0 protocol ip handle $handle fw flowid 10:$handle Вот сейчас вроде тема боле-мене обсосана. Вставить ник Quote
alex_iksi Posted April 9, 2008 Posted April 9, 2008 Есть решение промушленного уровня, которое позволяет все это делать - ограничивать скорость пользователям unlim, понижать приоритеты P2P и др, вплоть до невозможного использования, повышать приоритеты других приложений (Skype, sipnet), если это нужно и т.д. Решение дорогое, но окупается за счет простоты администрирования и поддержки (не надо постоянно изобретать велосипед) и нанимать высококвалифицированный персонал. Если интересно, обращайтесь. AMikheev@tehnomarket.ru +7 (905) 516-17-74 Алексей Вставить ник Quote
AlKov Posted April 10, 2008 Posted April 10, 2008 А кто и как решает проблему приоритезации пользователей подключающихся по VPN (PPTP)? Т.е. например пометровщикам высший приоритет, безлимитчикам пониже и т.п.?Скажу сразу, я эту проблему решил, но интересно как поступают другие? Применительно к Linux... А можно взглянуть на Ваше решение? Очень интересует, т.к. именно так и работаю VPN (PPTP), а вот задачу с приоритетами так и не решил.. :( Вставить ник Quote
SokolovS Posted March 19, 2010 Posted March 19, 2010 Задачу с приоритетами можно решить только если шейпить eth0 в целом, а не конректный ppp интерфейс. Вставить ник Quote
sfstudio Posted March 21, 2010 Posted March 21, 2010 Задачу с приоритетами можно решить только если шейпить eth0 в целом, а не конректный ppp интерфейс. use ifb/imq и не нать(от слова надо, а не НАТ) ничего на ethX или ppp городить, для того они и созданы. Вставить ник Quote
NewUse Posted December 11, 2010 Posted December 11, 2010 Уважаемые гуру, сорри за подъём старой темы, но вопрос похожий, а ответа пока не нашёл:( Есть точка доступа под управлением AirOS V, на ней был обнаружен tc :) Возможно, QoS в ядре не полная... Но htb есть точно :) SFQ и r2q тоже похоже имеется :) Можно ли и если можно то как, задавать правила (классы), для группы ip-адрессов: например, если нужно для каждого из подключившихся из подсети 10.10.0.0/24 выделить равные полосы по от 64кБит/с и до 1Мбит/с макс (в зависимости от загруженности канала, допустим в 100Мбит/с ), для одного ip в случае шейпинга это выглядело бы как-то так: TC=/sbin/tc $TC qdisc add dev eth1 root handle 1: htb default 10 $TC class add dev eth1 parent 1: classid 1:1 htb rate 10mbit ceil 10mbit burst 15k $TC class add dev eth1 parent 1:1 classid 1:10 htb rate 64kbit ceil 1mbit burst 15k $TC qdisc add dev eth1 parent 1:10 sfq perturb 10 $TC filter add dev eth1 protocol ip parent 1:0 prio 1 u32 match ip src 10.10.0.1 flowid 1:10 А как сделать для всех подключившихся IP? И что использовать в случае policing вместо shaping? В случае пайпов, было бы легко, а как быть в tc? PS: Манов в интернете полно, но всё сводится либо к тупому скрипту, создающему правила для каждого ip из подсети (в независимости, подключён он или нет) либо к попыткам разделить весь трафик по классам (что в данной задаче не требуется) PPS: Трафик ограничивается в целях спасения сети, построенной по очень неудачной схеме(WDS+AP с несколькими хопами), в связи с отсутствием финансов Вставить ник Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.