Ключевые слова:ipfw, rate-limit, cisco, linux, freebsd, limit, shaper, bandwidth, (найти похожие документы)
From: <itdep@lanbilling.ru.>
Date: Mon, 22 Aug 2006 14:31:37 +0000 (UTC)
Subject: Способы ограничения полосы пропускания на сетевых устройствах
Оригинал: http://www.lanbilling.ru/shaping_solution.html
Данное руководство по настройке адресовано системным администраторам,
эксплуатирующим АСР LANBilling у которых стоят задачи ограничения
полосы пропускания для абонентов сети передачи данных.
Обратите внимание что ссылки на актуальные скрипты АСР будут добавлены
в течение недели. В данный момент они унифицируются. И могут быть
высланы по дополнительному запросу по e-mail в любой момент.
В АСР LANBilling имеется возможность привязки ограничения пропускной
способности канала как к учетной записи, так и к тарифу абонента.
Установив определенное значение скорости в интерфейсе АСР, вы всего
лишь добавляете новое свойство учетной записи, но это никак не влияет
на фактическую пропускную способность канала пользователя. Дело в том,
что реальная регулировка полосы пропускания (шейпинг, от английского
shaping) возможна только на маршрутизирующих (коммутирующих)
устройствах, через которые проходит трафик. В качестве таких устройств
могут выступать PC-маршрутизаторы, маршрутизаторы cisco, управляемые
коммутаторы (например, HP Procurve) и т.п. К сожалению, универсального
интерфейса взаимодействия с подобными устройствами не существует,
поэтому перед системным администратором встает задача настройки этого
взаимодействия (написание дополнительных модулей, скриптов управления
и т.п.), которое в общем случае определяется спецификой используемого
оборудования, тополигией сети и другими факторами.
В АСР LANBilling предлагаются следующие механизмы взаимодействия с
внешними системами, осуществляющими шейпинг.
1. Средствами внешних скриптов. По определенному событию АСР
запускает внешний скрипт с рядом параметров, относящихся к
конкретной учетной записи. Среди этих параметров имеется значение
полосы пропускания, установленной для пользователя (см. описание
vg-скриптов в документации: разделы "Файл конфигурации
billing.conf","Система контроля доступа"). Этот скрипт должен
осуществлять управление шейпером.
2. При помощи RADIUS-атрибутов. Речь идет об услугах VPN и DialUP,
когда NAS является устройством, осуществляющим шейпинг. В ответе
на запрос аутентификации RADIUS сервер (он же агент АСР
LANBilling) может отсылать атрибут, определенный для данного
абонента, который содержит в себе инструкции по управлению
пропускной способностью устанавливаемого соединения. В данном
случае необходима поддержка этой возможности програмным
обеспечение со стороны NAS'а. Среди устройств, поддерживающих
данный механизм, можно выделить маршрутизаторы Cisco Systems и
коммутаторы HP Procurve.
Примеры управляющих скриптов.
1. Cisco.
Маршрутизаторы Сisco Systems позволяют делать шейпинг как по
входящиму, так и по исходящиму трафику (возможность зависит от версии
IOS).
1.1 Статическая привязка скорости к IP адресу.
!
interface FastEthernet0/0
ip address 192.168.0.1 255.255.255.0
rate-limit output access-group 2055 64000 8000 8000 conform-action transmit exceed-action drop
rate-limit output access-group 2057 128000 16000 16000 conform-action transmit
exceed-action drop
!
access-list 2055 permit ip any host 192.168.0.107
access-list 2055 deny ip any any
access-list 2057 permit ip any host 192.168.0.3
access-list 2057 deny ip any any
!
В данном примере конфигурации маршрутизатора на интерфейсе
FastEthernet0/0 созданы два правила по ограничению исходящего (по
отношению к интерфейсу) трафика. Под эти правила согласно access-list
попадает трафик хоста 192.168.0.107 (ограничение 64Кбит) и
192.168.0.3(ограничение 128Кбит). Автоматизировав редактирование этих
инструкций для каждого пользователя, можно динамически управлять
пропускной способностью из интерфейса АСР. В качестве примера
автоматизации можно рассмотреть следующий скрипт (ссылка). Скрипт
написан на языке perl использует telnet для доступа к маршрутизатору и
нуждается в редактировании параметров доступа в начале скрипта
(cisco_ip, cisco_password, cisco_enable). Этот скрипт принимает в
качестве параметров ip адрес, маску и значение пропускной способности,
и должен вызываться из процедур vg_on/vg_off.
1.2 Динамическая привязка скорости к интерфейсу с помощью RADIUS-атрибутов.
Когда DialUP (VPN) пользователь успешно прошел аутентификацию, на
маршрутизаторе создается новый виртуальный интерфейс. При этом RADIUS
агент (сервер) в ответном пакете может передать ряд VSA атрибутов,
определяющих параметры вновь созданного соединения. В контексте
решения интересует установка значения пропускной способности на этом
интерфейсе.
За установку значения полосы пропускания отвечает следующий атрибут:
Номер атрибута = 26 (VSA),
Номер Vendor'а = 9 (Cisco),
Номер VSA атрибута = 1 (Cisco-AVPair).
Значение атрибута =
lcp:interface-config#1=rate-limit ouput 192000 24000 24000 conform-action transmit exceed-action drop
Тип = строка (string)
В интерфейсе АСР создания/редактирования RADIUS-атрибутов поля должны
быть заполнены следующим образом.
Radius Code = Access-Accept
Атрибут = 26
Значение: строка
#000#000#000#009#001#104lcp:interface-config#1=rate-limit output
192000 24000 24000 conform-action transmit exceed-action drop
#xxx - десятичный код символа (1 байт)
Первые 5 байт определяют номер производителя (Vendor_ID) и номер VSA
атрибута, поэтому для устройства Cisco Systems эта часть меняться не
будет.
6-ой байт (#104) - это длина атрибута. Она вычисляется как длина
передаваемой строки + 2. При изменении значения атрибута нужно
обязательно учесть возможное изменение длины. В даном примере
устанавливается скорость 192kbps на исходящий по отношению к
интерфейсу на cisco трафик, т.е. на входящий трафик для пользователя.
К одной учетной записи можно привязать несколько атрибутов. Все они
будут передаваться на NAS. При этом нужно следить, чтобы атрибуты не
конфликтовали между собой.
2. Linux маршрутизатор.
2.1. Средства ядра ОС
В ОС Linux есть весьма мощное средство управления трафиком - утилита
tc, входящая в пакет iproute2. Вся работа с трафиком, в том числе
реализация QoS, происходит в ядре. Пакет iproute2 по сути представляет
из себя интерфейс взаимодействия с ядром ОС. В интернет можно найти
большое количество статей на эту тему (теперь даже на русском языке).
В двух словах механизм управления полосой пропускания можно описать
следующим образом. На интерфейсе создается очередь пакетов (qdisc).
Очередь обрабатывается в соответсвии с одним из возможных алгоритмов
(PFIFO, CBQ, HTB, TBF, SFQ, RED и т.д.). Существуют бескласcове и
классовые qdisc. Последние допускают создание разветвленной схемы
классов трафика в очереди, что обеспечивает более гибкое управление
трафиком. Пакет может быть отнесен к тому или иному классу в
соответсвии с правилами фильтров.
Следует отметить, что все очереди работают только с исходящим трафиком
(исключение ingress). Мотивировано это тем, что мы в общем случае не
можем влиять на скорость присылаемого нам трафика. На самом деле это
актуально только для трафика самого сервера. Если речь идет о
маршрутизируемом трафике, то это ограничение ничем не мешает, т.к.
весь трафик является исходящим на одном из интерфейсов роутера.
Нас будет интересовать только ограничение полосы пропускания для
конкретного пользователя. Рассмотрим простейший случай: требуется
ограничить скорость на интерфейсе до требуемого значения, скажем
128Кб/с. Такая необходимость может возникнуть при использовании
PoPToP, когда для каждого пользователя создается свой ppp интерфейс.
Здесь имеет смысл ограничивать скорость на всем интерфейсе без
приминения каких-либо фильтров. Для этих целей лучше всего подойдет
бесклассовый qdisc TBF.
#tc qdisc add dev ppp0 root tbf rate 128kbit burst 4kb latency 70ms minburst 1540
Этой командой ограничивается исходящая скорость на интерфейсе ppp0
(т.е. скорость входящего трафика для пользователя).
Использованы следующие параметры:
rate - максимальная скорость потока.
burst - количество байт данных, которые можно поместить в буфер в
единицу времени. Чем выше скорость потока, тем больше должно быть
значение burst. burst не может быть меньше значения MTU (minburst) -
1540 байт для ethernet.
latency - определяет размер буфера по максимальному времени нахождения
пакета в буфере. Можно вместо этого указать размер буфера в байтах
(параметр limit).
2.2. Пример скрипта для PoPToP.
Для установки заданной в АСР скорости потока для пользователя можно
использовать скрипт:
#!/bin/bash
# Wait before starting
sleep 1
# Set variables
DEV=$1
AIP=$5
LOG=/usr/local/billing/shaper.log
# Load config
. /etc/billing.conf
# Set mysql command line
MYSQL="/usr/bin/mysql -h${rdbhost} -u${rdbuser} -p${rdbpass} ${rdbname}"
q=`echo "select vgroups.tar_id,vgroups.shape from vgroups,sessionsradius where \
sessionsradius.assigned_ip=\"$AIP\" and sessionsradius.vg_id=vgroups.vg_id" \
| $MYSQL | tail -n1`
if test -z "$q"; then
echo "`date` $DEV cannot find ${AIP} in active sessions" >> $LOG
exit 0
fi
tarid=`echo "$q" | awk '{print $1}'`
shape=`echo "$q" | awk '{print $2}'`
if test $shape -eq 0 2>/dev/null; then
shape=`echo "select shape from tarifs where tar_id=${tarid}" | $MYSQL | tail -n1`
fi
if ! test $shape -ge 0 2>/dev/null
then
echo "`date` $DEV cannot get proper shape rate for $AIP" >> $LOG
exit 0;
fi
if test $shape -gt 0 2>/dev/null
then
burst=`echo $shape/100+2 | bc 2>/dev/null`
/sbin/tc qdisc add dev $DEV root tbf rate ${shape}kbit burst ${burst}kb latency 70ms minburst 1540 >/dev/null 2>&1
#/sbin/tc qdisc add dev $DEV handle ffff: ingress
#/sbin/tc filter add dev $DEV parent ffff: protocol ip u32 match ip src 0.0.0.0/0 police rate ${shape}kbps burst ${burst}k mtu 12k drop flowid :1
echo "`date` Setting shape rate $shape for $DEV [$AIP]" >> $LOG
fi;
exit 0
Данный скрипт должен быть помещен в /etc/ppp и называться
ip-up.local. Он будет запускаться демоном pppd при каждом новом ppp
соединении. Скрипт использует прямой доступ к БД биллинга, что
идеологически является не совсем верным подходом и не вписывается в
вышеописанные механизмы взаимодействия с внешними системами (в
ближайших сборках АСР в функционал агента RADIUS будет добавлена
возможность запуска внешней процедуры vg_start,сразу после отсылки
Access-Accept пакета).
2.3. Пример использования TC
#tc qdisc add dev eth0 root handle 1: htb
#tc class add dev eth0 parent 1: classid 1:10 htb rate 16kbps burst 2kbps
#tc class add dev eth0 parent 1: classid 1:20 htb rate 32kbps burst 2kbps
#tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.0.10 flowid 1:10
#tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.0.20 flowid 1:20
#tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
#tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
Первой инструкцией на интерфейсе создается htb qdisc. Затем от него
ответвляются 2 класса, для которых резервируется скорость 16 и 32
Кбайт/с. Следующие 2 инструкции - это фильтры, привязывающие трафик,
принадлежащий к данному ip к конкретному классу. Трафик, который не
попадает под правила фильтров, обрабатывается стандартным образом (без
ограничений). Следующие 2 команды не являются обязательными. Они
определяют тип очереди (sfq qdisc) в каждом из двух созданных классов.
По умолчанию всегда используется pfifo очередь, пакеты в которой
обрабатываются по принципу first-in-firts-out.
В sfq алгоритме очередность пакетов определяется случайным образом
так, чтобы обеспечить равномерное распределение полосы между между
различными приложениями (точнее между потоками, определяемыми по src
ip, dst ip, src port). Приминение sfq в некоторых случаях может помочь
избежать ситуации, когда процесс закачки полностью занял полосу и в
результате остальные приложения не могут отправлять пакеты.
В вышеприведенном примере мы выделяем гарантированную полосу для
каждого из двух пользователей, при этом неиспользуемая часть
зарезервированной для них полосы не может быть использована другими.
Допуская, что вся сеть 192.168.0.0/24 состоит из пользователей, для
которых нужно установит ограничение в 128Кбит/с каждому, но не имеется
желания выделять на них более 2Мбит/с. В этом случае конфигурация
может быть следующей:
#tc qdisc add dev eth0 root handle 1: htb
#tc class add dev eth0 parent 1: classid 1:1 htb rate 250kbps burst 10kbps
#tc class add dev eth0 parent 1:1 classid 1:10 htb rate 16kbps ceil 250kbps burst 2kbps
#tc class add dev eth0 parent 1:1 classid 1:20 htb rate 16kbps ceil 250kbps burst 2kbps
#tc class add dev eth0 parent 1:1 classid 1:30 htb rate 16kbps ceil 250kbps burst 2kbps
...
#tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.0.1 flowid 1:10
#tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.0.2 flowid 1:20
#tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.0.2 flowid 1:30
...
В этом случае пользовательские классы создаются как подклассы одного
root класса, определяющего общую пропускную способность, полоса в
2Мбит/с делится между всеми подклассами в соответсвии с их
параметрами.
Динамическое управление настройками шейпера через АСР должно быть
реализовано как часть скриптов vg_on, vg_off, vg_edit. При старте
агента эти скрипты запускаются для всех пользователей (vg_off для
заблокированных, vg_on для активных). Соответсвенно vg_on должен
добавлять правило для шейпера, а vg_off его удалять. Так же можно
использовать vg_create, vg_delete и vg_edit, которые запускаются
ссответсвенно при создании, удалении и редактировании учетной записи.
В параметрах скрипту передается все необходимое - ip, netmask, полоса
пропускания.
Примеры скриптов можно посмотреть здесь (ссылка).
3. FreeBSD маршрутизатор
Во FreeBSD существуют две различные реализации QoS: DUMMYNET и ALTQ.
Первая используется совместно с ipfw и содержится в базовой
комплектации ОС. ALTQ до недавнего времени приходилось устанавливать
отдельно, в отличие от dummynet здесь реализованы более гибкие
механизмы управления очередями (CBQ, RED...). Для задачи решаемой в
рамках этого документа - простого ограничения полосы пропускания для
пользователя (группы пользователей) - вполне подойдет dummynet.
3.1 Примеры настройки шейпера с использованием ipfw+dummynet.
В первую очередь, ядро должно быть сконфигурировано со следующими
опциями:
options IPFIREWALL
options DUMMYNET
options HZ=1000
Управление трафиком осуществляется при помощи двух объектов: канал
или труба(pipe) и очередь(queue). Каналы обладают такими свойствами
как пропускная способнось, размер очереди пакетов и дополнительная
задержка каждого пакета. Канал по сути имитирует линк заданной
"толщины". Очереди осуществляют распределение полосы пропускания в
соответвии с заданными весами(WFQ).
Канал определяется следующим правилом:
#ipfw pipe 1 config bw 256Kbits queue 20
Канал с номером 1 будет иметь пропускную способность 512Кбит/с и
очередь размером в 40 слотов(пакетов). Направления трафика в данный
канал осуществляется обычным правилом firewall'а:
#ipfw add pipe 1 ip from any to 192.168.0.1
Таким образом весь трафик, идущий на ip 192.168.0.1 в локальной сети
будет ограничен согласно параметрам созданного pipe'а. Для каждого
пользователя в АСР с установленным ограничением скорости нужно создать
свой pipe и соответсвующее правило ipfw. Однако эту задачу можно
несколько упростить, благодаря возможности использовать маску при
создании канала. Продемонстрируем на примере:
#ipfw pipe 1 config mask dst-addr 0xffffffff bw 256Kbits queue 20
Созданный таким образом канал на самом деле является шаблоном, на
основе которго создаются каналы для каждого нового адреса назначения
(dst-addr).
Можно статически прописать шаблоны всех используемых скоростей и с
помощью средств АСР динамически управлять только правилами ipfw,
направляющими трафик в тот или иной канал:
#ipfw pipe 1 config mask dst-addr 0xffffffff bw 64Kbits queue 10
#ipfw pipe 2 config mask dst-addr 0xffffffff bw 128Kbits queue 10
#ipfw pipe 3 config mask dst-addr 0xffffffff bw 256Kbits queue 20
#ipfw pipe 4 config mask dst-addr 0xffffffff bw 512Kbits queue 40
Примеры скриптов (ссылка).
3.2. Пример использования очередей (queue).
Часто возникает необходимость использования приоритезации трафика.
Предположим, есть несколько привиллегированных пользователей(VIP),
которым нужно гарантировать хорошую пропускную способность даже в
случае полной загрузки канала. Это можно реализовать, например, так.
Всю полосу пропускания необходимо поделить на две очереди: очередь для
"VIP персон" и для всех остальных с разными весовыми коэффициентами.
На языке ip-фильтра выглядить это будет следующим образом.
ipfw pipe 1 config bw 1000Kbit/s queue 40
ipfw queue 1 config pipe 1 weight 50 queue 40 mask dst-addr 0xffffffff
ipfw queue 2 config pipe 1 weight 10 queue 40 mask dst-addr 0xffffffff
ipfw add queue 1 ip from any to 192.168.0.0/24
ipfw add queue 2 ip from any to 172.16.0.0/12
Трафик подсети 192.168.0.0/24 попадает в первую (VIP) очередь. В
этой очереди в единицу времени обрабатывается в 5 раз больше пакетов,
чем во второй. В отличии от pipe здесь не происходит резервирование
полосы пропускания, поэтому если VIP очередь пустует, вся полоса (в
данном примере 1Мбит/с) делится между всеми остальными пользователями.
В большинстве случаев, чтобы добиться требуемого распределения полосы
пропускания между пользователями, необходимо использовать комбинации
queue и pipe.
Примечание: следует обратить внимание на следующий параметр ядра
(sysctl):
net.inet.ip.fw.one_pass: 0 - пакет обрабатывается следующим правилом
firewall'а при выходе из pipe, 1 - не обрабатывается.
(с) Сетевые решения, 2001-2006
По поводу создания rate-limit на cisco могу сказать, когда клиентов 10-20 это нормально, но когда их сотни и даже тысячи, то такая схема не прокатывает. Реальное решение для провайдеров это UBRL (User Based Rate Limit) или другими словами microflow. А увязать его с LanBilling особого труда не составит.