Вторая и заключительная статья в цикле организации родительского контроля на оборудовании MikroTik. Ранее подробно рассмотрены организация DNS, работа Firewall Filter и Ip Kid-control. В текущей части поговорим о прикладном применении маркировки трафика посредством Firewall Mangle, а также сделаем общие за представленный цикл статей выводы, касающихся возможностей RouterOS по организации родительского контроля.

▍ 1. Firewall Mangle


Рассмотрим имеющиеся возможности по маркировке трафика в контексте родительского контроля. Firewall Mangle подробно изучается на курсе MikroTik Certified Traffic Control Engineer (MTCTCE), тема требует внимательности и сосредоточенности. Разметим проходящий через маршрутизатор трафик:

/ip firewall mangle
add action=mark-connection chain=prerouting comment="WAN=>LAN connections" connection-nat-state="" in-interface=WAN new-connection-mark="WAN=>LAN connections" passthrough=yes
add action=mark-packet chain=prerouting comment="WAN=>LAN packets" connection-mark="WAN=>LAN connections" new-packet-mark="WAN=>LAN packets" passthrough=yes
add action=mark-connection chain=forward comment="LAN=>WAN connections" connection-mark=no-mark in-interface=bridge_home new-connection-mark="LAN=>WAN connections" out-interface=WAN passthrough=yes
add action=mark-packet chain=forward comment="LAN=>WAN packets" connection-mark="LAN=>WAN connections" new-packet-mark="LAN=>WAN packets" passthrough=yes
add action=mark-packet chain=forward comment="LAN=>WAN packets Children" new-packet-mark="LAN=>WAN packets Children" packet-mark="LAN=>WAN packets" passthrough=yes src-address-list=children
add action=mark-packet chain=postrouting comment="WAN=>LAN connections Children" dst-address-list=children new-packet-mark="WAN=>LAN packets Children" packet-mark="WAN=>LAN packets" passthrough=yes

В текстовом варианте они плохо представляются, поэтому объясним их по скриншоту. Как видно, трафик пользователей размечается на входящий (WAN => LAN) и исходящий (LAN => WAN).



На самом деле, так делать не нужно, ведь достаточно маркировать только исходящий трафик, потому что входящий – это всегда ответ на исходящий, в контексте домашнего устройства. TCP соединение устанавливается по инициативе пользователя, так же как и UDP пакеты к нам идут в ответ на наши запросы.

Итого нам нужно пометить весь исходящий трафик. Сразу будем выделять только детские соединения. Весь трафик разделим на четыре категории: DNS, HTTPS, QUIC и остальные соединения. DNS будем отлавливать в цепочки prerouting, сначала помечая соединения, затем пакеты в этих соединениях:

add action=mark-connection chain=prerouting comment="LAN=>WAN connections DNS Children" connection-mark=no-mark dst-port=53 in-interface=bridge_home new-connection-mark="LAN=>WAN connections DNS Children" passthrough=yes protocol=udp src-address-list=children
add action=mark-packet chain=prerouting comment="LAN=>WAN packets DNS Children" connection-mark="LAN=>WAN connections DNS Children" new-packet-mark="LAN=>WAN packets DNS Children" passthrough=yes

Чтобы понять, почему это нужно делать именно в prerouting, следует обратиться к схеме прохождения трафика внутри маршрутизатора MikroTik. Например, можно воспользоваться рисунком от этой компании.



Если первичным DNS сервером (/ip dhcp-server network add address=10.0.0.0/24 dns-server=10.0.0.1 gateway=10.0.0.1 netmask=24) будет выступать ваш роутер, то запросы от клиентов пойдут именно к нему, т. е. в Input Interface. Далее уже будем работать с цепочкой Forward. Помечаем все детские соединения. Среди них выделяем соединения HTTPS и QUIC:

