Причесываем трафик — динамический шейпер на Linux. Шейпер трафика


Ограничение скорости передачи трафика. Policer или shaper, что использовать в сети?

Когда речь заходит об ограничении пропускной способности на сетевом оборудовании, в первую очередь в голову приходят две технологи: policer и shaper. Policer ограничивает скорость за счёт отбрасывания «лишних» пакетов, которые приводят к превышению заданной скорости. Shaper пытается сгладить скорость до нужного значения путём буферизации пакетов. Данную статью я решил написать после прочтения заметки в блоге Ивана Пепельняка (Ivan Pepelnjak). В ней в очередной раз поднимался вопрос: что лучше – policer или shaper. И как часто бывает с такими вопросами, ответ на него: всё зависит от ситуации, так как у каждой из технологий есть свои плюсы и минусы. Я решил разобраться с этим чуточку подробнее, путём проведения нехитрых экспериментов. Полученные результаты подкатом.

И так, начнём с общей картинки разницы между policer и shaper.

Как видно, policer срезает все пики, shaper же делает сглаживание нашего трафика. Достаточно неплохое сравнение между policer и shaper можно найти здесь.

Обе технологии в своей основе используют механизм токенов (token). В этом механизме присутвует виртуальное ограниченное по размеру ведро (token bucket), в которое с некой регулярностью поступают токены. Токен, как проездной, расходуется для передачи пакетов. Если токенов в ведре нет, то пакет отбрасывается (могут выполняться и другие действия). Таким образом, мы получаем постоянную скорость передачи трафика, так как токены поступают в ведро в соответствии с заданной скоростью.

Может стоило сделать проще?Скорость сессии обычно меряется в отведённый промежуток времени, например, за 5 сек или 5 минут. Брать мгновенное значение бессмысленно, так как данные всегда передаются на скорости канала. При этом если мы будем делать усреднение за разные временные интервалы, мы получим разные графики скорости передачи данных, так как трафик в сети не равномерный. Я думаю, любой с этим сталкивался, строя графики в системе мониторинга.

Механизм токенов позволяет обеспечить гибкость в настройке ограничения скорости. Размер ведра влияет на то, как мы будем усреднять нашу скорость. Если ведро большое (т.е. токенов там может скопиться много), мы позволим трафику сильнее «выпрыгивать» за отведенные ограничения в определённые моменты времени (эквивалент усреднения на большем промежутке времени). Если размер ведра маленький, то трафик будет более равномерный, крайне редко превышая заданный порог (эквивалент усреднения на маленьком промежутке времени).

В случае policer’а наполнение ведра происходит каждый раз, когда приходит новый пакет. Количество токенов, которые загружаются в ведро, зависит от заданной скорости policer’а и времени, прошедшего с момента поступления последнего пакета. Если токенов в ведре нет, policer может отбросить пакеты или, например, перемаркировать их (назначить новые значения DSCP или IPP). В случае shaper’а наполнение ведра происходит через равные промежутки времени независимо от прихода пакетов. Если токенов не хватает, пакеты попадают в специальную очередь, где ждут появления токенов. За счёт этого имеем сглаживание. Но если пакетов приходит слишком много, очередь shaper’а в конечном счёте переполняется и пакеты начинают отбрасываться. Стоит отметить, что приведённое описание является упрощённым, так как и policer и shaper имеют вариации (детальный разбор данных технологий займёт объём отдельной статьи).

Эксперимент

А как это выглядит на практике? Для этого соберём тестовый стенд и проведём следующий эксперимент. Наш стенд будет включать устройство, которое поддерживает технологии policer и shaper (в моём случае – это Cisco ISR 4000; подойдёт устройство любого вендора аппаратное или программное, которое поддерживает данные технологии), генератор трафика iPerf и анализатор трафика Wireshark.

Сначала посмотрим на работу policer. Настроим ограничение скорости равным 20 Мбит/с.

Конфигурация устройстваpolicy-map Policer_20 class class-default police 20000000 interface GigabitEthernet0/0/1 service-policy output Policer_20Используем автоматически выставляемое значение размера ведра токенов (token bucket). Для нашей скорости – это 625 000 байт. В iPerf запускаем генерацию трафика в рамках четырёх потоков, используя протокол TCP.C:\Users\user>iperf3.exe -c 192.168.115.2 -t 20 -i 20 -P 4 Connecting to host 192.168.115.2, port 5201 [ 4] local 192.168.20.8 port 55542 connected to 192.168.115.2 port 5201 [ 6] local 192.168.20.8 port 55543 connected to 192.168.115.2 port 5201 [ 8] local 192.168.20.8 port 55544 connected to 192.168.115.2 port 5201 [ 10] local 192.168.20.8 port 55545 connected to 192.168.115.2 port 5201 [ ID] Interval Transfer Bandwidth [ 4] 0.00-20.01 sec 10.2 MBytes 4.28 Mbits/sec [ 6] 0.00-20.01 sec 10.6 MBytes 4.44 Mbits/sec [ 8] 0.00-20.01 sec 8.98 MBytes 3.77 Mbits/sec [ 10] 0.00-20.01 sec 11.1 MBytes 4.64 Mbits/sec [SUM] 0.00-20.01 sec 40.9 MBytes 17.1 Mbits/sec Средняя скорость составила 17.1 Мбит/с. Каждая сессия получила разную пропускную способность. Обусловлено это тем, что настроенный в нашем случае policer не различает потоки и отбрасывает любые пакеты, которые превышают заданное значение скорости.

С помощью Wireshark собираем дамп трафика и строим график передачи данных, полученный на стороне отправителя.

Чёрная линия показывают суммарный трафик. Разноцветные линии – трафик каждого потока TCP. Прежде чем делать какие-то выводы и углубляться в вопрос, давайте посмотрим, что у нас получится, если policer заменить на shaper.

Настроим shaper на ограничение скорости 20 Мбит/с.

Конфигурация устройстваpolicy-map Shaper_20 class class-default shape average 20000000 queue-limit 200 packets interface GigabitEthernet0/0/1 service-policy output Shaper_20 При настройке используем автоматическое выставляемое значение размера ведра токенов BC и BE равное 8000. Но меняем размер очереди с 83 (по умолчанию в версии IOS XE 15.6(1)S2) на 200. Сделано это сознательно, чтобы получить более чёткую картину, характерную для shaper’а. На этом вопросе мы остановимся более подробно в подкате «Влияет ли глубина очереди на нашу сессию?». cbs-rtr-4000#sh policy-map interface gigabitEthernet 0/0/1 Service-policy output: Shaper_20 Class-map: class-default (match-all) 34525 packets, 50387212 bytes 5 minute offered rate 1103000 bps, drop rate 0000 bps Match: any Queueing queue limit 200 packets (queue depth/total drops/no-buffer drops) 0/0/0 (pkts output/bytes output) 34525/50387212 shape (average) cir 20000000, bc 80000, be 80000 target shape rate 20000000 В iPerf запускаем генерацию трафика в рамках четырёх потоков, используя протокол TCP.C:\Users\user>iperf3.exe -c 192.168.115.2 -t 20 -i 20 -P 4 Connecting to host 192.168.115.2, port 5201 [ 4] local 192.168.20.8 port 62104 connected to 192.168.115.2 port 5201 [ 6] local 192.168.20.8 port 62105 connected to 192.168.115.2 port 5201 [ 8] local 192.168.20.8 port 62106 connected to 192.168.115.2 port 5201 [ 10] local 192.168.20.8 port 62107 connected to 192.168.115.2 port 5201 [ ID] Interval Transfer Bandwidth [ 4] 0.00-20.00 sec 11.6 MBytes 4.85 Mbits/sec [ 6] 0.00-20.00 sec 11.5 MBytes 4.83 Mbits/sec [ 8] 0.00-20.00 sec 11.5 MBytes 4.83 Mbits/sec [ 10] 0.00-20.00 sec 11.5 MBytes 4.83 Mbits/sec [SUM] 0.00-20.00 sec 46.1 MBytes 19.3 Mbits/sec Средняя скорость составила 19.3 Мбит/с. При этом каждый поток TCP получил примерно одинаковую пропускную способность.

С помощью Wireshark собираем дамп трафика и строим график передачи данных, полученный на стороне отправителя.

Чёрная линия показывают суммарный трафик. Разноцветные линии – трафик каждого потока TCP.

Сделаем первые промежуточные выводы:

  • В случае policer полезная пропускная способность составила 17.1 Мбит/с. Каждый поток в разные моменты времени имел разную пропускную способность.
  • В случае shaper полезная пропускная способность составила 19.3 Мбит/с. Все потоки имели примерно одинаковую пропускную способность.
Посмотрим более детально на поведение TCP сессии в случае работы policer и shaper. Благо, в Wireshark достаточно инструментов, чтобы сделать такой анализ.

Начнём c графиков, на которых отображаются пакеты с привязкой ко времени их передачи. Первый график – policer’а, второй – shaper’а.

Из графиков видно, что пакеты в случае shaper передаются более равномерно по времени. При этом в случае policer видны скачкообразные разгоны сессии и периоды пауз.

Анализ TCP сессии при работе policer

Посмотрим поближе на сессию TCP. Будем рассматривать случай policer’а.

Протокол TCP в своей работе опирается на достаточно большой набор алгоритмов. Среди них для нас наиболее интересными являются алгоритмы, отвечающие за управление перегрузками (congestion control). Именно они отвечают за скорость передачи данных в рамках сессии. ПК, на котором запускался iPerf, работает под управлением Windows 10. В Windows 10 в качестве такого алгоритма используется Compound TCP (CTCP). CTCP в своей работе позаимствовал достаточно многое из алгоритма TCP Reno. Поэтому при анализе TCP сессии достаточно удобно посматривать на картинку с состояниями сессии при работе алгоритма TCP Reno.

На следующей картинке представлен начальный сегмент передачи данных.

  1. На первом этапе у нас устанавливается TCP сессия (происходит тройное рукопожатие).
  2. Далее начинается разгон TCP сессии. Работает алгоритм TCP slow-start. По умолчанию значение окна перегрузки (congestion window — cwnd) для TCP-сессии в Windows 10 равно объёму десяти максимальных сегментов данных TCP сессии (MSS). Это означает, что данный ПК может отправить сразу 10 пакетов, не дожидаясь получения подтверждения на них в виде ACK. В качестве начального значения порога прекращения работы алгоритма slow-start (ssthresh) и перехода в режим избегания перегрузки (congestion avoidence) берётся значение максимального окна, которое предоставил получатель (advertised window — awnd). В нашем случае ssthresh=awnd=64K. Awnd – максимальное значение данных, которые получатель готов принять себе в буфер.Где посмотреть начальные данные сессии?Чтобы посмотреть параметры TCP, можно воспользоваться PowerShell.

    Смотрим, какой глобальный шаблон TCP используется в нашей системе по умолчанию.

    Далее выполняем запрос «Get-NetTCPSetting Internet» и ищем значение величины InitialCongestionWindow(MSS). Значение awnd можно найти в пакетах ACK, пришедших от получателя: В режиме TCP slow-start размер окна (cwnd) увеличивается каждый раз при получении ACK. При этом оно не может превысить значение awnd. За счёт такого поведения, мы имеем практически экспоненциальный рост количества передаваемых пакетов. Наша TCP сессия разгоняется достаточно агрессивно.Передача пакетов в режиме TCP slow-start
    1. ПК устанавливает TCP-соединение (№1-3).
    2. Отправляет 10 пакетов (№4-13), не дожидаясь подтверждения (ACK), так как cwnd=10*MSS.
    3. Получает ACK (№14), который подтверждает сразу два пакета (№4-5).
    4. Увеличивает размер окна Cwnd=(10+2)*MSS=12*MSS.
    5. Отправляет дополнительно три пакета (№15-17). По идее ПК должен был отправить четыре пакета: два, так как он получил подтверждение на два пакета, которые были переданы ранее; плюс два пакета из-за увеличения окна. Но в реальности на самом первом этапе система шлёт (2N-1) пакетов. Найти ответ на этот вопрос мне не удалось. Если кто-то подскажет, буду благодарен.
    6. Получает два ACK (№18-19). Первое ACK подтверждает получение удалённой стороной четырёх пакетов (№6-9). Второе — трёх (№10-12).
    7. Увеличивает размер окна Cwnd=(12+7)*MSS=19*MSS.
    8. Отправляет 14 пакетов (№20-33): семь новых пакетов, так как получили ACK на семь ранее переданных пакетов, и ещё семь новых пакетов, так как увеличилось окно.
    9. И так далее.
  3. Policer никак не препятствует разгону сессии. Токенов в ведре много (при инициализации policer’а ведро заполнено токенами полностью). Для скорости 20 Мбит/с размер ведра по умолчанию выставляется равным 625000 байт. Таким образом, сессия разгоняется в момент времени практически до 18 Мбит/с (а мы помним, что у нас таких сессий четыре). Размер окна cwnd достигает максимального значения и становится равным awnd, а значит, cwnd = ssthersh. cwnd = ssthersh

    Когда cwnd = ssthersh точного ответа, произойдёт ли смена алгоритма с slow-start на алгоритм congestion avoidance, я найти не смог. RFC точного ответа не даёт. С практической точки зрения это не очень важно, так как размер окна дальше расти не может.

  4. Так как наша сессия разогналась достаточно сильно, токены очень быстро тратятся и в конечном итоге заканчиваются. Ведро не успевает наполнятся (наполнение токенами идёт для скорости 20 Мбит/с, при этом суммарная утилизация всеми четырьмя сессиями в моменте времени приближается к 80 Мбит/с). Policer начинает отбрасывать пакеты. А значит, до удалённой стороны они не доходят. Получатель шлёт Duplicate ACK (Dup ACK), которые сигнализируют отправителю, что произошла потеря пакетов и нужно передать их заново. После получения трёх Dup ACK наша TCP сессия переходит в фазу восстановления после потери (loss recovery, включающую алгоритмы Fast Retransmit/Fast Recovery). Отправитель устанавливает новое значение ssthresh = cwnd/2 (32K) и делает окно cwnd = ssthresh+3*MSS.
  5. Отправитель пытается сразу же начать заново передать потерянные пакеты (работает алгоритм TCP Fast Retransmission). При этом продолжают приходить Dup ACK, назначение которых — искусственно увеличить окно cwnd. Это нужно, чтобы как можно быстрее восстановить скорость сессии из-за потери пакетов. За счёт Dup ACK окно cwnd вырастает до максимального значения (awnd).

    Как только было отправлено количество пакетов, укладывающихся в окно cwnd, система останавливается. Для продолжения передачи данных ей нужны новые ACK (не Dup ACK). Но ACK не приходят. Все повторные пакеты отбрасываются policer’ом, так в ведре закончились токены, а времени, чтобы их восполнить, прошло слишком мало.

  6. В таком состоянии система ждёт, пока не сработает таймаут на получение нового ACK от удалённой стороны (Retransmission timeout — RTO). С этим как раз и связаны наши большие паузы, которые видны на графиках.
  7. После срабатывания таймера RTO система переходит в режим slow-start и устанавливает ssthresh = FlightSize/2 (где FlightSize – количество не подтверждённых данных), а окно cwnd = 1*MSS. Далее снова делается попытка передать потерянные пакеты. Правда, теперь отправляется всего один пакет, так как cwnd = 1*MSS.
  8. Так как в течение некоторого времени система ничего не передавала, в нашем ведре успели накопиться токены. Поэтому в конечном итоге пакет доходит до получателя. А значит, мы получим новое ACK. С этого момента система начинает передать потерянные ранее пакеты в режиме slow-start. Происходит разгон сессии. Как только размер окна cwnd превышает значение ssthresh, сессия переходит в режим congestion avoidance.

    В алгоритме Compound TCP для регулирования скорости передачи используется окно отправителя (sending window — wnd), которое зависит от двух взвешенных величин: окна перегрузки (cwnd) и окна задержки (delay window — dwnd). Cwnd, как и раньше, зависит от полученных ACK, dwnd зависит от величины задержки RTT (round trip time). Окно wnd растёт только один раз за период времени RTT. Как мы помним, в случае slow-start окно cwnd росло при получении каждого ACK. Поэтому в режиме congestion avoidance сессия разгоняется не так быстро.

  9. Как только сессия разгоняется достаточно сильно (когда пакетов передаётся больше, чем есть токенов в ведре), опять срабатывает policer. Начинают отбрасываться пакеты. Далее следует фаза loss recovery. Т.е. весь процесс повторяется заново. И так продолжается, пока у нас не завершится передача всех данных. TCP сессия при работе policer выглядит как лестница (идёт фаза передачи, за которой следует пауза).

