Сегодня я хотел бы немного рассказать о приоритетах.
image

Статья не претендует на охват всей информации по QoS на Mikrotik. Это демонстрация набора правил, позволяющих настроить несложную схему приоритезации трафика и пополнять её по мере необходимости.

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

Говоря о QoS, обычно подразумевают два направления — более или менее равномерное деление канала по количеству пользователей, либо приоритезацию трафика. Направления эти вполне дополняют друг-друга, но для дома, для семьи заниматься делением канала я смысла не вижу и, если вас интересует эта тема, сошлюсь на исчерпывающе раскрывающую тему статью «MikroTik QoS — развенчание мифов».

Я же сосредоточусь на приоретизации трафика, благо это несколько проще.

Ограничение скорости передачи данных может быть выполнено двумя способами:

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

Principles of rate limiting and equalizing

Как видно на иллюстрации, шейпер режет всё, что не влезло, а шедулер просто притормаживает.
Соответственно, именно шедулер нам и нужен.

Теперь необходимо поделить трафик на классы и задать каждому классу свой приоритет. Первый класс обслуживается в первую очередь, последний — в последнюю.

Самый простой вариант такого решения, который зачастую и используется — просто пустить приоритетом VoIP-трафик, а весь остальной по остаточному принципу, но я сделаю чуть сложнее.

Итак, план таков:

prio_1: DNS, ICMP, ACK — в первую очередь идёт служебный трафик. Установка и разрыв соединений, резолвинг имён и т.п.
prio_2: SIP — VoIP очень любит минимальные задержки.
prio_3: SSH и игры — удалённый доступ важен для работы. Игры — для отдыха.
prio_4: RDP и HTTP/HTTPS — веб, видео и т.п.
prio_5: всё, что не опознано выше — в принципе, можно принудительно загнать сюда торренты. Благо дома порты с которых работают клиенты вполне известны..

Маленькое лирическое отступление:

Если мы поищем информацию о QoS в Mikrotik, то найдём несколько вариантов скриптов, начиная от монструозного QOS script by Greg Sowell или явно основанного на нём The Mother of all QoS Trees, заканчивая Traffic Prioritization Script (кстати, советую отнестись к нему с большой осторожностью, автор явно довольно смутно понимает, что делает и поэтому скрипт делает явно не то, что было задумано). У всех этих скриптов есть одна общая проблема — они написаны довольно давно и в значительной степени устарели по одной простой причине — мир изменился.

Сегодня, благодаря всеобщему шифрованию трафика, мы не можем так запросто взять и с помощью L7-regexp отловить трафик youtube, например, или Skype. Поэтому, используя такие скрипты, внимательно отнеситесь к вопросу определения трафика. Это, на мой взгляд, единственная сложность в этом вопросе.

Теперь разметим трафик согласно плана выше. В коде я использую interfaceBandwidth, т.е. ширину канала. У меня он симметричный и равен 100М. Если у вас отличается ширина канала, то необходимо изменить значение interfaceBandwidth на необходимое. Если канал асинхронный, то скрипт будет сложнее за счёт необходимости отдельно маркировать пакеты для входящего и исходящего трафика. Это несложно, но значительно увеличит скрипт, ухудшив его читаемость и, в целом, выходит за рамки статьи.

В address-list я демонстрирую возможность массовой вставки адресов из FQDN (для примера взяты адреса кластеров из wiki Мира Танков). Разумеется, можно просто прописать необходимые IP вручную.

#Set bandwidth of the interface
:local interfaceBandwidth 100M

# address-lists
:for i from=1 to=10 do={/ip firewall address-list add list=WoT address=("login.p"."$i".".worldoftanks.net")}
#
/ip firewall mangle
# prio_1
    add chain=prerouting action=mark-packet new-packet-mark=prio_1 protocol=icmp
    add chain=prerouting action=mark-packet new-packet-mark=prio_1 protocol=tcp port=53
    add chain=prerouting action=mark-packet new-packet-mark=prio_1 protocol=udp port=53
    add chain=prerouting action=mark-packet new-packet-mark=prio_1 protocol=tcp tcp-flags=ack packet-size=0-123
