Etcnet QoS
Настройка QoS в /etc/net (редакция 3)
Общая теория
QoS -- quality of service (качество обслуживания) -- общий термин, обозначающий технологии управления скоростными и временными характеристиками пропускаемого трафика. Конфигурация выполняется для каждого интерфейса отдельно. Для этого создаётся древовидная структура, состоящая из дисциплин очередей и классов. Корень этой структуры -- так называемая корневая дисциплина очереди, которая является обязательным атрибутом интерфейса. Увидеть её можно так:
$ /sbin/ip ad sh dev eth0 3: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 4c:00:10:3b:3e:f0 brd ff:ff:ff:ff:ff:ff inet 10.1.1.175/23 brd 10.1.1.255 scope global eth0
В данном случае корневая дисциплина очереди -- pfifo_fast (она назначается по умолчанию). Иерархия очередей и классов определяет, как именно будут обрабатываться исходящие с интерфейса пакеты: номинальная скорость, параметры допустимых кратковременных всплесков, правила переупорядочивания пакетов внутри очередей, условия взаимного заимствования полосы пропускания между объектами на одном уровне иерархии и прочие параметры, зависящие от конкретной используемой структуры. "Перпендикулярно" этому дереву существует набор фильтров, которые описывают прохождение пакетов по структуре. Наиболее популярными являются дисциплины очередей CBQ (class based queueing) и HTB (hierarchical token bucket). Дерево CBQ формируется по довольно простым принципам:
- пропускная способность корневой дисциплины очереди интерфейса равна физической пропускной способности интерфейса
- классы могут иметь своим родителем только дисциплину очереди
- решение о направлении пакета в класс принимается в дисциплине очереди с помощью фильтров
- если вам необходимо разделить класс на подклассы, то создайте вложенную дисциплину очереди, а далее делите её
Дерево HTB строится ещё проще:
- классы могут содержать другие классы напрямую, без промежуточных дисциплин очередей
Описание реализации
Общая идея реализации в /etc/net заключается в том, что иерархия объектов QoS представляется в виде дерева каталогов и файлов. Конфигурация начинается с каталога qos, располагающегося в каталоге конфигурации интерфейса. Далее в нём могут содержаться другие каталоги, которые представляют либо дисциплины очереди, либо классы. В каталогах дисциплин присутствуют файлы с названием qdisc, а в каталогах с классами -- файлы class. Эти файлы содержат параметры дисциплин и классов. Фильтры располагаются в файлах с названием filter.
Пример 1
Рассмотрим пример конфигурации HTB, поставляемый с /etc/net: http://etcnet.org/examples/QoS-HTB-user-guide/1/qdisc Так как дерево начинается с корневой дисциплины, то в каталоге qos будет содержаться только один каталог qos/1, а в нём будет содержаться файл qdisc:
[DIR] 1/ 22-Aug-2005 14:13 - [TXT] qdisc 18-Mar-2005 11:06 1k
Корневая дисциплина здесь имеет номер 1. Параметры корневой дисциплины простые: htb default 12. Корневая дисциплина кроме своих параметров содержит один класс в каталоге qos/1/1. Полным именем объекта будет 1:1. Левое число отсутствует в названии каталога, так как оно всегда равно идентификатору очереди. В файле qos/1/1/class содержатся параметры класса: htb rate 100kbps ceil 100kbps. Кроме этого, в каталогах qos/1/1/2 и qos/1/1/12 определено ещё два класса: 1:2 и 1:12. В файле qos/1/1/extra содержатся параметры, общие для классов 1:2 и 1:12: htb ceil 100kbps. Это необязательный файл, можно было бы поместить эти параметры в файлы qos/1/1/2/class и qos/1/1/12/class. Если у вас много классов на одном уровне, то файл extra поможет вынести общую часть "за скобки". Класс 1:12 пуст, а класс 1:2 содержит 1:10 и 1:11. В файлах qos/1/1/2/10/filter и qos/1/1/2/11/filter содержатся описания фильтров по одному в каждой строке. Местоположение файла filter определяет, куда будут направлены пакеты, которые ему удовлетворяют. Для класса 1:10 будет использован один фильтр protocol ip prio 1 u32 match ip src 1.2.3.4 match ip dport 80 0xffff, что соответствует исходящему HTTP-трафику с адреса 1.2.3.4, а для класса 1:11 будет использован фильтр protocol ip prio 1 u32 match ip src 1.2.3.4, что соответствует всему исходящему трафику с адреса 1.2.3.4. Файлы class классов 1:10 и 1:11 содержат соответственно rate 30kbps и rate 10kbps.
Пример 2
1. Я советую, поставив пакет etcnet, сначала спрятать куда-нибудь все каталоги интерфейсов из /etc/net/ifaces ( кроме lo, default и unknown) и запустить /etc/net/scripts/initconf. Его выдачу сохранить и на основании этой выдачи организовать файл /etc/net/iftab, который определит логические имена интерфейсов. Например, одну сетевую карту можно из eth0 переименовать в соответствии с её макадресом в wan, другую - в lan. Я для себя использовал вместо wan имя провайдера (comcast), а вместо lan - придуманное самим имя локального домена своей сети 192.168.10.0/24 (menlo). Ну и дальше буду их использовать, чтобы не ошибиться где-нибудь заменяя их на более нейтральные типа wan и lan. Далее создайте каталоги с именами определёнными в таблице /etc/net/iftab, внутри /etc/ifaces. Я создал /etc/net/ifaces/comcast и /etc/net/ifaces/comcast. И положил туда нужные мне файлы options. Для внешней сети comcast достаточно определить TYPE и BOOTPROTO, я добавил строчку MODULE как того рекомендовал initconf:
# cat <<EOF >/etc/net/ifaces/comcast/options TYPE=eth BOOTPROTO=dhcp MODULE=tulip EOF
Для интерфейса локальной сети menlo адрес задан статически, так что там кроме файла options ещё нужен файл ipv4address:
# cat <<EOF >/etc/net/ifaces/menlo/options TYPE=eth BOOTPROTO=static MODULE=natsemi EOF # echo "192.168.10.1/24" >/etc/net/ifaces/menlo/ipv4address
2. Дальше настраиваете ip-forwarding и nat masquarading. За первый отвечает строчка
net.ipv4.ip_forward = 1
в файле /etc/net/sysctl.conf, в то время как другое делается добавлением строки masquerade out-iface comcast в файл /etc/net/ifaces/default/fw/iptables/nat/POSTROUTING:
echo "masquerade out-iface comcast" >>/etc/net/ifaces/default/fw/iptables/nat/POSTROUTING
После этого ваш раутер после # service network restart уже должен начать выполнять свою функцию разделения доступа в интернет.
3. Далее я настраивал распознавание и маркирование пакетов, которым надо было обеспечить гарантированную ширину пропускания канала. Для меня это были два телефонных адаптера, которые не искажают звук только если им предоставлены 10 килобит в секунду. Эти адаптеры стоят в локальной сети и dhcp сервер по их мак-адресам даёт им статические адреса. Эти адреса я и использовал в качестве критерия для маркировки. Маркировка обеспечивается следующим образом:
#cat <<EOF >/etc/net/ifaces/default/fw/iptables/mangle/PREROUTING mark 21 if from 192.168.10.21 from-iface menlo mark 22 if from 192.168.10.5 from-iface menlo EOF
Мысль для себя на будущее: наверно можно было маркировать по мак-адресу, и тем самым избежать необходимости настраивать статические адреса выдаваемые dhcpd.
4. Ну а теперь остаётся самое настроить qos htb для идущего наружу интерфейса comcast.
# # создаём дисциплину 1 # mkdir -p /etc/net/ifaces/comcast/qos/1 # # определяем что эта дисциплина - htb # # и её дефолтный класс для неклассифицированного траффика 77. # echo "htb default 77" >/etc/net/ifaces/comcast/qos/1/qdisc # # создаём корневой класс 1 (1:1) # mkdir /etc/net/ifaces/comcast/qos/1/1 # # определяем ширину пропускания интерфейса (upload) # echo "htb rate 360kbit" >/etc/net/ifaces/comcast/qos/1/1/class # # организуем фильтр, направляющий весь траффик в класс 1:1 # echo "proto ip prio 1 u32 match ip src 0.0.0.0/0" >/etc/net/ifaces/comcast/qos/1/1/filter # # создаём класс для первого телефонного адаптера # mkdir /etc/net/ifaces/comcast/qos/1/1/21/ # # определяем для него ширину пропускания 80 килобит/сек. # echo "htb rate 80kbit" >/etc/net/ifaces/comcast/qos/1/1/21/class # # задаём фильтр этого класса, отбирающий для него пакеты с маркой "21" # echo "protocol ip prio 1 handle 21 fw" >/etc/net/ifaces/comcast/qos/1/1/21/filter # # создаём класс для второго телефонного адаптера # mkdir /etc/net/ifaces/comcast/qos/1/1/22/ # # определяем для него ширину пропускания 80 килобит/сек. # echo "htb rate 80kbit" >/etc/net/ifaces/comcast/qos/1/1/22/class # # задаём фильтр этого класса, отбирающий для него пакеты с маркой "22" # echo "protocol ip prio 1 handle 22 fw" >/etc/net/ifaces/comcast/qos/1/1/22/filter # # создаём класс для дефолтного траффика: # mkdir /etc/net/ifaces/comcast/qos/1/1/77/ # # определяем для него ширину пропускания 200 (= 360 - (80 + 80)) килобит/сек. # # с возможностью заимствования неиспользуемого в данный момент траффика других классов # # вплоть до 360kbit, то есть полной ширины исходящего канала # echo "htb rate 200kbit ceil 360kbit" >/etc/net/ifaces/comcast/qos/1/1/77/class
Теперь телефонам будет предоставляться 80 килобит в секунду как только они того потребуют, а если они недоиспользуют эти 80kbit, всё оставшееся будет предоставляться другим соединениям.
P.S Большое спасибо Денису Овсиенко за то, что объяснил, как правильно организовать иерархию фильтров, чтобы эта конструкция заработала.
Утилиты
- С 11/07/2006 в contrib находится скрипт eqos (по аналогии с efw), который предназначен для ручного управления qos и умеет следующее:
/etc/net QoS handler
Usage: ./eqos [iface] <action> [action options]
iface - real interface name ('eth0' by default) or 'all' for all interfaces action - 'start','stop','restart','show|list','stat|stats'
start - start QoS for given interface stop - stop QoS for given interface restart - equivalent to 'stop' then 'start' show - list qdiscs, classes or filters on given interface list - same as 'show' stat - print statistics for qdiscs, classes or filters on given interface stats - same as 'stat'
Options for actions 'show' or 'list' and 'stat' or 'stats':
- one of 'qdisc' (by default), 'class' or 'filter'
- component specific options (e.g. 'parent')