Анализ TCP сессии при работе shaper

Теперь давайте посмотрим поближе на сегмент передачи данных для случая shaper. Для наглядности возьмём аналогичный масштаб, как и для графика policer на Рис.6. Из графика мы видим всё ту же лесенку. Но размер ступенек стал существенно меньше. Однако если приглядеться к графику на Рис. 10, мы не увидим небольших «волн» на конце каждой ступеньки, как это было на Рис. 9. Такие «волны» были следствием потери пакетов и попыток их передачи заново.

Рассмотрим начальный сегмент передачи данных для случая shaper.

Происходит установление сессии. Далее начинается разгон в режиме TCP slow-start. Но этот разгон более пологий и имеет ярко выраженные паузы, которые увеличиваются в размере. Более пологий разгон обусловлен тем, что размер ведра по умолчанию для shaper всего (BC+BE) = 20 000 байт. В то время как для policer размер ведра — 625 000 байт. Поэтому shaper срабатывает существенно раньше. Пакеты начинают попадать в очередь. Растёт задержка от отправителя к получателю, и ACK приходят позже, чем это было в случае policer. Окно растёт существенно медленнее. Получается, что чем больше система передаёт пакетов, тем больше их накапливается в очереди, а значит, тем больше задержка в получении ACK. Имеем процесс саморегуляции.

Через некоторое время окно cwnd достигает значения awnd. Но к этому моменту у нас накапливается достаточно ощутимая задержка из-за наличия очереди. В конечном итоге при достижении определённого значения RTT наступает равновесное состояние, когда скорость сессии больше не меняется и достигает максимального значения для данного RTT. В моём примере среднее RTT равно 107 мс, awnd=64512 байт, следовательно, максимальная скорость сессии будет соответствовать awnd/RTT= 4.82 Мбит/с. Примерно такое значение нам и выдал iPerf при измерениях.

Но откуда берутся ярко выраженные паузы в передаче? Давайте посмотрим на график передачи пакетов через устройство с shaper в случае, если у нас всего одна TCP сессия (Рис.12). Напомню, что в нашем эксперименте передача данных происходит в рамках четырёх TCP сессий.

На этом графике очень хорошо видно, что нет никаких пауз. Из этого можно сделать вывод, что паузы на Рис.10 и 11 обусловлены тем, что у нас одновременно передаётся четыре потока, а очередь в shaper одна (тип очереди FIFO). На Рис.13 представлено расположение пакетов разных сессий в очереди FIFO. Так как пакеты передаются пачками, они будут располагаться в очереди таким же образом. В связи с этим задержка между поступлением пакетов на приёмной стороне будет двух типов: T1 и T2 (где T2 существенно превосходит T1). Общее значение RTT для всех пакетов будет одинаковым, но пакеты будут приходить пачками, разнесёнными по времени на значение T2. Вот и получаются паузы, так как в момент времени T2 никакие ACK к отправителю не приходят, при этом окно сессии остаётся неизменным (имеет максимальное значение равное awnd).Очередь WFQЛогично предположить, что, если заменить одну общую очередь FIFO на несколько для каждой сессии, никаких ярко выраженных пауз не будет. Для такой задачи нам подойдёт, например, очередь типа Weighted Fair Queuing (WFQ). В ней для каждой сессии создаётся своя очередь пакетов.policy-map Shaper class shaper_class shape average 20000000 queue-limit 200 packets fair-queue

Из общего графика мы сразу видим, что графики всех четырёх TCP сессий идентичны. Т.е. все они получили одинаковую пропускную способность.

А вот и наш график распределения пакетов по времени передачи ровно в том же масштабе, что и на Рис. 11. Никаких пауз нет.

Стоит отметить, что очередь типа WFQ позволит нам получить не только более равномерное распределение пропускной способности, но и предотвратить «забивание» одного типа трафика другим. Мы всё время говорили про TCP, но в сети также присутствует и UDP трафик. UDP не имеет механизмов подстройки скорости передачи (flow control, congestion control). Из-за этого UDP трафик может с лёгкостью забить нашу общую очередь FIFO в shaper’е, что драматически повлияет на передачу TCP. Напомню, что, когда очередь FIFO полностью заполнена пакетами, по умолчанию начинает работать механизм tail-drop, при котором отбрасываются все вновь пришедшие пакеты. Если у нас настроена очередь WFQ, каждая сессия пережидает момент буферизации в своей очереди, а значит, сессии TCP будут отделены от сессий UDP.

Самый главный вывод, который можно сделать после анализов графиков передачи пакетов при работе shaper’а – у нас нет потерянных пакетов. Из-за увеличения RTT скорость сессии адаптируется к скорости shaper’а. Влияет ли глубина очереди на нашу сессию?Конечно! Изначально (если кто-то об этом ещё помнит) мы изменили глубину очереди с 83 (значение по умолчанию) на 200 пакетов. Сделали мы это для того, чтобы очереди хватило для получения достаточного значения RTT, при котором суммарная скорость сессий становиться примерно равна 20 Мбит/с. А значит, пакеты «не вываливаются» из очереди shaper'а.

При глубине в 83 пакета очередь переполняется быстрее, нежели достигается нужное значение RTT. Пакеты отбрасываются. Особенно ярко это проявляется на начальном этапе, когда у нас работает механизм TCP slow-start (сессия разгоняется максимально агрессивно). Стоит отметить, что количество отброшенных пакетов несравнимо меньше, чем в случае с policer, так как увеличение RTT приводит к тому, что скорость сессии растёт более плавно. Как мы помним, в алгоритме CTCP размер окна в том числе зависит от значения RTT.

Графики утилизации пропускной способности и задержки при работе policer и shaper

В заключение нашего небольшого исследования построим ещё несколько общих графиков, после чего перейдём к анализу полученных данных.

График утилизации пропускной способности:

В случае policer мы видим скачкообразный график: сессия разгоняется, потом наступают потери, и её скорость падает. После чего всё повторяется снова. В случае shaper наша сессия получает примерно одинаковую пропускную способность на протяжении всей передачи. Скорость сессии регулируется за счёт увеличения значения RTT. На обоих графиках вначале можно наблюдать взрывной рост. Он обусловлен тем, что наши вёдра изначально полностью заполнены токенами и TCP-сессия, ничем не сдерживаемая, разгоняется до относительно больших значений (в случае shaper это значение в 2 раза меньше).

График задержки RTT для policer и shaper (по-хорошему, это первое о чём мы вспоминаем, когда говорим про shaper):

В случае policer (первый график) задержка RTT для большинства пакетов минимальна, порядка 5 мс. На графике также присутствуют существенные скачки (до 340 мс). Это как раз моменты, когда пакеты отбрасывались и передавались заново. Тут стоит отметить, как Wireshark считает RTT для TCP трафика. RTT – это время между отправкой оригинального пакета и получением на него ACK. В связи с этим, если оригинальный пакет был потерян и система передавала пакет повторно, значение RTT растёт, так как точкой отсчёта является в любом случае момент отправки оригинального пакета.

В случае shaper задержка RTT для большинства пакетов составила 107 мс, так как они все задерживаются в очереди. Есть пики до 190 мс.

Выводы

Итак, какие итоговые выводы можно сделать. Кто-то может заметить, что это и так понятно. Но наша цель была копнуть чуточку глубже. Напомню, что в эксперименте анализировалось поведение TCP-сессий.
  1. Shaper предоставляет нам на 13% больше полезной пропускной способности, чем policer (19.3 против 17.1 Мбит/с) при заданном ограничении в 20 Мбит/с.
  2. В случае shaper'а пропускная способность распределяется более равномерно между сессиями. Наилучший показатель может быть получен при включении очереди WFQ. При работе policer’а присутствуют существенные пики и падения скорости для каждой сессии.
  3. При работе shaper'а потерь пакетов практически нет (конечно, это зависит от ситуации и глубины очереди). При работе policer’а мы имеем существенные потери пакетов – 12.7%.

    Если policer настроен ближе к получателю, наша сеть фактически занимается прокачкой бесполезного трафика, который будет в итоге отброшен policer’ом. Например, в разрезе глобальной сети интернет это может является проблемой, так как трафик режется зачастую ближе к получателю.

  4. В случае shaper'а у нас появляется задержка (в нашем эксперименте – это дополнительные 102 мс). Если трафик примерно одинаков, без существенных всплесков, очередь shaper’а находится в относительно стабильном состоянии и больших вариаций в задержке (jitter) не будет. Если трафик будет иметь взрывной характер, мы можем получить повышенное значение jitter.

    Вообще наличие очереди может достаточно негативно сказываться на работе приложений – так называемый эффект излишней сетевой буферизации (Bufferbloat). Поэтому с глубиной очереди надо быть аккуратными.

  5. Благодаря разным типам очередей shaper позволяет нам учитывать приоритезацию трафика при ограничении скорости. И если встаёт необходимость отбрасывать пакеты, в первую очередь делать это для менее приоритетных. В policer'е добиться этого сложнее, а для некоторых схем невозможно.
  6. Policer и shaper подвержены ситуации, когда UDP трафик может «забить» TCP. При настройке этих технологий необходимо учитывать данный факт.
  7. Работа shaper'а создаёт бОльшую нагрузку на сетевое устройство, чем работа policer'а. Как минимум требуется память под очередь.
Можно отметить ещё один факт, хоть и не относящийся непосредственно к задаче ограничения скорости. Shaper позволяет нам настраивать различные типы очередей (FIFO, WFQ и пр.), обеспечивая тем самым разнообразные уровни приоритезации трафика при его отправке через устройство. Это очень удобно в случаях, если фактическая скорость передачи трафика отличается от канальной (например, так часто бывает с выходом в интернет или WAN каналами).Исследование влияния policer в сети интернетВ этом году при поддержке Google было проведено исследование, в котором анализировался негативный эффект работы policer’а в сети интернет. Было определено, что от 2% до 7% потерь видео трафика по всему Миру вызвано срабатыванием policer’а. Потери пакетов при непосредственной работе policer’а составили порядка 21%, что в 6 раз больше, чем для трафика, который не подвержен срабатыванию данной технологии. Качество видео трафика, который подвергся обработке policer’ом, хуже, чем в случае, если policer не срабатывал.

Для борьбы с негативным эффектом работы policer’а предлагаются следующие меры в зависимости от точки их применения.

Для интернет-провайдеров:

  1. В policer’е уменьшить размер ведра (burst size). Это приведёт к тому, что TCP сессия не сможет слишком сильно разогнаться, пока есть свободные токены, и быстрее начнёт адаптацию под реальную пропускную способность.
  2. Вместо policer’а использовать shaper (с небольшой глубиной очереди).
  3. Использовать и shaper, и policer одновременно. В этом случае shaper располагается чуть раньше, чем policer. Shaper задерживает пакеты, сглаживая колебания. Из-за такой задержки policer успевает аккумулировать достаточное количество токенов, чтобы передавать трафик. Потери в таком случае минимизируются.