# prio_2
    add chain=prerouting action=mark-packet new-packet-mark=prio_2 dscp=40                                     
    add chain=prerouting action=mark-packet new-packet-mark=prio_2 dscp=46
    add chain=prerouting action=mark-packet new-packet-mark=prio_2 protocol=udp port=5060,5061,10000-20000 src-address=192.168.100.110
    add chain=prerouting action=mark-packet new-packet-mark=prio_2 protocol=udp port=5060,5061,10000-20000 dst-address=192.168.100.110
# prio_3
    add chain=prerouting action=mark-packet new-packet-mark=prio_3 protocol=tcp port=22
    add chain=prerouting action=mark-packet new-packet-mark=prio_3 src-address-list=WoT
    add chain=prerouting action=mark-packet new-packet-mark=prio_3 dst-address-list=WoT
# prio_4
    add chain=prerouting action=mark-packet new-packet-mark=prio_4 protocol=tcp port=3389
    add chain=prerouting action=mark-packet new-packet-mark=prio_4 protocol=tcp port=80,443
Аккуратно уложим размеченный трафик в очередь:

<source>queue tree add max-limit=$interfaceBandwidth name=QoS_global parent=global priority=1
:for indexA from=1 to=4 do={
   /queue tree add \ 
      name=( "prio_" . "$indexA" )       parent=QoS_global       priority=($indexA)       queue=ethernet-default       packet-mark=("prio_" . $indexA)       comment=("Priority " . $indexA . " traffic")
}
/queue tree add name="prio_5" parent=QoS_global priority=5     queue=ethernet-default packet-mark=no-mark comment="Priority 5 traffic"

И последнее, коль скоро Mikrotik поддерживает WMM, было бы логично разметить трафик и для него.

Делается это тем же mangle-ом с помощью команды set_priority. Согласно wiki Mikrotik'а, таблица приоритетов WMM выглядит довольно причудливо:

1,2 — background
0,3 — best effort
4,5 — video
6,7 — voice.

Разметим приоритеты, используя те же правила, что и для маркировки пакетов:

/ip firewall mangle
# prio_1
    add chain=prerouting action=set-priority new-priority=7 protocol=icmp
    add chain=prerouting action=set-priority new-priority=7 protocol=tcp port=53
    add chain=prerouting action=set-priority new-priority=7 protocol=udp port=53
    add chain=prerouting action=set-priority new-priority=7 protocol=tcp tcp-flags=ack packet-size=0-123
# prio_2
    add chain=prerouting action=set-priority new-priority=6 dscp=40                                     
    add chain=prerouting action=set-priority new-priority=6 dscp=46
    add chain=prerouting action=set-priority new-priority=6 protocol=udp port=5060,5061,10000-20000 src-address=192.168.100.110
    add chain=prerouting action=set-priority new-priority=6 protocol=udp port=5060,5061,10000-20000 dst-address=192.168.100.110
# prio_3
    add chain=prerouting action=set-priority new-priority=5 protocol=tcp port=22
    add chain=prerouting action=mark-packet new-packet-mark=prio_3 src-address-list=WoT
    add chain=prerouting action=mark-packet new-packet-mark=prio_3 dst-address-list=WoT
# prio_4
    add chain=prerouting action=set-priority new-priority=3 protocol=tcp port=3389

В принципе, на этом всё.

В будущем, при необходимости, можно подумать о формировании динамических адресных листов, периодически формируемых из кэша DNS скриптами типа:

:foreach i in=[/ip dns cache all find where (name~"youtube" || name~"facebook" || name~".googlevideo")]
    do={:put [/ip dns cache get $i address]}

для отбора онлайнового видео.

Или детектить Skype с помощью поиска upnp-правил:

:foreach i in=[/ip firewall nat find dynamic and comment~"Skype"]
    do={:put [/ip firewall nat get $i dst-port]}

