Port knocking — настолько простой, насколько и эффективный способ защиты вашей локальной сети от несанкционированного доступа снаружи в случаях, когда вам необходимо использовать проброс портов. В этой статье я расскажу, как реализовать этот простой алгоритм авторизации на роутере MikroTik.
О том, что использовать обычный проброс портов не является правильным, я уже упомянул вскользь в статье «Проброс портов в MikroTik«. Но порой все же возникает необходимость давать доступ к удаленным рабочим столам некоторым сотрудникам (например, бухгалтерам в период сдачи отчетности — знакомо, да?).
При этом:
- вам неизвестен адрес, с которого человек будет подключаться и ограничиться правилом в фаерволе у вас не получится;
- использование VPN не представляется возможным в силу нескольких причин, начиная с некомпетентности сотрудника и заканчивая принципиальным запретом VPN на устройствах, через которые этот самый сотрудник будет пытаться подключиться (например, какой-нибудь бесплатный Wi-Fi в отеле на острове Пасхи).
Поможет в этом случае port knocking. Суть этого метода заключается в том, что пользователь, прежде чем получить доступ к чему-то, должен представиться. В классическом решении port knocking используются проколы TCP или UDP — пользователь «простукивает» определенную последовательность портов (обычно не менее трех), после чего его IP добавляется в список адресов с определенными привилегиями: в нашем случае к пробросу порта RDP на его рабочее место. Это как «постучи в дверь три раза, потом — два, потом — пять, чтобы я понял, что это ты». Знакомо, не правда ли?
Суть алгоритма работы firewall при обработке последовательности port knocking заключается в том, что на ряду с проверкой текущего условия происходит проверка: было ли выполнено предыдущее условие.
Последовательность портов для простукивания и ее длина обусловлены только вашей фантазией. Но тут возникает небольшая проблема: если с простукиванием портов из Linux штатными средствами проблем никаких не наблюдается, то с Windows этот номер просто так не пройдет. Но у ваших бухгалтеров наверняка на ноутбуках стоит Windows, а слово Linux они вообще воспринимают, как ругательство.
Пример простукивания портов штатными средствами на Linux:
1 2 3 4 5 |
[root@server~]# nc -zu 1.1.1.1 35123 [root@server~]# nc -zu 1.1.1.1 18357 [root@server~]# nc -zu 1.1.1.1 43249 |
Здесь использовалась команда nc [параметры] [хост] [порт]
, где
- z — говорит программе о том, что нужно просто «стукнуться», не посылая каки-либо дополнительных данных и не слушая ответ;
- u — использование UDP вместо TCP.
К сожалению, данный пример не решает нашей задачи со штатными средствами Windows. А решение простое и лежит на поверхности: вместо UPD или TCP использовать ICMP ping. Принцип port knocking мы оставим, а последовательность портов заменим последовательностью разных размеров пакета.
Выглядеть «простукивание» из Windows будет так:
1 2 3 4 5 |
C:\>ping 1.1.1.1 -f -n 1 -l 432 C:\>ping 1.1.1.1 -f -n 1 -l 521 C:\>ping 1.1.1.1 -f -n 1 -l 598 |
Простой ping с параметрами:
- -4 — использовать IPv4
- -f — запрет фрагментации пакета;
- -n — количество запросов;
- -l — буфер отправки (объем данных, которые мы отправляем «в нагрузку»).
Т.к. стандартный размер MTU — 1500, который к тому же может быть уменьшен всякими VLAN’ами и пр., а нам нужно, чтобы все влезло в один Ethernet фрейм, то рекомендую использовать буфер отправки в диапазоне 0-1000. Еще следует учесть, что размер самого пакета эхо-запроса ICMP «без нагрузки» (с L=0) — 28 байт, т.к. помимо данных там еще присутствует TCP-, ICMP-заголовки и .т.д. Можете погуглить, что из себя представляет ICMP-пакет. Таким образом, на роутере ловим пакеты размером равным [буфер отправки+28].
Теперь наш MikroTik должен распознать последовательность из трех пакетов с размерами 460, 549, 626. «На пальцах» алгоритм выглядит так:
- если размер пакета 460 (432+28), добавить этот IP в список «первый уровень»;
- если размер пакета 549 (521+28) и IP-адрес в списке «первый уровень», добавить этот IP в список «второй уровень».
- если размер пакета 626 (598+28) и IP-адрес в списке «второй уровень», добавить этот IP в список «доступ к пробросу портов по RDP»
Реализация port knocking на MikroTik
Сначала в картинках:
Правила проверки port knocking в фаерволе надо разместить вверху до разрешений related/established. Иначе вы не уйдете дальше первой проверки — будут срабатывать правила related/established.
В скриптах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# # /ip firewall filter #направим входящий ICMP в свою цепочку portKnocking. Для удобства. add action=jump chain=input comment="port knocking check" dst-address=1.1.1.1 jump-target=portKnocking protocol=icmp #первый пинг packet-size=460 add action=add-src-to-address-list address-list=checkLevelOne address-list-timeout=5s chain=portKnocking comment=CheckLevelOne packet-size=460 protocol=icmp #второй ping packet-size=549 и признак успешной проверки первого пинга src-address-list=checkLevelOne add action=add-src-to-address-list address-list=checkLevelTwo address-list-timeout=5s chain=portKnocking comment=CheckLevelTwo packet-size=549 protocol=icmp src-address-list=checkLevelOne #третий пинг packet-size=626 и признак успешной проверки второго пинга src-address-list=checkLevelTwo add action=add-src-to-address-list address-list=AllowRDP address-list-timeout=30m chain=portKnocking comment=AllowRDP packet-size=626 protocol=icmp src-address-list=checkLevelTwo #возврат из цепочки portKnocking add action=return chain=portKnocking # #где-то в правилах, где у вас разрешения на INPUT add chain=input comment="Allow RDP from PortKnockin authorized" protocol=tcp dst-port=4565,4355 src-address-list=AllowRDP # #проброс порта для адресов из списка AllowRDP /ip firewall nat # первому пользователю порт 4565 - > 192.168.33.129:3389 add action=dst-nat chain=dstnat comment=test dst-address=1.1.1.1 dst-port=4565 in-interface=inetTest src-address-list=AllowRDP protocol=tcp to-addresses=192.168.33.129 to-ports=3389 # второму пользователю порт 4355 - > 192.168.33.130:3389 add action=dst-nat chain=dstnat comment=test dst-address=1.1.1.1 dst-port=4355 in-interface=inetTest src-address-list=AllowRDP protocol=tcp to-addresses=192.168.33.130 to-ports=3389 |
Обратите внимание на параметр address-list-timeout
в правилах, где IP добавляется в список адресов. Для этапов проверки я выставляю address-list-timeout=5s
, т.к. считаю, что 5 секунд должно хватить для проверки следующего условия. Для завершающего правила, где адрес добавляется в разрешенные для подключения по RDP, address-list-timeout=30m
— т.е. для подключения к удаленному рабочему столу человеку дается полчаса после успешного «простукивания» MikroTIk’а.
По истечении получаса адрес будет удален из списка AllowRDP, но сеанс не прервется, т.к. будут срабатывать правила allow related/established. Пользователю придется заново «представиться» в случае, если он сам прервет сеанс или за него это сделает плохая связь.
Для автоматизации процесса пишем пакетный файл (.bat или .cmd — кому как больше нравится) следующего содержания:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@echo off rem раз ping 1.1.1.1 -f -n 1 -l 432 > NUL rem подождем секунду, вдруг роутер притормаживает timeout 1 > NUL rem два ping 1.1.1.1 -f -n 1 -l 521 > NUL rem подождем еще секунду timeout 1 > NUL rem три ping 1.1.1.1 -f -n 1 -l 598 > NUL rem запустим клиента удаленного рабочего стола, указав адрес сервера и порт mstsc.exe /v:1.1.1.1:4565 |
Теперь осталось только выслать каждому пользователю свой файл.
Как вы поняли, реализация алгоритма с простукиванием портов не только аналогична описанной выше, но даже проще — там не надо заморачиваться с размером пакета, а просто указать порт. Но для Windows нужны свои костыли…
Реклама: