Мікротик. QoS для дому

Стаття не претендує на охоплення всієї інформації щодо QoS на Mikrotik. Це демонстрація набору правил, дозволяють налаштувати нескладну схему пріоритезації трафіку і поповнювати її за необхідності.
Говорячи про QoS, зазвичай мають на увазі два напрями — більш менш рівномірний поділ каналу за кількістю користувачів, або пріоритезацію трафіку. Напрями ці цілком доповнюють один одного, але для дому, для сім'ї займатися поділом каналу я сенсу не бачу і, якщо вас цікавить ця тема, пошлюся на вичерпну тему статті «MikroTik QoS — розвінчання міфів».
Я ж зосереджуся на пріоретизації трафіку, благо це дещо простіше.
Обмеження швидкості передачі може бути виконано двома способами:
1. Відкидаються всі пакети, що перевищують ліміт швидкості передачі (Шейпер).
2. Затримка перевищили задане обмеження швидкості передачі пакетів у черзі і відправлення їх пізніше, щойно утворюється така можливість, тобто. вирівнювання швидкості передачі (шедулер).

Як видно на ілюстрації, шейпер ріже все, що не влізло, а шедулер просто пригальмовує.
Відповідно саме шедулер нам і потрібен.
Тепер необхідно поділити трафік на класи та задати кожному класу свій пріоритет. Перший клас обслуговується насамперед, останній – в останню.
Найпростіший варіант такого рішення, який найчастіше використовується — просто пустити пріоритетом VoIP-трафік, а решту за залишковим принципом, але я зроблю трохи складніше.
Отже, план такий:
prio_1: DNS, ICMP, ACK -у першу чергу йде службовий трафік. Встановлення та розрив з'єднань, резолвінг імен тощо.
prio_2: SIP -VoIP дуже любить мінімальні затримки.
prio_3: SSH та ігри -віддалений доступ важливий для роботи. Ігри - для відпочинку.
prio_5: все, що не впізнано вище -в принципі, можна примусово загнати сюди торренти. Благо вдома порти з яких працюють клієнти цілком відомі.
Маленький ліричний відступ:
Сьогодні, завдяки загальному шифруванню трафіку, ми не можемо так легко взяти і за допомогою L7-regexp відловити трафік youtube, наприклад, або Skype. Тому, використовуючи такі скрипти, уважно поставтеся до питання визначення трафіку. Це, на мою думку, єдина складність у цьому питанні.
Тепер розмітимо трафік згідно з планом вище. У коді я використовую interfacebandwidth, тобто. ширину каналу. У мене він симетричний і дорівнює 100м. Якщо у вас відрізняється ширина каналу, то необхідно змінити значення interfacebandwidth на необхідне. Якщо канал асинхронний, то скрипт буде складніше за потребу окремо маркувати пакети для вхідного та вихідного трафіку. Це нескладно, але значно збільшить скрипт, погіршивши його читальність і загалом виходить за рамки статті.
#Set bandwidth of the interface
:local interfaceBandwidth 100M
/ip firewall mangle
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
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
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 address-list=WoT
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
add chain=prerouting action=mark-packet new-packet-mark=prio_5
Акуратно укладемо розмічений трафік у чергу:
queue tree add max-limit=$interfaceBandw >
:for indexA from=1 to=5 do=
name=( "prio_" . "$indexA" ) \
comment=("Priority" . $indexA . " traffic")
І останнє, якщо Mikrotik підтримує WMM, було б логічно розмітити трафік і для нього.
Робиться це тим самим mangle-ом за допомогою команди set_priority. Згідно з wiki Mikrotik'а, таблиця пріоритетів WMM виглядає досить химерно:
0,3 - best effort
Розмітимо пріоритети, використовуючи самі правила, що й маркування пакетів:
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
add chain=prerouting action=set-priority new-priority=6 dscp=40
add chain=prerouting action=set-priority new-priority=6 dscp=46
add chain=preroutingaction=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
add chain=prerouting action=set-priority new-priority=5 protocol=tcp port=22
add chain=prerouting action=set-priority new-priority=4 address-list=WoT
add chain=prerouting action=set-priority new-priority=3 protocol=tcp port=3389
У принципі, у цьому все.
:foreach i in=[/ip dns cache all find where (name
Або детектувати Skype за допомогою пошуку upnp-правил:
:foreach i in=[/ip firewall nat find dynamic and comment
Але поки що в мене такої потреби немає.
Дякую за увагу!
UPD:У вихідній версії посту в скриптах була помилка (неправильно вказано ланцюжок) через яку трафік не потрапляв у чергу. Наразі вона виправлена.
UPD:У тексті скрипта у статті виявлено помилку. Прошу використати версію з GitHub'а.