Однозначных рекомендаций по поводу конфигурации shaper в документе не даётся. Shaper может обеспечивать положительный эффект как при большом, так и при маленьком значении размера ведра (даже если BC = 8 000 байт). Также нет однозначной рекомендации по поводу глубины очереди. Маленькая глубина приводит к лишним потерям, большая может негативно сказаться на задержках в сети. Во всех случаях есть свои плюсы и минусы.

Для контент-провайдеров предлагается ограничивать скорость отправки трафика на сервере, чтобы избегать включения policer’а. Но на практике оценить реальную скорость канала не всегда просто. Второй метод — избегать взрывной передачи трафика за счёт модификации алгоритмов TCP: использовать TCP Pacing (отправлять пакеты с привязкой к RTT, а не к моменту получения ACK) и изменить схему работы фазы loss recovery (на каждый полученный ACK слать только один новый пакет).

Таким образом, нет однозначного ответа на вопрос, что лучше использовать: shaper или policer. Каждая технология имеет свои плюсы и минусы. Для кого-то дополнительная задержка и нагрузка на оборудование не так критична, как для другого. А значит выбор делается в сторону shaper. Кому-то важно минимизировать сетевую буферизацию для борьбы с джиттером – значит наша технология policer. В ряде случаев вообще можно использовать одновременно обе эти технологии. Поэтому выбор технологии зависит от каждой конкретной ситуации в сети.

habrahabr.ru

Шейпер трафика: режем скорость.

htb.init - это скрипт, который с помощью утилит ip, tc настраивает пропускную способность канала.Адрес проекта HTB.init http://sourceforge.net/projects/htbinit/

Немного теории:

Шейпер может ограничивать только ИСХОДЯЩИЙ трафик, распределяя его по разным очередям.Пакеты, не помещающиеся в очередь, отбрасываются. Данные из очереди выдаются на сетевой интерфейс и далее к клиенту.

Каждый конфигурационный файл описывает очередь, это заложено в самом названии файла, который имеет формат:$HTB_PATH/<ifname>-<clsid>(:<clsid>).<description>или если "по-русски":$HTB_PATH/<Имя интерфейса>-<Номер класса>(:<Номер дочернего класса>).<Комментарий>

clsid - задается цифровыми значениями от 0x2 до 0xFFFF (записывается без приставки 0x)Сам интерфейс описывается файлом только с именем ifname. Например:

eth0 имеет идентификатор класса clsid=0.eth0-2 - основной (корневой) класс с clsid=2eth0-2:3 - класс очереди clsid=3, унаследует ограничения от родительского clsid=2eth0-2:3:4 - класс очередь clsid=4, унаследует ограничения от родительского clsid=3 и 2, т.е. накладываются еще более жесткие ограничения.

 

Параметры

- DEFAULT=30 : указывает номер класса, куда попадает трафик не попавший ни под одно правило.- R2Q=10 : точность шейпера.- RATE=5Mbit : выделенная (гарантированная) пропускная способность очереди, задается в Kbit, Mbit или bps (bytes per second)- CEIL=6MBit : максимальная пропускная способность очереди. если не указывать, то по умолчанию CEIL=RATE- BURST=<bytes> : количество байт без ограничения скорости- PRIO=<number> : приоритет трафика очереди к другим очередям в классе. Чем меньше число, тем выше приоритет. По умолчанию 0- LEAF=<параметр> правило распределения внутри самой очереди. default "none". LEAF=sfq - равномерное распределение между участниками очереди.- RULE= : правило, определяющее трафик, который должен проходить через данную очередь. В одном файле могут присутствовать сразу несколько правил.RULE=[[source_addr][:port[/mask]],][destination_addr][:port[/mask]]Если трафик попадает по условиям в очередь -2:10 (например где правило задано по маске), то дальше он уже не будет проверять условия в -2:20 (где допустим будет описано правило с конкретно этим ip), -2:30- MARK=<метка> : трафик имеющий метку. Например если надо ограничить исходящий трафик от клиента в лок. сети, находящегося за NATом, RULE не прокатит, нужно использовать MARK, и метить нужные пакеты в фаерволе примерно так:iptables -t mangle -A PREROUTING -s 192.168.0.1 -j MARK –set-mark 101- TIME : временные параметры. TIME=18:00-06:00;256KbitДля корректной работы скрипта, сумма всех RATE дочерних классов (очередей) не должна превышать RATE корневого класса, а значение CEIL в каждой очереди не должно превышать значение в корневом классе.

Установка htb.init

Качаем скрипт htb.init который будет генерировать вам правила шейпера согласно созданным вами файлам конфигурации. Сайт проекта http://sourceforge.net/projects/htbinit/ .Переименуем покороче скачанный скрипт, назовем например просто htb и поместим в директорию /usr/sbin. Разрешим выполнение этого скрипта:

chmod +x /usr/sbin/htb

По желанию можно добавить скрипт в автозагрузку системы, например добавив в rc.local строку /usr/sbin/htb start

Теперь надо создать директории и файлы необходимые для правильной работы скрипта.

mkdir /etc/sysconfigmkdir /etc/sysconfig/htbtouch /var/cache/htb.init

Теперь можно приступать к написанию конфигурационных файлов нашего шейпера.

cd /etc/sysconfig/htb

На сервере имеется локалка на интерфейсе eth0, интернет на eth2. Используется NAT. Скорость интернет-канала 30Мбит\с. Необходимо обеспечить гарантированную скорость доступа по rdp (на сервере проброшены порты к некоторым компам) и ограничить скорость интернет для некоторых компьютеров в сети, при этом не ограничивая скорость в локалке (на сервере еще файлопомойка).

Создаем конфигурационные файлы:

 

Для входящего трафика:

sudo touch eth0 # Описываем интерфейс eth0sudo nano eth0

DEFAULT=10 # метка на файл, создаваемый ниже, eth0-2:10.dflR2Q=100 # точность ограничений

sudo touch eth0-2.root # корневой классsudo nano eth0-2.root

RATE=100Mbit # гарантированная пропускная способность CEIL=100Mbit # максимальная пропускная способность BURST=15k # первые 15k без ограничений

sudo touch eth0-2:10.dfl # сюда попадает трафик, не попадающий ни в одно из правил нижеsudo nano eth0-2:10.dfl

RATE=1024Kbit # гарантированная пропускная способностьCEIL=99Mbit # максимальная пропускная способностьLEAF=sfq # равномерное распределение между участниками очереди.

sudo touch eth0-2:20.rdp # гарантированный канал для rdpsudo nano eth0-2:20.rdp

RATE=1Mbit # гарантированная пропускная способностьCEIL=2Mbit # максимальная пропускная способностьBURST=15k # первые 15k без ограниченийLEAF=sfq # равномерное распределение между участниками очереди.RULE=*:3389, # Применять правило для трафика, у которого исходящий порт - rdp-порт

sudo touch eth0-2:30.87 # ограничиваем скорость для ip 10.10.10.87sudo nano eth0-2:30.87

RATE=64Kbit # гарантированная пропускная способностьBURST=15k # максимальная пропускная способностьLEAF=sfq # равномерное распределение между участниками очереди.MARK=87 # применять правило для пакетов, маркированных меткой 87

Для корректной работы надо добавить правило в фаервол:

sudo iptables -A FORWARD -d 10.10.10.87 -j MARK --set-mark 87пакеты маркируются в цепочке форвард, поэтому на локалку это правило не действует.

sudo touch eth0-2:31.137 # ограничиваем скорость для ip 10.10.10.137sudo nano eth0-2:31.137

RATE=64Kbit # гарантированная пропускная способностьBURST=15k # максимальная пропускная способностьLEAF=sfq # равномерное распределение между участниками очереди.MARK=137 # применять правило для пакетов, маркированных меткой 137

Для корректной работы надо добавить правило в фаервол:sudo iptables -A FORWARD -d 10.10.10.137 -j MARK --set-mark 137

Для исходящего трафика:

sudo touch eth2 # Описываем интерфейс eth2sudo nano eth2

DEFAULT=10 # метка на файл, создаваемый ниже, eth2-2:10.dflR2Q=100 # точность ограничений

sudo touch eth2-2.root # корневой классsudo nano eth2-2.rootRATE=30Mbit # гарантированная пропускная способность CEIL=30Mbit # максимальная пропускная способность BURST=15k # первые 15k без ограничений

sudo touch eth2-2:10.dfl # сюда попадает трафик, не попадающий ни в одно из правил нижеsudo nano eth2-2:10.dfl

RATE=256Kbit # гарантированная пропускная способностьCEIL=29Mbit # максимальная пропускная способностьLEAF=sfq # равномерное распределение между участниками очереди.

sudo touch eth2-2:20.rdp # гарантированный канал для rdpsudo nano eth2-2:20.rdp

RATE=1Mbit # гарантированная пропускная способностьCEIL=2Mbit # максимальная пропускная способностьBURST=15k # первые 15k без ограниченийLEAF=sfq # равномерное распределение между участниками очереди.RULE=*:3389 # Применять правило для трафика, у которого порт назначения - rdp-порт

sudo touch eth2-2:30.87 # ограничиваем скорость для ip 10.10.10.87sudo nano eth2-2:30.87

RATE=64Kbit # гарантированная пропускная способностьBURST=15k # максимальная пропускная способностьLEAF=sfq # равномерное распределение между участниками очереди.MARK=87 # применять правило для пакетов, маркированных меткой 87

Для корректной работы надо добавить правило в фаервол:sudo iptables -t mangle -A PREROUTING -s 10.10.10.87 -j MARK --set-mark 87

sudo touch eth2-2:31.137 # ограничиваем скорость для ip 10.10.10.137sudo nano eth2-2:31.137

RATE=64Kbit # гарантированная пропускная способностьBURST=15k # максимальная пропускная способностьLEAF=sfq # равномерное распределение между участниками очереди.MARK=137 # применять правило для пакетов, маркированных меткой 137

Для корректной работы надо добавить правило в фаервол:sudo iptables -t mangle -A PREROUTING -s 10.10.10.137 -j MARK --set-mark 137

Осталось запустить скрипт:

sudo htb compile # тест. можно посмотреть какие правила будут сформированы и ошибки, если есть.sudo htb start # запускsudo htb stop # остановкаsudo htb restart # перезапуск после внесения изменений в файлы конфигурации

linux-bash.ru

Шейпер трафика под Linux - используем CBQ

CBQ представляет собой систему ограничения трафика по скорости. Этораспространенный шейпер для Linux систем.

Данное описание составлено на основе перевода оригинальнойдокументации с английского языка.

Простейший трафик шейпер

Для начала рассмотрим простейший случай настройки. По личному опыту —обычно больше и не надо.

Сама по себе система CBQ представляет собой один исполняемый файл.Обычно он называется cbq.init и расположен в папке /etc/rc.d. Запускосуществляется командой `/etc/rc.d/cbq.init start` а остановка`/etc/rc.d/cbq.init stop`. Также можно ввести команду`/etc/rc.d/cbq.init restart` для перезапуска.

Настройка CBQ производится с помощью написания файлов конфигурациишейперов. Файлы эти обычно располагаются в папке /etc/sysconfig/cbq идолжны иметь имена следующего формата:

cbq-<cbq_id>.

, где:

«cbq-» — эта часть имени обязательна.

<cbq_id> — номер шейпера в системе. Это должно быть шестнадцатеричноечисло в диапазоне 2-FFFF (номера 0 и 1 зарезервированы).

— название шейпера. На ваше усмотрение.

Примеры:

cbq-20.director-internetCbq-FE03.godzilla

Каждый файл должен содержать строки:

DEVICE=,{Mbit|Kbit|bps}RATE={Mbit|Kbit|bps}WEIGHT={Mbit|Kbit|bps}RULE=[from_addr[/mask][:port],][to_addr[/mask][:port]]…

DEVICE — описание интерфейса

— наименование интерфейса. В Linux’е обычно eth0,eth2, eth3… или ppp0, ppp1…

— скорость интерфейсаЕсть одна тонкость — шейпер может ограничивать только трафик исходящийс указанного интерфейса. Если надо ограничить входящий трафик —напишите еще один файл с другим интерфейсом. И еще — если в одномфайле указали «DEVICE=eth0,10Mbit», то в остальных файлах для этогоинтерфейса можно писать просто «DEVICE=eth0».

RULE и WEIGHT — параметры шейпера.

— лимит скорости

— погрешность лимита. То есть ограничиваемая скорость будет максимумRATE+WEIGHT, а как правило — не выше RATE. Обычно величинаWEIGHT принимается 1/10 от RATE.

RULE — это указание от кого к кому (имеются в виду IP-адреса и порты)работает данное ограничение.

Проще всего понять на примерах:

RULE=192.168.1.0/24:80,81.95.224.64/26:80

ограничивает трафик от подсети 192.168.4.0/24 (адреса192.168.4.1-192.168.4.254) до подсети 81.95.224.64/26 (адреса81.95.224.64 — 81.95.224.126) по порту 80 (HTTP).

RULE=192.168.2.1:21,10.0.1.0/24:2021

ограничивает трафик, который идет с порта 21 адреса 192.168.2.1 напорт 2021 до порта 2021 любого компьютера подсети 10.0.1.0/24 (адреса10.0.1.1 — 10.0.1.254).

RULE=192.168.4.5:25,

ограничивает весь трафик идущий с адреса 192.168.4.5 по порту 25 кудаугодно (обратите внимание — запятая в конце обязательна).

RULE=192.168.5.0/25:110

ограничивает весь трафик идущий на компьютеры подсети 192.168.5.0/25(адреса 192.168.5.1 — 192.168.5.126) по порту 110 откуда угодно(обратите внимание — запятая в начале не нужна).

В файле может быть несколько параметров RULE. При этом ограничиваетсятрафик по всем RULE сразу, а не для каждого отдельно.

Примеры файлов конфигурации:

Пример 1.

DEVICE=eth0,10MbitRATE=64KbitWEIGHT=6KbitRULE=192.168.1.0/24:8080,10.10.10.0/28:8080RULE=192.168.75.3,81.95.224.30

