Mikrotik и блокировка интернета с ограничением траффика в день

 

            В данной статье рассмотрим, как можно реализовать блокировку интернета, за исключением доступа к почте и мессенджерам имея в распоряжении только mikrotik роутер. Плюс сделаем ограничение по траффику в день.

            Вариантов решений блокировки не так чтобы много, т. к. https и другой шифрованный траффик составляет большую часть интернета, поэтому блокировать по содержимому пакета средствами только mikrotik роутера не выйдет. Вариант с прозрачным прокси по этой же причине отбросим (прокси сервис mikrotik не умеет работать с https, а поднять 3proxy на openwrt не каждый mikrotik сможет). Вариант с единственным dns сервером в сети и разрешением резолвить только разрешённые имена возможен (dns запросы не шифруются, следовательно, можно посмотреть пакет и принять решение), но есть проблема с возможностью достучаться по ip адресу и кэшем dns на устройствах. Последний вариант это белые адрес листы, который и рассмотрим.

            Задача: заблокировать весь интернет за исключением почтовых сервисов mail.ru, gmail.com и mail.yandex.ru через веб и мессенджеров viber и whatsapp через смартфоны.

            Выполнение задачи нужно начать с заполнения адрес листов, в которые будут включены ip адреса и сети необходимые для работы требуемых сервисов. Для этого перейдём  IP → firewall → address lists и добавляем нужные адреса и сети (можно использовать доменные имена). Например так:

/ip firewall address-list

add address=mail.ru list=whitelist

add address=18.201.5.0/24 comment="viber voice" list=whitelist

Использование доменных имён позволит избежать проблем, если сервис переедет на другой ip адрес, но как оказалось большие проекты используют множество ip адресов и сетей для работы, поэтому для отлова используем инструмент микротика torch или wireshark, или любой другой подобный инструмент.

            После того как адрес листы заполнены можно настроить firewall. Например так:

/ip firewall filter

add action=accept chain=forward comment="accept established & related " \

    connection-state=established,related

add action=accept chain=input connection-state=established,related

add action=accept chain=forward comment="accept forward white addreses" \

    dst-address-list=whitelist

add action=reject chain=input comment="reject new & invalid connections" \

    connection-state=invalid,new reject-with=icmp-host-unreachable

add action=reject chain=forward connection-state=invalid,new reject-with=\

    icmp-host-unreachable

 где первое и второе правила разрешают уже установившиеся соединения для того, что бы снизить нагрузку на роутер; третье правило разрешает устанавливать соединения с хостами из адрес листа; четвёртое и пятое запрещают остальное. Действие reject-with=icmp-host-unreachable нужно, что бы не разрешённое соединение сразу сбрасывалось, а не висело в попытках соединиться, соответственно не висела веб страничка ожидая очередной порции рекламы или другого мусора.

            Далее проверяем, смотрим что не работает, ищем torchем, добавляем в адрес листы, готово.

            Теперь о количестве траффика. Эту задачу можно решить с помощью скриптов, которые будут опрашивать счётчик rx-byte и tx-byte интерфейса, который смотрит в интернет и включать запрещающее правило в firewall, когда rx-byte+tx-byte достигнет определённого значения. Ничего сложного, но есть один нюанс: при выключении или перезагрузке микротик роутера эти счётчики сбрасываются. Поэтому данные нужно будет переодически писать в энергонезависимую память. Это может быть флеш память в микротике или какой-нибудь внешний диск (usb флешка, например). Флеш память в микротике, как и любая флеш память, имеет ограниченный ресурс на запись, поэтому надо понимать, что слишком часто на неё лучше не писать, что бы не израсходовать весь ресурс флешки в первый же месяц.

            Скрипт подсчёта траффика:

:global temprx;

global temptx ;\r\

:local rx [/interface get [find name=ether1] rx-byte ] ;

:local tx [/interface get [find name=ether1] tx-byte ] ;

/file set flash/rx.txt contents=((\$rx - \$temprx) + [/file get flash/rx.txt contents]);

/file set flash/tx.txt contents=((\$tx - \$temptx) + [/file get flash/tx.txt contents]);

:set temprx \$rx;

:set temptx \$tx;

            Скрипт проверки количества траффика и включения запрещающего правила:

:local total {[/file get flash/rx.txt contents]+[/file get flash/tx.txt contents ]};

:if (total > 490000000) do={/ip firewall filter enable numbers=1};

            Скрипт проверки текущей даты (т. к. лимит выдаётся на день):

:global currentdate [/system clock get date];

:global lastdate [/file get flash/lastdate.txt contents];

:if (\$lastdate!=\$currentdate) do={/system script run reset};

            Скрипт сброса траффика, прописывания текущей даты в файл и отключения запрещающего правила:

:global currentdate [/system clock get date];

/file set flash/rx.txt contents="0";

/file set flash/tx.txt contents="0";

/ip firewall filter disable numbers=1;

/file set flash/lastdate.txt contents=$currentdate;"

            Запрещающее правило в firewall:

add action=reject chain=forward reject-with=icmp-host-unreachable

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