add action=mark-connection chain=forward comment="LAN=>WAN connections Children" connection-mark=no-mark in-interface=bridge_home new-connection-mark="LAN=>WAN connections Children" out-interface=WAN passthrough=yes src-address-list=children
add action=mark-connection chain=forward comment="LAN=>WAN connections HTTPS Children" connection-mark="LAN=>WAN connections Children" dst-port=443 new-connection-mark="LAN=>WAN connections HTTPS Children"  passthrough=yes protocol=tcp
add action=mark-connection chain=forward comment="LAN=>WAN connections QUIC Children" connection-mark="LAN=>WAN connections Children" dst-port=443 new-connection-mark="LAN=>WAN connections QUIC Children" passthrough=yes protocol=udp

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

add action=mark-packet chain=forward comment="LAN=>WAN packets Children HTTPS+QUIC" connection-mark="LAN=>WAN connections HTTPS Children" new-packet-mark="LAN=>WAN packets Children HTTPS+QUIC" passthrough=yes
add action=mark-packet chain=forward comment="LAN=>WAN packets Children HTTPS+QUIC" connection-mark="LAN=>WAN connections QUIC Children" new-packet-mark="LAN=>WAN packets Children HTTPS+QUIC" passthrough=yes

Далее необходима перемаркеровка пакетов. Для чего это нужно, будет понятно далее. На выходе имеем все детские пакеты (HTTPS, QUIC, !HTTPS и !QUIC), идущие в цепочке Forward:

add action=mark-packet chain=forward comment="LAN=>WAN packets Children ALL" connection-mark="LAN=>WAN connections Children" new-packet-mark="LAN=>WAN packets Children ALL" passthrough=yes
add action=mark-packet chain=forward comment="LAN=>WAN packets Children ALL" new-packet-mark="LAN=>WAN packets Children ALL" packet-mark="LAN=>WAN packets Children HTTPS+QUIC" passthrough=yes

Для самоконтроля, рекомендую на каждом этапе проводить зеркалирование пакетов и их ручную обработку в Wireshark (как настроить прием трафика, рассмотрено ранее):

add action=sniff-tzsp chain=forward comment=Sniffer_for_Test disabled=yes packet-mark="LAN=>WAN packets Children"  sniff-target=192.168.1.1 sniff-target-port=37008

Трафик размечен, теперь прикрутим сюда параметры блокировки. В Firewall Mangle во вкладке Advanced имеются следующие интересующие нас возможности: Content и TLS Hosts.



Параметр Content позволяет задать текст, который будет искаться во всех проходящих через маршрутизатор пакетах. В первую очередь, это подойдет для HTTP соединений по понятным причинам. Для HTTPS и QUIC это тоже работает. В качестве примера рассмотрим соединение с одним из сайтов, о которых нельзя говорить вслух:

openssl s_client -servername xvideos.com:443 -tlsextdebug -connect xvideos.com:443

CONNECTED(00000003)
TLS server extension "server name" (id=0), len=0
TLS server extension "renegotiation info" (id=65281), len=1
0000 - 00                                                .
TLS server extension "EC point formats" (id=11), len=4
0000 - 03 00 01 02                                       ....
TLS server extension "session ticket" (id=35), len=0
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
verify return:1
depth=0 CN = *.xvideos.com
verify return:1
Certificate chain
 0 s:CN = *.xvideos.com
   i:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
 1 s:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
   i:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
 2 s:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
   i:C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
Server certificate
-----BEGIN CERTIFICATE-----
MIIFtzCCBJ+gAwIBAgIQCP+nsUrbzwj8B5SCxl4RzjANBgkqhkiG9w0BAQsFADCB
…….
kvUG3hiNVNNEK4n1a8M3a32muX6G9vm17N6j
-----END CERTIFICATE-----
subject=CN = *.xvideos.com
issuer=C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA

Видно, что его доменное имя несколько раз проходит в устанавливаемом соединении. Используем его в качестве фильтра, для всех типов размеченных пакетов: DNS и остального трафика Именно поэтому нужна была перемаркеровка пакетов, выполненная ранее в цепочке Forward:

add action=mark-packet chain=prerouting comment="Children Filter Content \"xvideo\"" content=xvideo new-packet-mark="Children Filter" packet-mark="LAN=>WAN packets DNS Children" passthrough=no
add action=mark-packet chain=prerouting comment="Children Filter Content \"porn\"" content=porn new-packet-mark="Children Filter" packet-mark="LAN=>WAN packets DNS Children" passthrough=no
add action=mark-packet chain=prerouting comment="Children Filter Content \"drug\"" content=drug new-packet-mark="Children Filter" packet-mark="LAN=>WAN packets DNS Children" passthrough=no

add action=mark-packet chain=forward comment="Children Filter content \"porn\"" content=porn new-packet-mark="Children Filter" packet-mark="LAN=>WAN packets Children ALL" passthrough=no
add action=mark-packet chain=forward comment="Children Filter Content \"drug\"" content=drug new-packet-mark="Children Filter" packet-mark="LAN=>WAN packets Children ALL" passthrough=no

Конечно, такой анализ сильно грузит процессор роутера. Как видно, при срабатывании хотя бы одно из правил ставится запрет на дальнейшую перемаркировку трафика, что разгрузит маршрутизатор (passthrough=no).

Параметр TLS Hosts позволяет задать SNI или Server Name Indication – расширение популярного широко используемого криптографического протокола TLS. Смысл SNI в том, что если в настройках web сервера включена поддержка технологии, то на одном IP адресе может размещаться неограниченное количество сайтов, работающих по HTTPS. Изначально HTTPS можно было использовать только при наличии выделенного IP адреса. Если возникала необходимость разместить на сервере второй сайт, работа с которым была бы возможна по защищенному соединению, нужно было использовать другой белый IP. В современном мире, конечно, на одном сервере хостится огромное количество сайтов.
Рассмотрим как проверить SNI на сервере:

openssl s_client -servername xvideos.com:443 -tlsextdebug -connect xvideos.com:443 | grep 'TLS'

TLS server extension "server name" (id=0), len=0
TLS server extension "renegotiation info" (id=65281), len=1
TLS server extension "EC point formats" (id=11), len=4
TLS server extension "session ticket" (id=35), len=0…

Наличие в выводе строки TLS server extension «server name» (id=0), len=0 будет означать, что SNI используется, и на сервере с одним IP адресом можно разместить любое количество сайтов. Таким образом, можно помечать пакеты на основании параметра TLS Hosts:

add action=mark-packet chain=forward comment="Children Filter SNI \"habr.com\"" new-packet-mark="Children Filter" packet-mark="LAN=>WAN packets Children HTTPS+QUIC" passthrough=no protocol=tcp tls-host=habr.com
add action=mark-packet chain=forward comment="Children Filter SNI \"xvideo\"" content=xvideo new-packet-mark="Children Filter" packet-mark="LAN=>WAN packets Children HTTPS+QUIC" passthrough=no

Запретим дальнейшую перемаркеровку пакетов (passthrough=no) и поставим эти правила перед правилами с параметром Content. Говорят, таким же образом работает великий китайский firewall, но при этом он умеет лезть еще глубже. Жалко пока нет технических подробностей.

Во вкладке Mangle Extra для решения поставленной задачи нам ничего не подойдет, увы…



Теперь соберем все правила Mangle воедино по следующей схеме:

LAN=>WAN connections DNS Children
LAN=>WAN packets DNS Children
Children Filter

LAN=>WAN connections Children
LAN=>WAN connections HTTPS Children
LAN=>WAN connections QUIC Children
LAN=>WAN packets Children HTTPS+QUIC
Children Filter

LAN=>WAN packets Children ALL
Children Filter


Пакеты, помеченные как Children Filter, будем дропать в Firewall Filter. Иллюстрация ниже, взятая опять же у этих ребят, объясняет почему это нужно делать именно там, а не в результате, например, роутинга:



Блокирующее правило придется поставить самым первым в цепочке Forward, иначе пакеты, подлежащие фильтрации, перескочат через Firewall:

/ip firewall filter
add action=accept chain=input comment="Accept established,related" connection-state=established,related
add action=drop chain=input comment="Drop invalid" connection-state=invalid
add action=drop chain=forward comment="Drop Children Filter" packet-mark="Children Filter"
add action=accept chain=forward comment="Accept established,related" connection-state=established,related
add action=drop chain=forward comment="Drop invalid" connection-state=invalid
add action=drop chain=forward comment=Drop_sites_by_address_list dst-address-list=Block_site_by_dns_name

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

Упомяну еще про /ip firewall layer7-protocol. Данный фильтр позволяет искать совпадения в первых 2 KB трафика (или 10 первых пакетах) по регулярным выражениям в ICMP, TCP и UDP потоках. Не рекомендую его использовать, слишком вероятностно все там работает и очень сильно загружает процессор роутера.

▍ 2. Заключение


RouterOS обладает различными возможностями по организации родительского контроля. В статьях представлены различные подходы: работа с DNS протоколом, Firewall Filter, Firewall Mangle и Kid-Control. Последний является средством автоматизации от MikroTik и не несет самостоятельных инженерных решений. Что же лучше использовать: работу с DNS, Firewall Filter или Firewall Mangle?

Работа DNS протокола неизбежна связана с кешированием, как на промежуточных серверах, так и на вашем роутере и даже в операционной системе. Нельзя сказать, чтобы это прямо-таки был минус, но нужно учитывать. Чтобы вы, как родитель, не подставили в DNS ответ, но до него дело может даже не дойти. Устройство ребенка извлечет IP адрес запрашиваемого ресурса из своего собственного хранилища. А вот то, что рано или поздно шифрованный DNS прочно войдет в нашу жизнь, нужно понимать уже сейчас. Поэтому в будущем актуальность эксплуатации собственных DNS серверов или коммерческих аналогов, по моему мнению, сохранится. Для данного подхода придется задействовать дополнительные технические ресурсы и, самое главное, поддерживать всю эту инфраструктуру в исправном и актуальном состоянии, что, скорее всего ляжет на ваши сисадминские плечи.

Дропать пакеты по IP адресу в Firewall Filter – достаточно топорное решение. Автоматический резолвинг доменных имен работает хорошо. Однако поле TLS Hosts в Firewall Mangle имеет перед ним сильное преимущество, так как позволяет фильтровать и субдомены. Ведь забивать их все в address-list совсем не хочется. А если на одном IP адресе окажется несколько сайтов, что было достаточно частой проблемой в период известных блокировок Роскомнадзора, то ничего хорошего из подобного подхода не выйдет. Грамотно разметить трафик в Firewall Mangle – это хороший навык, который позволяет решать много инженерных задач, в том числе таких как, приоритезация трафика и балансировка. Поэтому он мне нравится больше других.

Параметр Content может показаться исключительно хорошим решением, однако прогон толстого трафика через не достаточно сильный MikroTik по множеству фильтров может перегрузить центральный процессор роутера. Поэтому это остается последней мерой качественной фильтрации трафика.

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

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