Пример 2.

DEVICE=ppp1,56KbitRATE=32KbitWEIGHT=3KbitRULE=192.168.2.2

Трафик, не попадающий ни под одно правило, описанное в файлах — неограничивается.

Немного теории

Шейпер работает так: все ИСХОДЯЩИЕ пакеты, т.е. предназначенные длявыдачи на любой интерфейс вместо того, чтобы быть отправлятьсянапрямую на интерфейс ставятся в разные очереди. Длина каждой очерединастраивается. Настраиваются также: скорость выдачи данных из очереди(это и есть собственно лимит), длина очереди (размер в байтах), размерпакета, выходящего из очереди (может не совпадать с длиной поступающихпакетов) и многое другое. Пакеты, не помещающиеся в очередь,сбрасываются. Данные из очереди выдаются на интерфейс и далее — кклиенту. Вот как раз каждый файл конфигурации и представляет собойописание одной очереди.

CBQ позволяет также строить иерархические системы очередей. Каждаяочередь может брать данные из выхода другой очереди. Таким образомочередь может быть дочерней для одной очереди и родительской длямногих других.

Для правильной работы очереди нужно знать следующие данные:

А) Какие пакеты направлять в очередь, а именно:

— пришедшие от каких адресов/портов;— предназначенные для каких адресов/портов;— предназначенные для выдачи на какой интерфейс.

Б) Параметры самой очереди, а именно:

— размер очереди в байтах;— скорость выдачи данных из очереди;— приоритет очереди;— размер пакета, выдаваемого из очереди;— и т.д.

Очереди бывают следующих классов:

— очереди без определенного класса (класс NONE). Если такая очередьпереполняется, то пакеты, не вмещающиеся в нее, остаются вродительской очереди (если она есть), а если и она переполняется, тоданные, предназначенные для нее, остаются в ее родительской очереди, акогда и та переполняется — в родительской очереди еще более высокогоуровня и т.д. И только если переполняется самая верхняя очередь(класса CBQ), то пакет сбрасывается. Однако процесс можно регулироватьпараметрами BOUNDED и ISOLATED.

— CBQ — это очереди самого верхнего уровня (они все имеют cbq_id,равный 1). Их бывает по одной на каждый интерфейс. Создаютсяавтоматически. В каждую записываются пакеты, предназначенные дляданного интерфейса. Нельзя самому назначать параметры для такихочередей.

— TBF — очереди со строгим ограничением (термин мой). Пакеты, непомещающиеся в очередь, просто сбрасываются. Поведение очередиопределяется ее собственными [5]параметрами и от родительской никак независит.

— SFQ — очереди со справедливым распределением (термин мой). В этомтипе очередей лимит родительской очереди распределяется среди дочернихпо особому математическому закону для более справедливого иравномерного распределения.

Можно создать очередь, динамически меняющую скорость выдачи информациив зависимости от дня недели и времени суток.

В общем это можно представить как водопроводную систему. На входе —краны (очереди класса CBQ). Затем трубы разных диаметров и длины.Длина трубы символизирует в нашем случае размер очереди, а ее диаметр— скорость выдачи информации. На некоторых трубах есть клапаны навходе или выходе (параметры BOUNDED/ISOLATED). На трубах также могутбыть вентили (с регулировкой в зависимости от времени суток и днянедели)(параметры TIME).

Продвинутая настройка

Рассмотрим теперь подробно ВСЕ возможные параметры конфигурационныхфайлов.

Интерфейс

DEVICE=,[,] — описание устройства, параметр обязательный

— наименование интерфейса. В Linux’е обычно eth0, eth2, eth3… или ppp0, ppp1…

— скорость интерфейса (10Mbit, 56Kbit, 2Mbit …)

— вес интерфейса (обычно 10% от )

Примечание: — если в одном файле указали «DEVICE=eth0,10Mbit,1Mbit»,то в остальных файлах для этого интерфейса можно писать просто«DEVICE=eth0»

Еще раз напомню, что шейпер ограничивает только трафик, исходящий сданного интерфейса.

Общие параметры для всех классов очередей

RATE={Mbit|Kbit|bps} — скорость выдачи данных с очереди, параметр обязательный

Примеры:

RATE=10Mbit (10 Мбит/с)RATE=128Kbit (123 Кбит/с)RATE=3600bps (3600 байт/с) ********** Не бит/с **********

———-WEIGHT={Mbit|Kbit|bps} — вес шейпера. Обычно 10% от RATE

Примеры:

WEIGHT=1Mbit (1 Мбит/с)WEIGHT=12Kbit (12 Кбит/с)WEIGHT=360bps (360 байт/с) ********** Не бит/с **********RULE=[[saddr[/prefix]][:sport[/mask]],][daddr[/prefix]][:dport[/mask]]

Это фильтр, определяющий, для каких пакетов используется даннаяочередь. Параметр обязательный. Он управляет т.н. «u32 filter rules».

saddr — адрес источника (IP).

prefix — маска подсети источника. Указывается не маска в форматеxxx.xxx.xxx.xxx, а число вкл. бит (32-1).24 соответствует 255.255.255.0, 16 — 255.255.0.0 и т.д.

daddr/prefix — аналогично для адреса назначения.

sport — порт источника (0-65535).

mask — маска для порта (нужна, если надо указать не один порт, а диапазон протов). Это шестнадцатеричное число формата0x**** (например 0xfffe — маска на два порта, 0xff00 — на256 портов). Вообще число портов подряд равно 0xffff минус mask.

dport/mask — аналогично для порта назначения.

Примеры:

RULE=10.1.1.0/24:80RULE=10.2.2.5RULE=10.2.2.5:20/0xfffeRULE=10.5.5.5:80,RULE=:25,10.2.2.128/26:5000RULE=192.168.1.0/24:80,81.95.224.64/26:80

Примечание: В файле может быть несколько параметров RULE. Приэтом ограничивается трафик по всем RULE сразу, а не для каждого отдельно.

———-TIME=[,, …,/]-;/[/]

Эти параметры (их может быть несколько в одном файле) дают возможностьназначить разные лимиты скорости в зависимости от дня недели и временисуток.

— дни недели (0-7, 0=воскресение). Если лимитдействует для нескольких дней, перечислите ихчерез запятую. Если не указано, то лимит действует на все дни.

— интервал времени в формате ЧЧ:MM-ЧЧ:MM. Указывать обязательно.

— лимит скорости для данного периода (Mbit|Kbit|bps). См. RATE. Указывать обязательно.

— вес лимита для данного периода (Mbit|Kbit|bps). См. WEIGHT. Указывать обязательно.

— пик скорости для данного периода (Mbit|Kbit|bps). См. PEAK. Указывать необязательно.

Примеры:

TIME=0,1,2,5/18:00-06:00;256Kbit/25KbitTIME=18:00-06:00;256Kbit/25Kbit

Примечания: 1. Если интервалы времени перекрываются, действует тот,который описан последним.

2. Если текущее время не попадает ни под одну строку TIME,используются глобальные параметры RATE, WEIGHT и PEAK

3. Для того, чтобы это все действовало необходимо выполнять команду`/etc/rc.d/cbq.init timecheck` каждую минуту (если с точностью до минутнадо менять шейпер).

———-REALM=[srealm,][drealm] — Параметр управляет т.н. «route filter rules».Параметр необязательный.

srealm и drealm — это должны быть десятичные числа или соответствующие имстроковые значения из файла /etc/iproute2/rt_realms.

Примеры:

REALM=russia,internet от russia до internetREALM=10 до 10 от всехREALM=freenet, от freenet до всехREALM=internet,5 ot internet до 5

———-MARK= — управляет т.н. «fw filter rules». Параметр необязательный.

— десятичное число — тег для пакетов.

Пример:

MARK=15

Примечание: В одном файле может быть несколько строк MARK.

———-PRIO= — приоритет шейпера (1-8). 1- максимальныйприоритет. Необязательный параметр. Если неуказать — по умолчанию 5.

Пример:

PRIO=3

———-PARENT= — номер родительской очереди. Необязательныйпараметр. Если не указать — данные берутсянапрямую с очереди типа CBQ соответствующего интерфейса.

Пример:

PARENT=3F00

Примечание: родительская очередь должна быть описана раньше, чемдочерние. По видимому это означает, что номер ее должен быть меньше.

———-LEAF=none|tbf|sfq — класс очереди. Можно создавать очередикласса TBF или SFQ, а также очереди безкласса. Указывать необязательно, по умолчанию tbf.

Пример:

LEAF=sfq

———-BOUNDED=yes|no — ограничение. Если поставить yes, то пакеты при переполненииочереди не остаются в родительской, а сбрасываются. Указывать необязательно, по умолчанию yes

Пример:

BOUNDED=yes

Примечание: Для TBF — очередей всегда yes (даже если прямо указать no).

———-ISOLATED=yes|no — изоляция. Если поставить yes на родительской очереди,то все дочерние будут работать как будто у них BOUNDED=yes, то естьбез резервирования. Указывать необязательно, по умолчанию «no»

Пример:

ISOLATED=yes

Параметры для очередей класса TBF

LIMIT=[{Mb|Kb}] — длина очереди в мегабайтах (Mb),килобайтах (Kb) или в байтах, если не указана единица.Указывать необязательно, по умолчанию 15Kb.

Примеры:

LIMIT=10KbLIMIT=1MbLIMIT=65535

———-PEAK={Mbit|Kbit|bps} — максимальная пиковая скорость выдачи информациииз очереди. Только на короткое время. Параметр необязателен.

Примеры:

PEAK=10Mbit (10 Мбит/с)PEAK=128Kbit (123 Кбит/с)PEAK=3600bps (3600 байт/с) ********** Не бит/с **********

———-MTU= — размер выходного пакета, исходящего из очереди.Необязательный параметр, если не указать, то такой, как MTU на интерфейсе(для Ethernet — 1500). Имеет смысл указывать, когда задан параметр PEAK.

Пример:

MTU=1024

———-BUFFER=[{Mb|Kb}][/] — размер буфера.

— Это максимальное число байт (Кбайт, Мбайт), котороеможет быть выдано из очереди за один раз.

— я не понял. В оригинале — parameter is used todetermine the Length of intervals in packet sizes,for which the transmission times are kept.

Параметр указывать необязательно, по умолчанию 10Kb/8.

Параметры для очередей класса SFQ

QUANTUM= — значение не может быть меньше MTU. Что означает — не знаю.В оригинале тоже ничего не сказано. Это необязательный параметр.

Пример:

QUANTUM=1514

———-PERTURB= — период пертурбации hash-функции в секундах.По умолчанию 10. Если не указать, пертурбация никогда не происходит.Назначение непонятно.

Пример:

PERTURB=15

Еще раз хочу напомнить, что настройки каждого файла действуют толькона трафик, исходящий с интерфейса, описанного в параметре DEVICE.

itman.in

Шейпер трафика на CentOS 7 — лимитируем скорость канала!

В этой записке собраны примеры контроля скорости трафика на ОС Linux - CentOS. Эти примеры помогут контролировать скорость входящего (исходящего) канала, чтобы он полностью не забивался не нужным трафиком, например от torrent.

Когда много пользователей сидят на одном интернете, возникает проблема, в виде нехватки скорости соединения, это заметно в браузере - он начинает тормозит. В такой ситуации юзеры жалуются и гневно зовут админа :). И бывает даже такое, когда их жалобы доходят до самого директора - проверено!

В общем, можно положить любой канал (возможно роутер) через обычный торрент клиент, ведь известно, что торрент клиент закачивает данные на максимальной скорости, при этом еще умудряется создать кучу соединений с другими участниками торрент сети, которые уже закачали аналогичный файл и теперь уже раздают его.

Бывают  и  такие случаи, когда некоторые юзеры смотрят онлайн видео, и тем самым используют большую часть канала, что в итоге сказывается на других безобидных пользователей, которым нужно работать. В такой ситуации, одни смотрят фильмы, а другие страдают. У страдальцев попросту перестают открываться сайты, возникают проблемы с получением/отправкой электронной почты. Когда другие юзеры смотрят очередной турецкий сериал, хорошо проводя время на работе. Мы должны понимать что такое может произойти, заведомо включая шейпер трафика на шлюзе. Желательно эту операцию проводить до ввода в эксплуатацию шлюза, чтобы не слышать лишних слов со стороны пользователей.

Чтобы не происходило полного забивания канала одним или более участниками, его делят по частям между компьютерами локальной сети, давая каждому ПК кусочик от общего канала. Возможен и другой сценарий, как вариант можно лимитировать снижать скорость всех портов за исключением Web (80) и SMTP/POP3 (25,110), что даст нам шустрого открытия веб страниц и без проблемной работы электронной почты.

Инструмент по управлению пропускной способностью канала называют - шейпер трафика. Актуальность шейпера особенно велика при использовании низко скоростного интернета. В сети на одном форуме есть пример, когда организация имеет интернет канал на скорости - 4Мбит, при этом количество пользователей 500 человек (завод). И вот эти 500 человек большого завода,  умудряются более менее сидеть в Интернете при помощи шейпера на малюсеньком интернете! Теперь представьте какую большую роль играет шейпер трафика в каждой сети, это один из важных элементов шлюза.

Обычно в локальной сети офиса интернет канал просаживается из за следующего:

1. Онлайн видео - сюда можно отнести интернет кинотеатры и youtube

2. Торрент закачки с большим количеством соединений

3. Файлообменники

 

Хотя на самом деле можно загрузить канал чем угодно, используя нестандартные порты/протоколы, чтобы бороться с этим, приходиться обычно ставить отдельное правило для такого трафика. Вообще, тема "нарезки" трафика очень большая и по ней много документации. В силу своих малых познаний, попытаюсь описать уже опубликованные примеры по распределению трафика применительно к шлюзу (прокси серверу). Пишу для себя, но конструктивная критика не помешает :)

Записку буду корректировать и возможно добавлять новые настройки контроля трафика.

 

