mikrotik: sstp и веб сервер на одном порту

Я тут подумал, чего бы мне не запилить домашний sstp сервер? VPN этого типа бегает по 443 порту и не привлекает лишнего внимания. Вот только есть одна проблема. 443 порт у меня уже занят и отдавать его VPN серверу я категорически не хочу. И тут я вспомнил про port knocking.

Термин «Port knocking» подразумевает сценарий, когда удалённая машина заранее условленным образом «стучится» на определённый порт. Тем самым она сообщает свой адрес и намерение подключиться к приватному сервису. (как например наш sstp). Сервер в свою очередь открывает для удалённой машины такую возможность.

А теперь практическая чаcть.

Первым делом, нам нужно определиться с условием для «простукивания». И тут всё зависит от вашей фантазии. Но, на мой взгляд, идеальным вариантом было бы стучаться на всё тот же 443 порт. Это сведёт к минимуму «подозрительность» данной активности.

Как оказалось, RouterOS позволяет это сделать чрезвычайно простым путём (как всегда ;)). Забегаем в ip > firewall > Mangle и создаём правило:

/ip firewall mangle add chain=prerouting protocol=tcp dst-port=443 content="tuktuktuk" action=add-src-to-address-list address-list="sstp-in" address-list-timeout="00:01:00"

Идея тут заключается в том, что так или иначе, из https запроса вполне легко вытаскивается sni заголовок. А вот то самое «кодовое слово» будет передаваться в качестве доменного имени (например tuktuktuk.ex.uz). Как только наш тик получит GET запрос на это доменное имя, он создаст запись в src листе фаерволла. Её мы будем использовать в правиле dstnat:

/ip firewall nat add action=dst-nat chain=dstnat dst-address-list=\
    "router interfaces" dst-port=443 protocol=tcp src-address-list=!sstp-in \
    to-addresses=192.168.88.123

Таким образом, мы натим все соединения на 443 порт на вебсервер 192.168.88.123, кроме тех, которые пришли от адресов из списка sstp-in.
Для последних это правило не работает и пойдут прямиком на sstp сервер микротика.

Настраиваем клиента

Теперь на стороне клиента нужно добавить задачу в расписание, которая будет периодически стучаться, обновляя свой динамический адрес в src листе сервера. Кстати, записи туда добавляются с таймаутом в 1 минуту.

Самый простой вариант, это зайти в system > Sheduler и добавить задачу с интервалом в 1 минуту и командной строкой:

/tool fetch url=https://tuktuktuk.ex.uz/ mode=https keep-result=no

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

Ну а если вы не хотите отправлять лишние запросы, скрипт шедалера можно сделать таким:

{
:if ([/interface get sstp-out running]=true) \
do={
 :log info "SSTP interface running. skeep knocking"
} \
   else={[/tool fetch url=https://tuktuktuk.ex.uz/ mode=https keep-result=no]}
}