Но пока у меня такой необходимости нет.

Скрипты из статьи доступны на GitHub'е. Если у вас что-то не заработало, есть идеи или комментарии — пишите.

Спасибо за внимание!

UPD: В исходной версии статьи в скриптах была ошибка (неверно выбранная цепочка). Скрипты исправлены.
Поделиться с друзьями
-->

Комментарии (26)


  1. Expelliamus
    06.06.2017 16:55

    Очень содержательная статья на тему: https://habrahabr.ru/post/307214/

    max-limit=30M — в условии задачи указано что канал у нас выдает 32 метра, но прописывать нужно чуть меньше доступной скорости. В противном случае вы упретесь в шейпер своего провайдера, ваш же просто не будет работать.


    родительскую очередь (у Вас QoS_global) нужно брать чуть уже, чем скорость от провайдера


    1. StraNNicK
      06.06.2017 16:58

      Да, всё верно. Но есть небольшой нюанс — я не пытаюсь шейпить трафик, я пытаюсь его эквалайзить.
      Т.е. провайдер может урезать всё как он считает нужным, но под нож пойдут пакеты из prio_5, а их не жалко.

      Хотя могу ошибаться, разумеется.


      1. Expelliamus
        06.06.2017 17:09

        Насколько я понял из указанной статьи — дочерние очереди («prio_». "$indexA") не будут отбрасывать / задерживать пакеты, пока у родителя (QoS_global) не сработает отсечка (max-limit, limit-at и т.д.)


        1. StraNNicK
          06.06.2017 17:42

          На всякий случай сверился с документацией. В вики сказано следующее:
          1. https://wiki.mikrotik.com/wiki/Руководства: Очередь_(Queue)
          В дереве очередей отсутствует строгая последовательность обработки трафика как в простых очередях – весь трафик попадает в необходимые очереди сразу, одновременно.
          2. https://wiki.mikrotik.com/wiki/Руководства:HTB
          Каждая очередь в HTB обладает двумя ограничениями на скорость передачи данных: CIR (гарантированная скорость) и MIR (максимальная скорость). Сначала будет удовлетворено значение limit-at (CIR) всех очередей, и только затем дочерние очереди будут пытаться «одолжить» необходимую им скорость передачи данных у своих родительских очередей для того, чтобы достичь своих значений max-limit (MIR).

          т.е., похоже что нет, отсечки ждать не обязательно.

          P.S. Спасибо за вопрос, благодаря нему ещё раз проверил скрипты и нашёл в них ошибку, из-за которой трафик не распределялся по очередям (неверно указал цепочки. Сейчас исправлю)


  1. beho1der
    06.06.2017 20:06

    У вас жестко указаны IP адреса для SIP трафика, нужно ли это?


    1. StraNNicK
      07.06.2017 12:53

      Хороший вопрос. Для 5060 и 5061 скорее всего нет, но там просто SIP, он просто управляет сессией.
      Мне кажется, что малые задержки критичнее для RTP-трафика, а вот с ним сложнее.
      С одной стороны, должно быть достаточно выставлять TOS на сервере и определять трафик по нему (через поле DSCP/TOS), с другой — я решил перестраховаться и определять его по протоколу и диапазону портов.

      Короче, в примере я перестраховался на всякий случай.


  1. ekerlostw
    07.06.2017 11:25
    -2

    В домашних условиях QoS вообще лишний — у домашних микротов на него мощностей толком не хватит — модели с вайфаем прокачают мегабит 60-70 торрентами и захлебнутся.
    Одно время ограничивал количество соединений на адрес, но потом и на это забил.


    1. Ruckus
      07.06.2017 11:40

      А сколько по вашему нужно на QoS? Я думал для домашнего использования 720МГц MIPS'а вполне хватает, а некоторые могут себе и что-то из CloudCore серии поставить, если частный дом и видеонаблюдение, а там уже 9x1ГГц и выше.


      1. ekerlostw
        08.06.2017 05:23

        Безусловно зависит от конечной нагрузки, но с запасом до 100мбит хватит 750gr3, а до 200 3011. Но проблема в том, что любая модель с беспроводным модулем (что для домашних условий крайне актуально) не обладает такой производительностью.


    1. StraNNicK
      07.06.2017 13:10

      Ну, я на двух 100М линках дома выжимал на торрентах 150 мегабит в пике, а в среднем было 110-130.
      Нагрузка на процессор 67% максимум.
      image


      1. StraNNicK
        07.06.2017 13:17

        кстати, было ощущение, что скорость закачки тупо в производительность винта упёрлась.


        1. Ruckus
          07.06.2017 14:32

          Странный у вас хард.
          По теме — два линка 80 и 100 на балансировке выжимали из торрента примерно 150-160, что сходится с теоритическим средним в удвоенную минимальную пропускную способность двух интерфейсов. Качал на SSD (чтоб точно не учитывать ограничение HDD, а так конечно насилие над твердотельником). Нагрузка до 30% на Hap AC. Это учитывая неидеальность настройки и отключеный fastpath. Без QoS, конечно.


      1. ekerlostw
        08.06.2017 05:27

        Если с фаст-треком (читай без коса ибо фасттрек не закосишь) то вообще не вопрос, а вот с простой приоритезацией, через которую идёт весь трафик, мой 951G на 650МГц захлёбывался на уровне 55-65мбит.


        1. StraNNicK
          08.06.2017 06:44

          у меня hAP AC, там чип поновее и пошустрее. А 951G хорош, но на нём HD-каналы с torrent-tv чуть-чуть подтормаживают.


          1. ekerlostw
            08.06.2017 06:56

            hAP AC хорош, но был бы ещё лучше если бы стоил ну хотя бы 6к, а не 8-10…


            1. StraNNicK
              08.06.2017 07:07

              О, да! Я когда свой брал, меня жаба давила так, что я чуть не умер.
              Хотя сейчас я.маркет говорит, что уже за 6.5 есть, но то в Москве.


              1. Ruckus
                08.06.2017 09:46

                Буквально недавно сменил 951G на hAP AC, брал как раз за 6500, у них вроде была доставка по россии, если надо в личку.


    1. umatrix
      07.06.2017 13:10

      3011RM запросто торренты на 300-350 мегабит качает. Проверено лично.


  1. Faight
    07.06.2017 22:11

    QoS в микротике боль и страдания, когда у тебя несколько провайдеров, несколько тунелей…

    Кстати, почему pfifo, а не pcq?


    1. StraNNicK
      08.06.2017 04:21

      Ну да, поэтому у меня и маркируются только пакеты, а не соединения (а жаль, я бы ещё короткие http-соединения от длинных отделил).

      pfifo тупо потому что оно по умолчанию. Я честно прочёл документацию, но не очень понял как виды очередей повлияют на приоретизацию. С делением канала понятно, а вот в моём случае — не очень.


      1. Faight
        10.06.2017 23:35

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


        1. StraNNicK
          12.06.2017 04:38

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


  1. Elordis
    08.06.2017 04:09
    +1

    Это круто. Но зачем?
    Даунстрим трафик все равно контролирует провайдер. Приоритезация его имеет смысл только если у вас локальная сетка дома имеет меньшую полосу, чем куплен канал.
    А апстрим в 99% случаев у вас будет свободен. А в остальном 1% случаев проще зарезать полосу в торрент-клиенте.


    1. StraNNicK
      08.06.2017 04:13

      Честно говоря, в основном, чтобы разобраться, как работает приоритезация трафика в микротике.
      Потому что по мере чтения документации и примеров из вики возникло недопонимание.


  1. Dmitry_4
    14.06.2017 11:47
    -1

    В отеле был микроблевотик, так не работали половина сайтов, не отправлялись файлы в телеграмме и т.п.


    У соседей в таверне все работало, хотя тот же провайдер.


    1. wilddingodog
      14.06.2017 16:26
      +1

      А может блевотик был не микротик, а настройщик микротика??!