Краткое содержание записки:

 

1. Проверка скорости через утилиту speedtest-cli

2. Пример с использованием скрипта CBQ.Init для шлюза

3. Пример с использованием скрипта HTB.INIT для шлюза

4. Пример с использованием скрипта Wondershaper для одиночного Linux компьютера с одной сетевой платой

5. Пример с использованием виртуального интерфейса ifb и дисциплины htb для одиночного ПК

6. Пример с использованием дисциплины HTB и виртуального интерфейса IFB для шлюза

7. Пример с использованием маркировки трафика в iptables

8. Пример простого шейпера для шлюза

9. Пример простого шейпера на Shaper Control Tool

10. Дополнительные команды tc

11. Алгоритм составления правил для нарезки канала

 

Скрипты облегчающие составления правил ограничения трафика:

  • cbq.init - скрипт для составления правил ограничения трафика на основе tc и cbq.
  • htb.init - скрипт для составления правил ограничения трафика на основе tc и htb.
  • wondershaper - аналогичный скрипт как и cbq.init, но только для одиночного Linux ПК.

Чтобы продемонстрировать как работает шейпер, возьмем типичную задачу когда у системного администратора есть компьютер с двумя сетевыми картами, который выступает в роли шлюза. А также, будут показаны примеры контроля скорости трафика на одиночном компьютере Linux.

Сперва начнем со скриптов, так как именно они помогают быстро настроить контроль трафика на Linux машине даже не зная основ.

Основная цель: Ограничить полосу пропускания трафика локальной сети в Интернет. Разделить канал поровну между компьютерами, чтобы каждый мог комфортно выходить в глобальную сеть. Трафик компьютеров локальной сети будет идти через шлюз на котором будут прописаны правила нарезки канала.

 

А вот более наглядная схема:

 

Здесь из рисунка видно, что мы можем контролировать только исходящий трафик с физического интерфейса. Исходящий трафик с внутренней сетевой платы enp0s8 будет входящим для компьютеров локальной сети. И наоборот, исходящий трафик с внешнего адаптера enp0s3 - будет исходящим для компьютеров локальной сети за шлюзом. Так как шлюз имеет две сетевые карты, нам доступен контроль как входящего, так и исходящего трафика. Обычно с помощью шейпера можно контролировать скорость только исходящего трафика. Если у вас всего один компьютер на Linux, вы можете ограничивать канал через скрипт Wondershaper или свой ручной скрипт в котором используется виртуальный интерфейс ifb (imq).

Для замера скорости интернета был использован сайт speedtest.com. Сайт speedtest.com использовался для замера скорость интернета на компьютере за шлюзом. Исходящий трафик со шлюза до компьютера замерялся с помощью программы fastcopy. Можно была использовать утилиту iperf - да, она хороша, но для наглядности выше описанный сайт и fastcopy - подходят лучше, так как есть графические скрины (имхо). Для замера скорости одиночного Linux ПК использовалась утилита speedtest-cli, внизу написана инструкция по ее установке.

Если в правилах шейпера пишется kbps - значить это килобайты, если видите kbit - значить это килобиты.

1. Проверка скорости через утилиту speedtest-cli

Есть очень замечательный скрипт написанный на Phyton от популярного сайта www.speedtest.net

С помощью него замер скорости делается за 5 секунд, измеряется скорость входящего и исходящего потока.

Установка скрипта:

# wget https://raw.github.com/sivel/speedtest-cli/master/speedtest_cli.py

# chmod a+rx speedtest_cli.py

# mv speedtest_cli.py /usr/local/bin/speedtest-cli

# chown root:root /usr/local/bin/speedtest-cli

Запуск скрипта:

# speedtest-cli

Полученная информация:

 

2. Пример с использованием скрипта CBQ.Init для шлюза

 

Шейпер трафика:                    скрипт cbq.init

Входящий трафик, скорость:   5Мбит

Исходящий трафик, скорость: 5Мбит

Названия сетевых адаптеров: enp0s3 - внешний, enp0s8 - внутренний

 

Допустим шлюз имеет скорости интернет 5-мбит на входящий поток и 5 мбит исходящий.  Как обычно сервер в роли шлюза должен иметь два интерфейса, первый enp0s3 - внешний и enp0s8 - внутренний. В этом случае компьютеры локальной сети получают интернет по технологии NAT. Входящий  и исходящий трафик лимитируем через через скрипт CBQ.init, в CentOS он просто называется коротко "cbq", как и дисциплина cbq. Не путайте дисциплину cbq и скрипт cbq.init. Скрипт cbq.init создает правила шейпирования трафика на основе дисциплины cbq.

Создадим 3 файла в каталоге /etc/sysconfig/cbq:

- cbq-5000.internet-out

- cbq-5000.internet-in

- cbq-40.router_to_network

 

Сперва лимитируем исходящий трафик в Интернет

Про маркируем исходящий трафик через iptables, чтобы потом им управлять через cbq:

iptables -t mangle -A PREROUTING -s 10.168.50.0.0/24 -j MARK --set-mark 6

Заходим в каталог где должны быть файлы описывающие скорость:

# cd /etc/sysconfig/cbq

Создаем файл cbq-5000.internet-out:

# vi cbq-5000.internet-out

# Исходящая скорость в Интернет - скорость 5 Мбит

DEVICE=enp0s3,100Mbit,10Mbit

RATE=5Mbit

WEIGHT=500Kbit

LEAF=sfq

PRIO=6

MARK=6

RULE=10.168.50.0/24,

Теперь пришла очередь входящего трафика

Создаем файл cbq-9.router_to_network:

# vi cbq-9.router_to_network

# Входящая скорость для локальной сети 40 Мбит

DEVICE=enp0s8

RATE=40Mbit

WEIGHT=5Mbit

LEAF=sfq

PRIO=8

RULE=10.168.50.2,

Создаем файл cbq-900.internet-in:

# vi cbq-900.internet-in

# Входящая скорость Интернета для локальной сети 5 Мбит

DEVICE=enp0s8,100Mbit,90Mbit

RATE=5Mbit

WEIGHT=800Kbit

LEAF=sfq

PRIO=1

RULE=10.168.50.0/24

 

Замеряем скорость, качаем файл с сервера локальной сети из любого компьютера:

Видим что здесь есть наши 40 Мбит.

Проверяем входящею и исходящею скорость в Интернет:

Замеряем скорость интернета с машины локальной сети, как видим входящая/исходящая скорость в 5 Мбит.

Ставим шейпер в автозагрузку, добавляем строку:

# vi /etc/rc.d/rc.local

/usr/sbin/cbq start

 

3. Пример с использованием скрипта HTB.INIT для шлюза

 

Шейпер трафика:                    скрипт htb.init

Входящий трафик, скорость:   8Мбит

Исходящий трафик, скорость: 1Мбит

Названия сетевых адаптеров: enp0s3 - внешний, enp0s8 - внутренний

Входящая и исходящая скорость для клиентов локальной сети, будет регулироваться настройками "HTB.init" скрипта для адаптера локальной сети, а исходящая скорость будет зависеть от настроек внешнего адаптера шлюза.

Интернет в данном примере будет поступать от ADSL модема, в котором скорость исходящего трафика меньше входящего.

Задача шейпера: разделение входящей и исходящей скорости канала поровну между машинами локальной сети

Установим зависимость:

# yum install iproute -y

Скачайте скрипт htb.init с сайта sourceforge.

# wget http://sourceforge.net/projects/htbinit/files/HTB.init/0.8.5/htb.init-v0.8.5/download -O htb.init-v0.8.5

# mv htb.init-v0.8.5 /etc/init.d/htb

# chmod 755 /etc/init.d/htb

Поставьте его в автозагрузку:

# chkconfig htb on

Создайте каталог для конфигурации:

# mkdir -p /etc/sysconfig/htb

Перейдите в каталог конфигурации htb.init:

# cd /etc/sysconfig/htb

Сперва настроим входящею скорость для компьютеров локальной сети - трогаем настройки внутреннего адаптера enp0s8.

Создадим корневой  файл enp0s8:

# vi enp0s8

В нем впишем текст:

DEFAULT=20

Здесь строчка DEFAULT=20 задает параметр по которому будет учитываться трафик не попадающий ни под одно правило шейпера.

# vi enp0s8-2.root

Впишем в него:

RATE=100Mbit

Здесь мы указали скорость нашего адаптера локальной сети.

# vi enp0s8-2:20.default

RATE=92Mbit

PRIO=5

LEAF=sfq

# vi enp0s8-2:4.from_router_to_network

RATE=99Mbit

PRIO=4

LEAF=sfq

RULE=10.168.50.0/24,

Здесь запятая говорит нам, что нужно шейпить исходящею скорость (исходящий порт). Без запятой, шейпится входящая скорость.

# vi enp0s8-2:5.to_network

RATE=8Mbit

PRIO=5

# vi enp0s8-2:5:1025

CEIL=8Mbit

RATE=2Mbit

PRIO=5

LEAF=sfq

RULE=10.168.50.0/24

ИТОГО: Входящая скорость 8Мбит будет распределятся поровну между компьютерами локальной сети 10.168.50.0/24. Если канал не занят, одному компьютеру дается 8Мбит во время закачки, в противном случае скорость делится между качающимися.

Скриншот c сайта speedtest.net, тест запускался на машине c Windows XP в локальной сети:

Как видно из картинки, скорость почти соответствует нашим настройкам.

Теперь скрин из Download Master:

Здесь у нас почти 8Мбит = 940Кбайт

Теперь надо порезать исходящею скорость

Создадим корневой  файл enp0s3:

# vi enp0s3

В нем впишем текст:

DEFAULT=20

# vi enp0s3-2.root

RATE=1Mbit

# vi enp0s3-2:20.default

CEIL=1Mbit

RATE=1Mbit

PRIO=5

LEAF=sfq

ИТОГО: Мы дали компьютерам локальной сети 10.168.50.0/24 исходящею скорость в 1Мбит, скорость эта делиться поровну между компьютерами локальной сети, если качает только один ПК, ему дается весь 1Мбит.

Как видно из скриншота, исходящий трафик всего 0,96 Мбит. Как мы и задали!

При этом мы не трогаем входящею и исходящею скорость самого интернет шлюза в локальную сеть и обратно. Смысла резать локальную скорость - нет.

Последний шаг - запуск системы контроля трафика с помощью следующей команды:

# service htb compile

# service htb start

При запуске скрипта HTB.init выйдет окошко с ошибкой:

find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it).  Please specify options before other arguments.

Так как ошибка не критичная, и не влияет на работу скрипт, на нее можно не обращать внимания.

Если вы еще не поставили демон в автозагрузку:

# chkconfig htb on

Иногда нужно чистить кэш HTB.Init:

# rm /var/cache/htb.init

4. Пример с использованием скрипта Wondershaper для одиночного Linux компьютера с одной сетевой платой

 

Шейпер трафика:                    скрипт wondershaper

Входящий трафик, скорость:   5Мбит

Исходящий трафик, скорость: 10Мбит

Названия сетевых адаптеров: enp0s3 - один внешний

Скрипт wondershaper использует дисциплину CBQ для ограничения скорости.

Устанавливаем wondershaper:

# yum install wondershaper -y

Синтаксис скрипта шейпера:

wondershaper [интерфейс] [download, kbits] [upload, kbits]

Например:

wondershaper enp0s3 50000 10000 - здесь 5Мбит входящая скорость и 1Мбит исходящая скорость

Проверка через wget - закачка ISO образа.

Здесь из скриншота видно, что входящая скорость равна 417Кбайтам, то есть наши 5Мбит.

Скрипт работает очень странно, смотрите скриншоты внизу:

3 mb_out / 5 mb_in

3 mb_out / 8 mb_in

4 mb_out / 8 mb_in

Дополнительные команды:

wondershaper [интерфейс] - показывает состояние шейпера для интерфейса

wondershaper [clear] - стирает правила которые были заданы

Сам скрипт находиться здесь /sbin/wondershaper

5. Пример с использованием виртуального интерфейса ifb и дисциплины htb для одиночного ПК

 

Шейпер трафика:                    ручной скрипт

Входящий трафик, скорость:   8Мбит

Исходящий трафик, скорость: 4Мбит

Названия сетевых адаптеров: enp0s3 - один внешний

 

Создаем простой скрипт /etc/sysconfig/shaper.sh

# vi /etc/sysconfig/shaper.sh

### Скорость входящего трафика ###

# Активируем виртуальный интерфейс ifb0 и перенаправляем входящий трафик с адаптера enp0s3 на активированный интерфейс ifb0

# Здесь egress - означает входящий трафик, соответственно ingress - исходящий трафик

modprobe ifb

ip link set ifb0 up

# Удаляем правила

tc qdisc del dev enp0s3 root 2> /dev/null > /dev/null

tc qdisc del dev enp0s3 ingress 2> /dev/null > /dev/null

tc qdisc del dev ifb0 root 2> /dev/null > /dev/null

tc qdisc del dev ifb0 ingress 2> /dev/null > /dev/null

#Перенаправляем трафик на виртуальный интерфейс

tc qdisc add dev enp0s3 handle ffff: ingress

tc filter add dev enp0s3 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0

# Указываем использование дисциплины HTB на виртуальном интерфейсе ifb0 и дефолтный класс 11,

# куда будет попадать трафик не подходящий ни под одно правило шейпера

tc qdisc add dev ifb0 root handle 1:0 htb default 11

# Указываем гарантированную полосу пропускания (rate) и максимально возможную скорость (ceil) - корневой класс 1:1

tc class add dev ifb0 parent 1:0 classid 1:1 htb rate 1024kbps

# Указываем rate - 30Kbyte/s и ceil - 300Kbyte/s для очереди по умолчанию 1:11, имеющей меньший приоритет (5)

tc class add dev ifb0 parent 1:1 classid 1:11 htb rate 30kbps ceil 300kbps prio 5

