Статья не претендует на охват всей информации по QoS на Mikrotik. Это демонстрация набора правил, позволяющих настроить несложную схему приоритезации трафика и пополнять её по мере необходимости.
Надеюсь, коллеги помогут советами в комментариях.
Говоря о QoS, обычно подразумевают два направления — более или менее равномерное деление канала по количеству пользователей, либо приоритезацию трафика. Направления эти вполне дополняют друг-друга, но для дома, для семьи заниматься делением канала я смысла не вижу и, если вас интересует эта тема, сошлюсь на исчерпывающе раскрывающую тему статью «MikroTik QoS — развенчание мифов».
Я же сосредоточусь на приоретизации трафика, благо это несколько проще.
Ограничение скорости передачи данных может быть выполнено двумя способами:
1. Отбрасываются все пакеты, превышающие лимит скорости передачи (шейпер).
2. Задержка превысивших заданное ограничение скорости передачи пакетов в очереди и отправка их позже, как только появляется такая возможность, т.е. выравнивание скорости передачи (шедулер).
Как видно на иллюстрации, шейпер режет всё, что не влезло, а шедулер просто притормаживает.
Соответственно, именно шедулер нам и нужен.
Теперь необходимо поделить трафик на классы и задать каждому классу свой приоритет. Первый класс обслуживается в первую очередь, последний — в последнюю.
Самый простой вариант такого решения, который зачастую и используется — просто пустить приоритетом 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)
beho1der
06.06.2017 20:06У вас жестко указаны IP адреса для SIP трафика, нужно ли это?
StraNNicK
07.06.2017 12:53Хороший вопрос. Для 5060 и 5061 скорее всего нет, но там просто SIP, он просто управляет сессией.
Мне кажется, что малые задержки критичнее для RTP-трафика, а вот с ним сложнее.
С одной стороны, должно быть достаточно выставлять TOS на сервере и определять трафик по нему (через поле DSCP/TOS), с другой — я решил перестраховаться и определять его по протоколу и диапазону портов.
Короче, в примере я перестраховался на всякий случай.
ekerlostw
07.06.2017 11:25-2В домашних условиях QoS вообще лишний — у домашних микротов на него мощностей толком не хватит — модели с вайфаем прокачают мегабит 60-70 торрентами и захлебнутся.
Одно время ограничивал количество соединений на адрес, но потом и на это забил.Ruckus
07.06.2017 11:40А сколько по вашему нужно на QoS? Я думал для домашнего использования 720МГц MIPS'а вполне хватает, а некоторые могут себе и что-то из CloudCore серии поставить, если частный дом и видеонаблюдение, а там уже 9x1ГГц и выше.
ekerlostw
08.06.2017 05:23Безусловно зависит от конечной нагрузки, но с запасом до 100мбит хватит 750gr3, а до 200 3011. Но проблема в том, что любая модель с беспроводным модулем (что для домашних условий крайне актуально) не обладает такой производительностью.
StraNNicK
07.06.2017 13:10Ну, я на двух 100М линках дома выжимал на торрентах 150 мегабит в пике, а в среднем было 110-130.
Нагрузка на процессор 67% максимум.
StraNNicK
07.06.2017 13:17кстати, было ощущение, что скорость закачки тупо в производительность винта упёрлась.
Ruckus
07.06.2017 14:32Странный у вас хард.
По теме — два линка 80 и 100 на балансировке выжимали из торрента примерно 150-160, что сходится с теоритическим средним в удвоенную минимальную пропускную способность двух интерфейсов. Качал на SSD (чтоб точно не учитывать ограничение HDD, а так конечно насилие над твердотельником). Нагрузка до 30% на Hap AC. Это учитывая неидеальность настройки и отключеный fastpath. Без QoS, конечно.
ekerlostw
08.06.2017 05:27Если с фаст-треком (читай без коса ибо фасттрек не закосишь) то вообще не вопрос, а вот с простой приоритезацией, через которую идёт весь трафик, мой 951G на 650МГц захлёбывался на уровне 55-65мбит.
Faight
07.06.2017 22:11QoS в микротике боль и страдания, когда у тебя несколько провайдеров, несколько тунелей…
Кстати, почему pfifo, а не pcq?StraNNicK
08.06.2017 04:21Ну да, поэтому у меня и маркируются только пакеты, а не соединения (а жаль, я бы ещё короткие http-соединения от длинных отделил).
pfifo тупо потому что оно по умолчанию. Я честно прочёл документацию, но не очень понял как виды очередей повлияют на приоретизацию. С делением канала понятно, а вот в моём случае — не очень.Faight
10.06.2017 23:35Если у вас в домашней сети только один компьютер, то pfifo достаточно, только буфер дефолтный можно увеличить. Если же несколько устройств, то необходима очень pcq, это позволит в рамках одного класса трафика поделить полосу пропускания и нивелировать загрузку канала одним из устройств ( буферы тоже можно подкрутить, ну и бёрст по желанию).
StraNNicK
12.06.2017 04:38Спасибо, исчерпывающе.
Но я правильно понимаю, что в таком случае нужно делать две очереди, для входящего и исходящего трафика?
Elordis
08.06.2017 04:09+1Это круто. Но зачем?
Даунстрим трафик все равно контролирует провайдер. Приоритезация его имеет смысл только если у вас локальная сетка дома имеет меньшую полосу, чем куплен канал.
А апстрим в 99% случаев у вас будет свободен. А в остальном 1% случаев проще зарезать полосу в торрент-клиенте.StraNNicK
08.06.2017 04:13Честно говоря, в основном, чтобы разобраться, как работает приоритезация трафика в микротике.
Потому что по мере чтения документации и примеров из вики возникло недопонимание.
Dmitry_4
14.06.2017 11:47-1В отеле был микроблевотик, так не работали половина сайтов, не отправлялись файлы в телеграмме и т.п.
У соседей в таверне все работало, хотя тот же провайдер.
Expelliamus
Очень содержательная статья на тему: https://habrahabr.ru/post/307214/
родительскую очередь (у Вас QoS_global) нужно брать чуть уже, чем скорость от провайдера
StraNNicK
Да, всё верно. Но есть небольшой нюанс — я не пытаюсь шейпить трафик, я пытаюсь его эквалайзить.
Т.е. провайдер может урезать всё как он считает нужным, но под нож пойдут пакеты из prio_5, а их не жалко.
Хотя могу ошибаться, разумеется.
Expelliamus
Насколько я понял из указанной статьи — дочерние очереди («prio_». "$indexA") не будут отбрасывать / задерживать пакеты, пока у родителя (QoS_global) не сработает отсечка (max-limit, limit-at и т.д.)
StraNNicK
На всякий случай сверился с документацией. В вики сказано следующее:
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. Спасибо за вопрос, благодаря нему ещё раз проверил скрипты и нашёл в них ошибку, из-за которой трафик не распределялся по очередям (неверно указал цепочки. Сейчас исправлю)