Сегодня я хотел бы немного рассказать о приоритетах.
Статья не претендует на охват всей информации по 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=forward action=mark-packet new-packet-mark=prio_1 protocol=icmp
add chain=forward action=mark-packet new-packet-mark=prio_1 protocol=tcp port=53
add chain=forward action=mark-packet new-packet-mark=prio_1 protocol=udp port=53
add chain=forward action=mark-packet new-packet-mark=prio_1 protocol=tcp tcp-flags=ack packet-size=0-123
# prio_2
add chain=forward action=mark-packet new-packet-mark=prio_2 dscp=40
add chain=forward action=mark-packet new-packet-mark=prio_2 dscp=46
add chain=forward action=mark-packet new-packet-mark=prio_2 protocol=udp port=5060,5061,10000-20000 src-address=192.168.100.110
add chain=forward 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=forward action=mark-packet new-packet-mark=prio_3 protocol=tcp port=22
add chain=forward action=mark-packet new-packet-mark=prio_3 address-list=WoT
# prio_4
add chain=forward action=mark-packet new-packet-mark=prio_4 protocol=tcp port=3389
add chain=forward action=mark-packet new-packet-mark=prio_4 protocol=tcp port=80,443
# prio_5
add chain=forward action=mark-packet new-packet-mark=prio_5
Аккуратно уложим размеченный трафик в очередь:
queue tree add max-limit=$interfaceBandwidth name=QoS_global parent=global priority=1
:for indexA from=1 to=5 do={
/queue tree add
name=( "prio_" . "$indexA" )
parent=QoS_global
priority=($indexA)
queue=ethernet-default
packet-mark=("prio_" . $indexA)
comment=("Priority " . $indexA . " 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=forward action=set-priority new-priority=7 protocol=icmp
add chain=forward action=set-priority new-priority=7 protocol=tcp port=53
add chain=forward action=set-priority new-priority=7 protocol=udp port=53
add chain=forward action=set-priority new-priority=7 protocol=tcp tcp-flags=ack packet-size=0-123
# prio_2
add chain=forward action=set-priority new-priority=6 dscp=40
add chain=forward action=set-priority new-priority=6 dscp=46
add chain=forward action=set-priority new-priority=6 protocol=udp port=5060,5061,10000-20000 src-address=192.168.100.110
add chain=forward action=set-priority new-priority=6 protocol=udp port=5060,5061,10000-20000 dst-address=192.168.100.110
# prio_3
add chain=forward action=set-priority new-priority=5 protocol=tcp port=22
add chain=forward action=set-priority new-priority=4 address-list=WoT
# prio_4
add chain=forward 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'е. Если у вас что-то не заработало, есть идеи или комментарии — пишите.
Спасибо за внимание!
Автор: StraNNicK