tc qdisc add dev ifb0 parent 1:11 handle 11: sfq perturb 10

# Указываем rate 100Kbyte/s и ceil 1000Kbyte/s для очереди 1:10, имеющей наивысший приоритет (0)

tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 100kbps ceil 1024kbps prio 0

tc qdisc add dev ifb0 parent 1:10 handle 10: sfq perturb 10

# Фильтруем в очередь 1:10 ssh и www трафик

tc filter add dev ifb0 parent 1:0 protocol ip prio 0 u32 match ip sport 22 0xffff flowid 1:10

tc filter add dev ifb0 parent 1:0 protocol ip prio 0 u32 match ip sport 80 0xffff flowid 1:10

### Скорость исходящего трафика ###

# Указание к использованию дисциплины очереди HTB на интерфейсе, класс 11 - класс по умолчанию

tc qdisc add dev enp0s3 root handle 1:0 htb default 20

# Указание ширины гарантированной полосы (rate) - 512Kbyte/s и максимально возможной (ceil) - 512Kbyte/s для корневого класса 1:1

tc class add dev enp0s3 parent 1:0 classid 1:1 htb rate 512kbps ceil 512kbps

# Указание rate - 64Kbyte/s и ceil 512Kbyte/s для очереди 1:10, имеющей наивысший приоритет (0)

tc class add dev enp0s3 parent 1:1 classid 1:10 htb rate 64kbps ceil 512kbps prio 1

tc qdisc add dev enp0s3 parent 1:10 handle 10: sfq perturb 10

# Указание rate - 512Kbyte/s и ceil - 1Kbyte/s для очереди 1:11, используемой по умолчанию и имеющей меньший приоритет (5)

tc class add dev enp0s3 parent 1:1 classid 1:20 htb rate 1kbps ceil 512kbps prio 5

tc qdisc add dev enp0s3 parent 1:20 handle 20: sfq perturb 10

# Фильтруем очередь 1:10, трафик ssh и www

tc filter add dev enp0s3 parent 1:1 protocol ip prio 0 u32 match ip dport 22 0xffff flowid 1:10

tc filter add dev enp0s3 parent 1:1 protocol ip prio 0 u32 match ip dport 80 0xffff flowid 1:10

Даем права на запуск скрипта:

# chmod +x /etc/sysconfig/shaper.sh

Запускаем скрипт:

# /etc/sysconfig/shaper.sh

И замеряем скорость:

# speedtest-cli

Здесь видно, что трафик 8Мбит на вход и 4Мбит на выходе.

 

6. Пример с использованием дисциплины HTB и виртуального интерфейса IFB для шлюза

 

Шейпер трафика:                    ручной скрипт

Входящий трафик, скорость:   4Мбит

Исходящий трафик, скорость: 512Кбит

Названия сетевых адаптеров: enp0s3 - один внешний, enp0s8 - внутренний

Этот пример хорош когда у вас подключено два и более провайдеров. Виртуальный интерфейс ifb, поможет лимитировать исходящий трафик.

Регулируем скорость входящего и исходящего трафика через виртуальный сетевой адаптер ifb0

Создаем файл скрипт для ограничения входящего и исходящего трафика:

# vi /etc/sysconfig/out_shaper.sh

# Исходящий трафик 512Кбит локальной сети 10.168.50.0/24

tc qdisc del dev enp0s8 root 2> /dev/null > /dev/null

tc qdisc del dev enp0s8 ingress 2> /dev/null > /dev/null

tc qdisc del dev ifb0 root 2> /dev/null > /dev/null

tc qdisc del dev ifb0 ingress 2> /dev/null > /dev/null

tc qdisc del dev enp0s3 root 2> /dev/null > /dev/null

tc qdisc del dev enp0s3 ingress 2> /dev/null > /dev/null

# Скорость исходящего трафика 512Кбит/s для локальной сети 10.168.50.0/24

modprobe ifb

ip link set dev ifb0 up

tc qdisc add dev enp0s8 ingress

tc filter add dev enp0s8 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0

tc qdisc add dev ifb0 root handle 1: htb default 20

tc class add dev ifb0 parent 1: classid 1:1 htb rate 1024kbit

tc class add dev ifb0 parent 1:1 classid 1:100 htb rate 512Kbit ceil 512Kbit prio 2 quantum 15365

tc qdisc add dev ifb0 parent 1:100 handle 100: sfq perturb 10

tc filter add dev ifb0 protocol ip prio 2 u32 ht 800:: match ip src 10.168.50.0/24 flowid 1:100

tc class add dev ifb0 parent 1:1 classid 1:200 htb rate 512kbit ceil 512kbit prio 2 quantum 15365

tc qdisc add dev ifb0 parent 1:200 handle 200: sfq perturb 10

tc filter add dev ifb0 protocol ip prio 2 u32 ht 800:: match ip src 10.168.50.0/24 flowid 1:200

tc class add dev ifb0 parent 1:1 classid 1:20 htb rate 32kbit ceil 32kbit prio 2 quantum 15365

tc qdisc add dev ifb0 parent 1:20 handle 20: sfq perturb 10

# Скорость входящего трафика для локальной сети 4Мбит/s для локальной сети 10.168.50.0/24

tc qdisc add dev enp0s8 root handle 2: htb default 30

tc class add dev enp0s8 parent 2: classid 2:1 htb rate 5Mbit burst 15k

# PRIO 1 -> tcp sport 80 – WWW трафик из мира

tc class add dev enp0s8 parent 2:1 classid 2:101 htb rate 33kbit ceil 4Mbit prio 1

# PRIO 3 -> unclassified traffic – трафик, который не попал под условия, указанные в предыдущих классах

tc class add dev enp0s8 parent 2:1 classid 2:102 htb rate 33kbit ceil 4Mbit prio 3

# u32 классификаторы

tc filter add dev enp0s8 protocol ip parent 2:0 prio 1 u32 match ip dst 10.168.50.0/24 match ip protocol 6 0xff match ip sport 80 0xffff flowid 2:101

tc filter add dev enp0s8 protocol ip parent 2:0 prio 2 u32 match ip dst 10.168.50.0/24 flowid 1:102

# chmod 750 /etc/sysconfig/out_shaper.sh

Здесь мы дали 4Мбит/с входящего трафика и 512Кбит исходящего трафика для локальной сети 10.168.50.2/255.255.255.0

Чтобы запуск скрипта был при загрузке, поместите его в rc.local

# vi /etc/rc.local

/etc/sysconfig/out_shaper.sh

Скрин замера скорости с клиента Windows XP за шлюзом:

7. Пример с использованием маркировки трафика в iptables

Шейпер трафика:                    ручной скрипт htb/iptables

Входящий трафик, скорость:   1Мбит

Исходящий трафик, скорость: 3Мбит

Названия сетевых адаптеров: enp0s3 - внешний , enp0s8 - внутренний

Устанавливаем пакет iproute2:

# yum install iproute2

Создаем файл скрипт /etc/sysconfig/shaper.sh:

#!/bin/bash

start() {

DOWN=enp0s8

UP=enp0s3

# UPLOAD  - создаем корневую дисциплину HTB для интерфейса enp0s3

tc qdisc del dev $UP root 2> /dev/null > /dev/null

tc qdisc del dev $UP ingress 2> /dev/null > /dev/null

tc qdisc add dev $UP root handle 1:0 htb default 10

tc class add dev $UP parent 1:0 classid 1:1 htb rate 1000mbit

# Создание классов для соответствующих протоколов

# default 10

tc class add dev $UP parent 1:1 classid 1:10 htb rate 2mbit ceil 3000kbit prio 0

# ICMP

tc class add dev $UP parent 1:1 classid 1:20 htb rate 4mbit ceil 7mbit prio 0

# HTTP/s TCP

tc class add dev $UP parent 1:1 classid 1:21 htb rate 2mbit ceil 3mbit prio 0

# HTTP/s UDP

tc class add dev $UP parent 1:1 classid 1:22 htb rate 800kbit ceil 1mbit prio 0

# POP / SMTP TCP

tc class add dev $UP parent 1:1 classid 1:23 htb rate 800kbit ceil 1mbit prio 0

# DNS

tc class add dev $UP parent 1:1 classid 1:24 htb rate 800kbit ceil 1mbit prio 0

# SSH

tc class add dev $UP parent 1:1 classid 1:25 htb rate 800kbit ceil 1mbit prio 0

# DOWNLOAD (Закачка) -  используется для загрузки

tc qdisc del dev $DOWN root 2> /dev/null > /dev/null

tc qdisc del dev $DOWN ingress 2> /dev/null > /dev/null

tc qdisc add dev $DOWN root handle 1:0 htb default 10

tc class add dev $DOWN parent 1:0 classid 1:1 htb rate 1000mbit

# Создание классов для соответствующих протоколов

# default 10

tc class add dev $DOWN parent 1:1 classid 1:10 htb rate 700kbit ceil 1000kbit prio 0

# ICMP

tc class add dev $DOWN parent 1:1 classid 1:20 htb rate 4mbit ceil 7mbit prio 0

# HTTP/s TCP

tc class add dev $DOWN parent 1:1 classid 1:21 htb rate 2mbit ceil 3mbit prio 0

# HTTP/s UDP

tc class add dev $DOWN parent 1:1 classid 1:22 htb rate 800kbit ceil 1mbit prio 0

# POP / SMTP TCP

tc class add dev $DOWN parent 1:1 classid 1:23 htb rate 800kbit ceil 1mbit prio 0

# DNS

tc class add dev $DOWN parent 1:1 classid 1:24 htb rate 800kbit ceil 1mbit prio 0

# SSH

tc class add dev $DOWN parent 1:1 classid 1:25 htb rate 800kbit ceil 1mbit prio 0

################################################################

iptables -t mangle -F FORWARD

# UPLOAD управление - Сортировка пакетов для своих классах .

iptables -t mangle -A FORWARD -o $UP -p icmp -j CLASSIFY --set-class 1:20

iptables -t mangle -A FORWARD -o $UP -p tcp -m multiport --sports 80,443 -j CLASSIFY --set-class 1:21

iptables -t mangle -A FORWARD -o $UP -p udp -m multiport --sports 80,443 -j CLASSIFY --set-class 1:22

iptables -t mangle -A FORWARD -o $UP -p tcp -m multiport --sports 465,25,110 -j CLASSIFY --set-class 1:23

iptables -t mangle -A FORWARD -o $UP -p udp -m multiport --sports 53,953 -j CLASSIFY --set-class 1:24

iptables -t mangle -A FORWARD -o $UP -p tcp -m multiport --sports 22 -j CLASSIFY --set-class 1:25

# DOWNLOAD управление

iptables -t mangle -A FORWARD -o $DOWN -p icmp -j CLASSIFY --set-class 1:20

iptables -t mangle -A FORWARD -o $DOWN -p tcp -m multiport --dports 80,443 -j CLASSIFY --set-class 1:21

iptables -t mangle -A FORWARD -o $DOWN -p udp -m multiport --dports 80,443 -j CLASSIFY --set-class 1:22

iptables -t mangle -A FORWARD -o $DOWN -p tcp -m multiport --dports 465,25,110 -j CLASSIFY --set-class 1:23

iptables -t mangle -A FORWARD -o $DOWN -p udp -m multiport --dports 53,953 -j CLASSIFY --set-class 1:24

iptables -t mangle -A FORWARD -o $DOWN -p tcp -m multiport --dports 22 -j CLASSIFY --set-class 1:25

#конец начала функции

}

stop() {

DOWN=enp0s8

UP=enp0s3

# Очистка правил контроля трафика

tc qdisc del dev $UP root

tc qdisc del dev $DOWN root

iptables -t mangle -F FORWARD

}

case $1 in

start) start;

;;

stop) stop;

;;

restart)start ; stop ;

;;

*) echo "Enter command: [start|stop|restart]";

;;

esac

 

Запуск скрипта:

# chmod +x /etc/sysconfig/shaper.sh

# ./etc/sysconfig/shaper.sh start

Вот скрин замера скорсти с компьютера на Windows XP который находится в локальной сети:

8. Пример простого шейпера для шлюза

Шейпер трафика:                    ручной скрипт

Входящий трафик, скорость:   Указывается как параметр скрипта

Исходящий трафик, скорость: Указывается как параметр скрипта

Названия сетевых адаптеров: enp0s8 - внутренний

Создаем простой скрипт:

# vi /sbin/shaper.sh

Cо следующим содержимым:

#!/bin/bash

speedUp=$1

speedDown=$2

# Удаление очередей

/sbin/tc qdisc del dev enp0s8 ingress

/sbin/tc qdisc del dev enp0s8 root handle 1:

# Ограничение скорости отдачи

/sbin/tc qdisc add dev enp0s8 root handle 1: htb default 10 r2q 1

/sbin/tc class add dev enp0s8 parent 1: classid 1:10 htb rate ${speedUp}kbit quantum 8000 burst 8k

# Ограничение скорости загрузки

/sbin/tc qdisc add dev enp0s8 handle ffff: ingress

/sbin/tc filter add dev enp0s8 parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate ${speedDown}kbit burst 12k drop flowid :1

Запуск скрипта:

# /sbin/shaper.sh 5000 1000

В примере скорость скачивания лимитируется до 1000 кбит/с, а исходящего скорость трафика - до 5000 кбит/с

9. Пример простого шейпера на Shaper Control Tool

Шейпер трафика:                    ручной скрипт

Входящий трафик, скорость:   Указывается как параметр скрипта

Исходящий трафик, скорость: Указывается как параметр скрипта

Названия сетевых адаптеров: eth0 - внешний, eth2 - внутрений

Устанавливаем SC (Shaper Control Tool)

Если у вас CentOS 6:

# rpm -Uvh http://rnd.rajven.net/centos/6.5/os/i386/files-repo-1.3-2.cnt6.noarch.rpm

# yum install sc -y