Часть 1
Часть 2 (вы тут)

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


  1. AcidVenom
    28.10.2021 18:58

    Не рекомендую его использовать, слишком вероятностно все там работает и очень сильно загружает процессор роутера.

    Это неправда, Content нагружает процессор сильнее, так как лезет во все пакеты.


    1. olegtsss Автор
      28.10.2021 19:07

      Мы весь трафик дифференцируем по нужной маркировке. Это делается достаточно тонко. И только в нужных пакетах лезем в content. L7 фильтр работает же с регулярными выражениями, а это совсем другая история.


      1. AcidVenom
        28.10.2021 19:46

        Что мешает точно так же лезть с помощью L7? Ничего.
        Сравнение есть в курсе MTCSE, слайд, увы, не взял.


        1. olegtsss Автор
          28.10.2021 19:50

          /system resource print interval=00:00:00.2
          Покажет, что там с нагрузкой.


        1. olegtsss Автор
          29.10.2021 03:31

          Работы с L7 фильтром связана с регулярными выражениями, требующими гораздо большей вычислительной мощности.


  1. max_rip
    28.10.2021 23:08

    Техническая реализация это самое простое, а вот наполнение списка...

    Так что тут вне конкуренции Яндекс днс или скайднс.

    Также кроме фильтра контента, надеюсь будет раскрыт ещё контроль времени, хотя эта функция присутствует из коробки. Но не без проблем. Может есть более интересные варианты.


    1. olegtsss Автор
      29.10.2021 03:33

      В первой части статьи идет разговор как раз о этом.


  1. ba00
    28.10.2021 23:17

    Здравствуйте.

    А как сейчас обстоит дело с блокировками ютуба на микротике для телефонов ? Всё что описано про маркировку пакетов отлично работает только для ПК, а вот для телефона на андроиде не хочет работать от слова совсем.


    1. olegtsss Автор
      29.10.2021 03:33

      Вы имеете ввиду работу мобильного приложения Ютуб?


      1. ba00
        29.10.2021 10:07

        Да. Возможно оно там на какой то свой домен ходит, потому как то что маркируется по правилу ^.+(youtube).*$ на десктопе работает, а на андроиде никак.


        1. olegtsss Автор
          29.10.2021 10:15

          Интересно, я попробую и напишу позже.


        1. AcidVenom
          29.10.2021 10:37

          Регулярку поправьте хотя бы на ^.*(youtube).*$


  1. Wesha
    28.10.2021 23:25
    +3

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

    Мне, например, объяснили, как работает механизм наркотического привыкания. Позднее показали парочку "привыкших" и до какого состояния они себя довели. Знаете, очень отрезвляюще. Желания "попробовать" никогда не возникало — такое дерьмо сами пробуйте.


    1. olegtsss Автор
      29.10.2021 03:37
      +4

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


  1. Worky
    29.10.2021 11:05

    Очень нужные статьи! Но сложно: даже не всякий эникейщик осилит, а простые граждане и подавно. Либо нужно что то более просто настраиваемое в интерфейсе, либо не микротик. Как вариант - в будущих версиях РотутерОС добавить фичу контейнеров с ПиХоле.


    1. olegtsss Автор
      29.10.2021 16:49

      Коллеги пишут, что в RouterOS 7 уже имеется контейнеризация, и то, о чем вы написали, посмотрите комментарии к первой части статьи.


  1. NikaLapka
    29.10.2021 11:57
    +1

    Позвольте внести предложение: разделите задачу на двое: во-первых, оставить рабочим лишь кэширующий DNS микротика, во-вторых, L7 проверять только собственный udp 53 микротика. Мне кажется, что это проще.

    В последствии, можно рассмотреть вариант просто со списком доверенных и заблокированных AS.


    1. AcidVenom
      29.10.2021 13:28

      Можно приземлять все DNS запросы на микрот (action REDIRECT) и создавать статические записи на 127.0.0.1, либо форвардить запросы на безопасный DNS. (фича не работает c DoH)


  1. olegtsss Автор
    29.10.2021 16:53

    Об этом есть в первой части статьи. Достаточно подробно. В этой части предлагается маркировка трафика по схеме:

    LAN=>WAN connections DNS Children LAN=>WAN packets DNS Children Children Filter

    LAN=>WAN connections Children LAN=>WAN connections HTTPS Children LAN=>WAN connections QUIC Children LAN=>WAN packets Children HTTPS+QUIC Children Filter

    LAN=>WAN packets Children ALL Children Filter

    Как видно, первым делом фильтруется содержание запрашиваемых доменных имён.


  1. densenator
    24.11.2021 19:17

    Теперь соберем все правила Mangle воедино по следующей схеме:

    Можно подробнее, как теперь это объединить?


    1. olegtsss Автор
      24.11.2021 19:48

      Напишу в личку.