Pull to refresh
2759.12
RUVDS.com
VDS/VPS-хостинг. Скидка 15% по коду HABR15

Сам себе РКН или родительский контроль с MikroTik (ч.2)

Reading time10 min
Views14K

Вторая и заключительная статья в цикле организации родительского контроля на оборудовании 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 (вы тут)

Tags:
Hubs:
Total votes 32: ↑31 and ↓1+30
Comments21

Articles

Information

Website
ruvds.com
Registered
Founded
Employees
11–30 employees
Location
Россия
Representative
ruvds