Если CentOS 7:

# yum install bzip2 iproute -y

# wget http://netassist.dl.sourceforge.net/project/sc-tool/sc-tool/sc-1.5.7.tar.bz2

# tar -xvf sc-1.5.7.tar.bz2

# cd sc-1.5.7

# make

Поправим файл /etc/sc/sc.conf чтобы он принял следующий вид:

tc = /sbin/tc

out_if = eth0

in_if = eth2

filter_method = u32

limit_method = hybrid

debug = 0

verbose = 0

quiet = 0

colored = 1

joint = 0

network = 10.0.0.0/24

filter_network = 10.0.0.0/24

policer_burst_ratio = 0.3

quantum = 1500

rate_unit = kibit

rate_ratio = 1.0

leaf_qdisc = 'pfifo limit 50'

db_driver = SQLite

db_host = 127.0.0.1

db_name = /etc/sc/sc.db

db_user = username

db_pass = password

query_create = "CREATE TABLE rates (ip UNSIGNED INTEGER PRIMARY KEY, rate UNSIGNED INTEGER NOT NULL)"

query_load = "SELECT ip,rate FROM rates"

query_list = "SELECT ip,rate FROM rates WHERE ip=?"

query_add = "INSERT OR REPLACE INTO rates VALUES (?, ?)"

query_del = "DELETE FROM rates WHERE ip=?"

query_change = "REPLACE INTO rates VALUES (?, ?)"

syslog = 0

 

Инициализируем

# sc init

Создадим файл БД

# sc dbcreate

Добавим в него запись для IP нашего сервера

# sc dbadd 10.0.0.1 100Mbit

Добавим запись для тестового клиента допустим 10.0.0.2

# sc dbadd 10.0.0.1 1Mbit

Синхронизируем правила с БД

# sc sync

Собственно на этом вся настройка заканчивается.

Добавление нового клиента заключается в добавлении записи в БД + синхронизации правил с помощью sc sync

Для того чтобы правила стартовали после перезагрузки сервера необходимо внести sc в автозапуск

# chkconfig --add sc

# chkconfig --level 3 sc on

 

10. Дополнительные команды tc

При контроле трафика в Linux, используются следующие инструменты:

  • tc - утилита для контроля трафика tc (Traffic Control) через ядро Linux. Она идет в наборе программ пакета iproute2. Эта программа - сердце управления трафиком, с помощью нее производятся операции по лимитированию трафика.
  • imq - псевдо-интерфейс (виртуальная сетевая плата), специальное устройство к которому цепляются дисциплины управления очередью, такие как htb, cbq и tbf. Для его работы нужно патчить ядро. На данный момент устарел и не используется, так как есть аналог ifb.
  • ifb - это тоже виртуальное устройство как и imq
  • htb -  дисциплина управления очередью которая на данный момент широко используется всеми.
  • cbq -  дисциплина управления очередью
  • tbf - дисциплина управления очередью
  • red - дисциплина управления очередью
  • sfq - очередь равномерного случайного распределения пакетов
 

* Показать правила для интерфейса eth0:

tc -s qdisc show dev eth0;

 

* Отчистить правила для интерфейса eth0:

tc qdisc del dev eth0 root 2> /dev/null > /dev/null

tc qdisc del dev eth0 ingress 2> /dev/null > /dev/null

 

11. Алгоритм составления правил для нарезки канала

Правила для фильтрации (нарезки) составляются по следующей последовательности

1. Создаем корневую дисциплину для интерфейса и указываем класс куда будет попадать не классифицированный трафик -

tc qdisc add dev eth0 root handle 1:0 htb default 10

2. Создаем корневой (иерархию классов) класс  и определяем ширину канала -

tc class add dev eth0 parent 1:0 classid 1:1 htb rate 1000mbit

3. Создаем дочерний класс для шейпирования абонента.

tc class add dev eth0 parent 1:0 classid 1:1 htb rate 1000mbit

4. Создаем дисциплину шейпирования для класса абонента.

tc class add dev eth0 parent 1:1 classid 1:21 htb rate 2mbit ceil 3mbit prio 0

5. Создаем фильтра позволяющие классифицировать трафик абонента, например через iptables:

iptables -t mangle -A FORWARD -o eth0 -p tcp -m multiport --sports 80,443 -j CLASSIFY --set-class 1:21

или так для www трафика:

tc filter add dev eth0 parent 1:0 protocol ip prio 0 u32 match ip sport 80 0xffff flowid 1:10

или как вариант:

tc filter add dev ifb0 protocol ip prio 2 u32 ht 800:: match ip src 10.168.50.0/24 flowid 1:100

 

Полезные ссылки:

 

1. http://docstore.mik.ua/manuals/ru/adv_route_qos/index.html

2. http://www.opennet.ru/base/net/linux_traffic_qos.txt.html

3. http://www.opennet.ru/base/net/htb_manual.txt.html

4. http://unixforum.org/index.php?showtopic=123039

5. http://unixforum.org/index.php?showtopic=120023&st=0&p=1117510&#entry1117510

6. http://habrahabr.ru/post/119611/

7. http://asmodeus.com.ua/library/os/linux/shaper_tc.html

8. http://zooom.com.ua/linux/ustanovka-i-nastrojka/154--linux.html

9. LARTC в fb2 формате - http://coollib.com/b/106373

yvision.kz

Шейпер для ОС Windows

В последнее время проблема стоимости трафика отходит на второй план, а вот проблемы со скоростью передачи данных через Интернет остаются. Какой бы широкий не был канал, один пользователь, закачивая большой файл, может занять его весь. Так, если одни пользователи скачивают большие объемы информации, то они могут существенно ограничить скорость другим пользователям. Для решения этой проблемы необходимо распределять Интернет канал между пользователями в соответствии с их потребностями.

Существует несколько решений этой проблемы. Но на практике оказывается что они: либо дорогие, либо их сложно применять, либо лишь частично решают проблему. Имеются хорошие решения для распределения канала на базе Unix систем. Но эти решения требуют наличия совместимой аппаратной части и содержание в штате администратора этой системы. Аппаратные решения, как, например, сетевой роутер, которые позволяют управлять трафиком, как правило, дорогостоящие, и их настройка также может стать нетривиальной задачей.

Некоторые производители ПО заявляют, что имеют в своем продукте модули управления загрузкой канала, но на практике оказывается, что эта возможность реализована не полностью, например, с помощью proxy-сервера. Такое решение существенно ограничивает возможности, так как многие сетевые приложения не поддерживают непрямой тип подключения и производительность proxy гораздо ниже, чем сетевого драйвера работающего на уровне ядра ОС.

В идеале необходимо динамическое распределение канала с возможностью указать приоритеты для разных классов трафика и, собственно, определения классов трафика для разделения: по пользователям, протоколам, компьютерам. Например, руководителю организации постоянно необходима высокая скорость доступа в Интернет. Ему устанавливается самый высокий приоритет. Для трафика класса с более высоким приоритетом, система динамически выделит больший канал, по сравнению с остальным трафиком с приоритетом ниже. Или другой пример. Нужно иметь возможность выделить приоритет почтовым сервисам над остальным трафиком, обеспечив хорошую скорость и бесперебойный доступ к почте. Или, если в интернет одновременно выходят несколько пользователей, распределить скорость поровну, либо по индивидуальным настройкам для каждого пользователя. При этом, нужно чтобы распределение было бы динамическим, то есть если один из пользователей не использует Интернет, другой мог бы занять освободившийся канал. Немало важно, чтобы вся настройка системы не занимала много времени, была простой и удобной.

Интересное решение предлагает компания ООО «Нетсиб» - Lan2net Traffic Shaper. Можно сказать, что это клон Shaper, встроенного в ядро Unix систем, только под ОС Windows. В нем реализованы те же алгоритмы (регуляторы HTB, TBF, DRR), а настройка Lan2net Traffic Shaper окажется не сложной даже для администратора небольшого офиса.

Lan2net Traffic Shaper разделяет весь трафик на классы, и к каждому классу можно применить индивидуальные настройки, в зависимости от потребностей пользователей. Если в этом потребности нет, то можно просто ограничить скорость передачи всего трафика.

Рассмотрим работу Lan2net Traffic Shaper на простом примере. Например, у вас есть три компьютера, которым нужно разделить поровну канал в 1 Мбайт/сек. Для этого открываем панель управления Lan2net Traffic Shaper, на вкладке «Классы» выбираем адаптер, к которому подключены эти компьютеры. Предварительно убедившись, что у этого адаптера стоит регулятор HTB, добавляем дочерний класс, выбирая соответствующий пункт в контекстном меню.

В появившемся окне мастера создания класса на первой странице вводим имя класса и нажатием кнопки «Далее» переходим на следующую страницу. На этой странице вводим параметры родительского класса HTB. В поля «Гарантированная скорость» и «Максимальная скорость» вводим значение ширины канала. При этом рекомендуется задавать значение немного ниже максимальной ширины канала для более эффективного регулирования. На этом этапе мы создали класс, у которого будут «занимать» трафик дочерние классы в меру необходимости. Теперь подобным образом нужно создать непосредственно классы для компьютеров. Максимальную скорость указываем такую же, как в родительском классе. Гарантированную скорость указываем меньше. При этом для правильной настройки, желательно, чтобы сумма гарантированных скоростей дочерних классов равнялась максимальной скорости родительского класса. В качестве источников у создаваемых дочерних классов указываем соответствующие объекты-компьютеры. В результате получилось дерево классов, как на скриншоте.

Теперь, если мы будем качать большой файл на Компьютере 1, а остальные будут неактивны, скорость скачивания на Компьютере 1 получится 990 Кб/сек. При подключении другого компьютера скорость скачивания на Компьютере 1 снизится, но будет больше или равна 300 Кб/сек. Если все три компьютера будут пытаться захватить максимум ширины канала, тогда их скорости будут равны 300 Кб/сек, для Компьютера 1, 300 Кб/сек для Компьютера 2 и 390 Кб/сек для Компьютера 3. Если только два компьютера будут активны, тогда канал будет делится поровну (т.к. приоритет для всех классов в нашем примере одинаковый), т.е. примерно по 0.5 Мбайт/сек. Естественно, программа позволяет создавать более сложные конфигурации. С помощью Lan2net Traffic Shaper, можно устанавливать приоритеты, распределять скорость входящего и исходящего трафика для отдельных протоколов, IP адресов или подсетей.

Грамотное распределение ширины канала, полученного от провайдера, позволяет улучшить качество обслуживания пользователей даже в большей степени, чем приобретение дополнительной полосы пропускания у провайдера. И с этой задачей вам поможет справиться российский программный продукт – Lan2net Traffic Shaper!

Ссылка на сайт: http://www.lan2net.ru

news.softodrom.ru

Шейпирование трафика в Linux / Хабрахабр

Под катом описано как шейпировать трафик в Linux и что для этого нужно знать. Осуществлять шейпирование трафика будем посредством утилиты tc из пакета iproute2. Знания без которых нельзя осознать всю полноту управления трафиком в Linux:Шейпировать можно только исходящий из интерфейса трафик. (в связи с чем возникает проблема с nat, о ней мы поговорим позже). Предположим, что имеется роутер между «интернетом» и абонентом. В роутер воткнуто две сетевые карты: eth0 смотрит на абонента, а eth2 в мир. Для ограничения «скорости скачивания» правила шейпирования описываем на eth0, для ограничения «отдачи» — на eth2.Необходимо понимать разницу между rate и ceil. Rate — гарантированная полоса пропуская, Ceil — максимальная полоса которую может получить данный класс, rate не может быть больше ceilПараметры rate и ceil для корневого класса должны совпадать. Таким образом мы определяем общую полосу пропускания. Сумма Rate'ов классов-потомков, не должна превышать Rate родительского класса. Конечно можно не выполнять этот пункт, но тогда могут возникнуть проблемы с предоставлением «гарантированной полосы пропускания».Идентификаторы классов указаны в шестнадцатеричной системе, и должны находиться в пределах от 2 до 2^16Для промежуточных классов необязательно создавать дисциплины и фильтры.Идентификаторы классов в пределах интерфейса должны быть уникальны.

В простом варианте изложения алгоритм нарезки трафика выглядит так: 1. Создаем корневую дисциплину для интерфейса и указываем класс куда будет попадать не классифицированный трафик. 2. Создаем корневой класс и определяем ширину канала. 3. Создаем дочерний класс для шейпирования абонента. 4. Создаем дисциплину шейпирования для класса абонента. 5. Создаем фильтра позволяющие классифицировать трафик абонента.

В принципе все просто, но в реальной жизни придется потратить много нервов, что бы добиться желаемого результата. Один из способов добиться результата не тратя много нервов — использовать скрипт htbinit (взять его можно с sourceforge.net/projects/htbinit). Синтаксис конфигов простой, создание классов тоже просто. Для построения конфигураций средней сложность вполне достаточно. Пример. Имеется локальная сеть, средних размеров. Вам необходимо ограничивать скорость абонентов согласно прейскуранту, трансляция адресов (NAT) происходит на другом сервере.

Получение htbinitdebian:~# wget downloads.sourceforge.net/project/htbinit/HTB.init/0.8.5/htb.init-v0.8.5?use_mirror=surfnet debian:~# mv htb.init-v0.8.5 /usr/local/sbin/ debian:~# cd /usr/local/sbin/ debian:/usr/local/sbin# mv htb.init-v0.8.5 htb.init debian:/usr/local/sbin# chmod +x htb.init По умолчанию htbinit хранит конфиги в папке /etc/sysconfig/htb.debian:~# mkdir -p /etc/sysconfig/htb Создаем коневую дисциплину для интерфейса eth0 (интерфейс смотрит в локальную сеть, «на абонента»)debian:~# touch /etc/sysconfig/htb/eth0 Указываем в какой класс будет попадать трафик не попавший ни в один из фильтровdebian:~# mcedit /etc/sysconfig/htb/eth0 DEFAULT=42 Создаем корневой классdebian:~# touch /etc/sysconfig/htb/eth0-2.root debian:~# mcedit /etc/sysconfig/htb/eth0-2.root RATE=100Mbit Можно не указывать CEIL, тогда он автоматом будет равен RATE.

Создаем класс для не классифицированного трафикаdebian:~# touch /etc/sysconfig/htb/eth0-2:42.root debian:~# mcedit /etc/sysconfig/htb/eth0-2:42.root RATE=4Kbit

Создаем общий клиентский класс. Пускай его ID будет равно «D» и всего для абонентов мы выделим 10 Мбит.debian:~# touch /etc/sysconfig/htb/eth0-2:D.sumamry_cilents_class debian:~# mcedit /etc/sysconfig/htb/eth0-2:D.sumamry_cilents_class RATE=10Mbit

Теперь можно заняться абонентами. Что бы ограничить скорость скачивания в 512 КБит абоненту Василию нужно: Создать класс для абонента Василия. Пускай ID клиентов будут начинаться с 255. Весьма полезно, если потребуется создать какой либо «системный» класс. debian:~# touch /etc/sysconfig/htb/eth0-2:D:100.client_login Интерфейс, идентификатор класса и родительские классы описываются в названии конфига. Запись eth0-2:D:100.client_login означает чтоeth0- Данный класс принадлежит к интерфейсу eth0 2 Корневой классD Родительский класс (В нашем случае общий клиентский класс)100 Идентификатор класса клентаclient_login Мнемоническая составляющая названия файла, несет смысловую нагрузку, в генерации классов не используется

Название файла генерируется таким образом: 1. Интерфейс к которому принадлежит класс. 2. Разделитель "-"(минус) 3. ID корневого класса 4. Разделитель ":"(двоеточие) 5. ID родительского класса 6. Разделитель ":"(двоеточие) 7. ID клиентского класса 8. Разделитель "."(точка) 9. Мнемоническая составляющая названия файла Пункты 5 и 6 могут отсутствовать, в зависимость от выбранной Вами стратегии шейпирования.

debian:~# mcedit /etc/sysconfig/htb/eth0-2:D:100.client_login RATE=512Kbit LEAF=sfq RULE=0.0.0.0/0,client_ip/32 По минимуму в конфиге должно быть 3 строки. RATE — полоса предоставляемая абоненту. LEAF — указатель на то, что класс конечный и для него необходимо создать создать дисциплину, в нашем случае sfq («псевдочестное» распределение полосы) RULE — определяем что попадает в класс.Фильтровать можно по ип адресам, подсетям ип адресов, портам. Количество записей RULE может быть более одной.

Если нам нужно шейпировать трафик и натить на том же руотере, то вместо RULE нужно использовать MARK. Единственное придется маркировать пакеты. Пример скрипта генерирующего конфиги для htbinit в конфигурации с NATом.#!/bin/bash #определяем переменныеdeclare -a rules inif="eth0" outif="eth2" vlan="10" workdir="/home/netup" vardir="${workdir}/var" htb_dir="/etc/sysconfig/htb"mysql="/usr/bin/mysql -h host -u user -ppassword -D base" ipt="/usr/local/sbin/iptables" IPT_UNLIM="UNLIM_"${vlan} utm_rules="${vardir}/htb_rules_htb" htb_rules="${vardir}/htb_rules_utm" #подготавливаем конфиги при первом запуске[ -e ${htb_rules} ] || touch ${htb_rules} #полная регенерация конфиговif [ "${1}" = "zopa" ];then echo ""> ${htb_rules}; fi #получаем данные (id в шестнадцатиричной системе)echo "select id,ip,mask,speed from view_shaper order by id;"|$mysql|sed '1d' > ${utm_rules}; #если достучались к базе и есть разница с текущим конфигомexp="${utm_rules} ${htb_rules}" [ -s ${utm_rules} ] && if [ -n "`diff ${exp}`" ] then #удаляем конфиги надобность в которых отпала for i in `diff ${exp}|awk '{if (NF==5)print $2}'|sort -n|uniq` do inshaper=${htb_dir}/${inif}-2:${i}.rule_${i}; [ -e ${inshaper} ] && rm ${inshaper}; outshaper=${htb_dir}/${outif}-2:${i}.rule_${i}; [ -e ${outshaper} ] && rm ${outshaper}; done; #формируем новые конфигиrules=(`diff ${exp}|grep "<"|awk '{if (NF==5)print $2,$3,$4,$5}'`) for i in `seq 1 4 ${#rules[@]}`; do id=${rules[$i-1]}; ip=${rules[$i]}; mask=${rules[$i+1]}; rate=${rules[$i+2]}; #Формируем названия конфигов inshaper=${htb_dir}"/"${inif}-2:${id}.rule_${id}; outshaper=${htb_dir}/${outif}-2:${id}.rule_${id}; #Рассчитываем марки для пакетов inmark="0x"`echo "obase=16; $((0x${id}*2))"|bc` outmark="0x"`echo "obase=16; $((0x${id}*2+1))"|bc` #Удаляем «старые» правила маркировки${ipt} -t mangle -S ${IPT_UNLIM}|grep -w ${ip}|awk -v ipt=${ipt} '{$1="-D";system(ipt" -t mangle "$0)}'; #Создаем конфиг и правила на внутреннем интерфейсеif [ -e ${inshaper} ]; then #echo "RULE="0.0.0.0/0,"${ip}"/"${mask}">> ${inshaper} ${ipt} -t mangle -A ${IPT_UNLIM} -s ${ip} -j MARK --set-mark ${inmark} else echo "RATE=4096bit" > ${inshaper} echo "CEIL="$((${rate}*1024))"bit" >>${inshaper} echo "LEAF=sfq" >> ${inshaper} #echo "RULE=0.0.0.0/0,"${ip}"/"${mask}>> ${inshaper}; echo "MARK="${inmark}>> ${inshaper}; ${ipt} -t mangle -A ${IPT_UNLIM} -d ${ip}/${mask} -j MARK --set-mark ${inmark} fi #Создаем конфиг и правила на внутреннем интерфейсе if [ -e $outshaper ]; then #echo "RULE="${ip}"/"${mask}",0.0.0.0/0" >> ${outshaper} ${ipt} -t mangle -A ${IPT_UNLIM} -s ${ip}/${mask} -j MARK --set-mark ${outmark} else echo "RATE=4096bit" > ${outshaper} echo "CEIL="$((${rate}*1024))"bit" >> ${outshaper} echo "LEAF=sfq" >> ${outshaper} #echo "RULE="${ip}"/"${mask}",0.0.0.0/0" >> ${outshaper} echo "MARK="${outmark}>> $outshaper; ${ipt} -t mangle -A ${IPT_UNLIM} -s ${ip}/${mask} -j MARK --set-mark ${outmark} fi echo $ip done; cp ${exp} [ -e /var/cache/htb.init ] && rm /var/cache/htb.init /usr/local/sbin/htb.init restart fi

Для конфигураций до 1000-1500 фильтров такой вариант подойдет. Для более крупных уже нужно использовать быстрые хэш фильтры, о ни и о приоретизации трафика я расскажу в следующей статье.

habrahabr.ru

Причесываем трафик — динамический шейпер на Linux / Хабрахабр

Предположим у вас есть домашняя сеть (или не домашняя, а сеть небольшого офиса) с выходом в интернет через не очень скоростной канал. А пользователей — много, и каждый хочет что-то скачивать, да с максимальной скоростью. Вот тут перед нами встатет задача, как максимально эффективно распределить наш интернет-канал между пользователями так, чтобы они не мешали друг другу. В этой статье я опишу, как можно решить такую задачу с помощью Linux-сервера.

Сформулируем, что же мы хотим получить в результате: 1. Чтобы канал поровну делился между пользователями. 2. Чтобы канал зря не простаивал. 3. Чтобы онлайн-игры, ssh и telnet не «лагали» даже при полной загрузке канала, например торрентами.

Если интернетом будут одновременно пользоваться 10 пользователей — каждый получит в свое распоряжение 1/10 часть канала, если в данный момент активен только один пользователь — он будет использовать весь канал сам. Добиться этого можно используя планировщик пакетов HTB, который входит в ядро linux начиная с версии 2.4.20. Можно конфигурировать шейпер с помощью команды tc, но для более удобной и наглядной настройки я рекомендую скачать скрипт htb.init. Они использует для конфигурации htb набор конфигурационных файлов, именуемых так, что при сортировке по алфавиту их имена позволяют визуально представить себе дерево классов шейпера и удобно его редактировать. Предположим, что у нас на сервере есть интерфейс eth0, через который мы подключены к интернет, и eth2, который «смотрит» в локальную сеть.

Управлять можно только исходящим из интерфейса трафиком, поэтому для eth0 будут правила для upload трафика пользователей, а для — eth2 — download трафика.

По умолчанию конфигурационные файлы htb.init находятся в /etc/htb/. Для начала напишем правила шейпинга для upload трафика, они у нас будут простые. Создаем файл с именем eth0 (интерейс «смотрящий» в интернет), в него напищем следующие строки:DEFAULT=20 R2Q=1 Параметр DEFAULT задает номер класса, к которому будет относиться трафик «по умолчанию» — обычно это класс с минимальным приоритетом. Параметр R2Q влияет на работу алгоритма разделения канала и зависит от ширины канала. Я подбирал его значение эмпирическим путем, для моего исходящего канала в 2 Mbit.

Далее, создадим файл eth0-2.full2MBit, для класса включающего в себя весь доступный интернет-канал. Имя файла состоит из имени интерфейса и id класса, после точки идет смысловое имя класса, используется как комментарий и системой игнорируется.RATE=2Mbit CEIL=2Mbit RATE — это наша гарантированная полоса, CEIL — максимальная полоса. Так как у меня канал с гарантированной максимальной полосой в 2 Mbit, то эти параметры у меня равны.

Теперь мы создадим по одному файлу для каждого класса трафика, который у нас будет. Я у себя создал отдельные классы для ssh трафика, а так же трафика игр World Of Warcraft и Counter Strike, хотя вы можете сделать для всего высокоприоритетного трафика один класс.

Пример для ssh — создаем файл eth0-2:10.ssh. В имени файла через двоеточие указан id родительского класса 2 и id текущего класса — 10. Идентификаторы для класса вы можете выбирать произвольно.# class for outgoing ssh RATE=128Kbit CEIL=2Mbit RULE=*:22 PRIO=1 BURST=100Kb В параметре RATE указана гарантированная полоса для этого класса, в CEIL — максимальная. Мы выделяем для ssh 128 KBit (как минимум) и разрешаем ему загрузить весь канал (я закачивать файлы по sftp). PRIO задает приоритет класса трафика (1- максимальный, чем больше число — тем меньш приоритет). BURST задает максимальный объем трафика, который будет передан на максимальной скорости перед тем, как перейти к передаче данных из дургих классов. Установив этот параметр в достаточно высокое значение мы добиваемся того, что трафик ssh будет передан с минимальными задержками. RULE задает правило, по которому будет отбираться трафик в этот класс. Формат — RULE=[[saddr[/prefix]][:port[/mask]],][daddr[/prefix]][:port[/mask]] Обратите внимание на запятую! RULE=*:22 обозначает трафик, у которого порт назначения 22, а RULE=*:22, обозначает трафик, у которого исходящий порт — 22.

Создадим так же классы для других видов трафика, и класс для трафика «по умолчанию» с id 20 (мы указали вначале что именно в класс номер 20 надо направлять трафик «по умолчанию»). В нем укажем используемую дисциплину разделения канала LEAF=sfq, для того чтобы upload поровну делился между TCP сессиями разных пользователей.

Для eth2 правила будут почти такие же, только с учетом что общая ширина канала — 100 Mbit, мы ведь хотим чтобы можно было обращаться к локальным ресурсам сервера на полной скорости, для интернет-трафика выделен отдельный класс на 2 MBit, у которого как потомки добавлены классы отдельных пользователей, разделение по классам я делал по IP адресам. Для каждого пользователя можно указать максимальную и гарантированную скорость, а так же приоритет.

После правки конфигурации перезапускаем htb.init:/etc/init.d/htb.init restart И правила шейпинга трафика сразу же вступают в силу.

В процессе состевления правил обычно возникает необходимость как-то визуализировать трафик, в целях отладки и мониторинга, поэтому решил написать плагин для системы мониторинга серверов munin, который бы визуализировал распределение по классам HTB трафика. Выводить решил загрузку только классов-листьев дерева, так как именно они обычно несут смысловую нагрузку. Скачать плагин вы можете из официального репозитория плагинов munin, называется он qos_, просто скопируйте его в папку плагинов munin /usr/share/munin/plugins/ и в папке используемых плагинов /etc/munin/plugins сделайте на него символическую ссылку вида qos_eth2, где eth2 — имя интерфейса, на котором нужно мониторить загрузку. В файле конфигурации плагинов можно добавить следущее:[qos_eth2] env.ignore_queue1_10 yes env.label_name1_31 Viperet env.label_name1_32 Cornet Параметр env.ignore_queue позволяет не отображать на графике состояние класса с указанным id, а параметр env.label_name — задать человекопонятную метку для класса на графике.

В итоге должно получиться что то такое:

Хочу заметить, что у меня несколько нетипичная ситуация, два интернет канала на 2 и 1 Mbit, и для каждого пользователя ограничение в 2 Mbit скорости загрузки, поэтому на графике видно, что если активен один пользователь — его скорость урезается на 2 Mbit, а если несколько — суммарная скорость может достигать и трех. На таком достаточно «тесном» канале работают более 20 человек, и вполне комфортно себя чувствуют, не мешая друг другу. Эта картинка с реально действующего сервера, и она обновляется каждые 5 минут и отображает актуальную картину загрузки канала.

UPD: выложил пример конфига htb.init

habrahabr.ru


Смотрите также