@ECHO OFF
echo ICMP KNOCK STEP 1
ping x.x.x.x -n 1 -f -l 300 > Nul
TIMEOUT /T 11 /NOBREAK
echo ICMP KNOCK STEP 2
ping x.x.x.x -n 1 -f -l 350 > Nul
TIMEOUT /T 11 /NOBREAK
echo ICMP KNOCK STEP 3
ping x.x.x.x -n 1 -f -l 650 > Nul
echo ICMP KNOCK END
start "" mstsc.exe -v:x.x.x.x:48000
TIMEOUT /T 11 /NOBREAK
Этот скрипт, реализует ICMP-нок (англ. knock) — последовательную отправку специальных ICMP-пакетов (ping) с определёнными параметрами перед подключением к RDP (порт 48000).
Что происходит по шагам:
1. echo ICMP KNOCK STEP 1 — вывод сообщения в консоль.
2. ping x.x.x.x -n 1 -f -l 300 > Nul — отправка 1 ICMP-пакета (ping) на IP x.x.x.x с:
- -f (Don't Fragment) — флаг запрета фрагментации.
- -l 300 — размер данных 300 байт.
Результат скрыт (> Nul).
3. TIMEOUT /T 11 /NOBREAK — пауза 11 секунд (игнорирует нажатия клавиш).
4. Затем второй «нок» с размером 350 байт и снова пауза 11 секунд.
5. Третий «нок» с размером 650 байт (без паузы после него).
6. start "" mstsc.exe -v:x.x.x.x:48000 — запуск стандартного RDP-клиента Windows с подключением к порту 48000 указанного хоста.
7. В конце — ещё одна пауза 11 секунд (возможно, чтобы удержать консоль открытой или подождать подключения).
Для чего это может использоваться:
- Скрытый доступ — на маршрутизаторе или брандмауэре настроено правило: порт 48000 (RDP) закрыт для всех, но если приходит определённая последовательность ICMP-пакетов с заданными размерами (300, 350, 650) с определённым интервалом, то временно открывается доступ с этого IP-адреса.
- Обход простых фильтров — защита от сканирования портов: сканер не увидит открытый порт, пока не будет отправлена корректная последовательность «ноков».
Обратите внимание:
- Удалённый IP x.x.x.x должен быть настроен соответствующим образом, иначе скрипт бесполезен.
- Пинг с флагом -f и размером пакета может не работать через некоторые узлы сети (если MTU на пути меньше, пакет будет отброшен). Для теста 300 и 350 байт — нормально, 650 — тоже обычно проходит.
Как проверить, сработает ли подключение:
Вручную откройте mstsc.exe и попробуйте подключиться к x.x.x.x:48000. Если без предварительного запуска скрипта не подключается — вероятно, «нок» действительно необходим.
Как настроить: Скрытый доступ — на маршрутизаторе или брандмауэре настроено правило: порт 48000 (RDP) закрыт для всех, но если приходит определённая последовательность ICMP-пакетов с заданными размерами (300, 350, 650) с определённым интервалом, то временно открывается доступ с этого IP-адреса.
Идея cпрятать RDP за "стуком" в дверь на уровне маршрутизатора — отличный способ защиты. Настроить его можно на большинстве устройств с помощью встроенных средств, будь то профессиональный роутер MikroTik, сервер под Linux или даже простой роутер Keenetic.
---
Вариант 1: RouterOS (MikroTik)
На роутерах MikroTik это самый гибкий и распространенный способ.
1. Создайте скрипт-обработчик
Перейдите в System → Scripts и добавьте новый скрипт (например, add-rdp-whitelist).
bash
# Добавляем IP, с которого пришел корректный "стук", в список адресов на 5 минут
/ip firewall address-list add list=rdp_whitelist address=$"knock-ip" timeout=00:05:00
:log info "Port knock accepted from $"knock-ip""
2. Добавьте правила в Firewall
Теперь перейдите в IP → Firewall на вкладку Filter Rules.
Скрипт должен зафиксировать последовательность ICMP-пакетов с нужным размером (300, 350, 650) и интервалом между ними (около 11 секунд).
Используйте три правила, которые ставят метки при "ударах":
| Шаг | Цепочка | Protocol | Параметры | Dst. Port | Действие |
| 1 | Input | ICMP | Packet Length=300 | — | add src to list "knock_stage1", DROP |
| 2 | Input | ICMP | Packet Length=350 | — | allow only from list "knock_stage1", add to list "knock_stage2", DROP |
| 3 | Input | ICMP | Packet Length=650 | — | allow only from list "knock_stage2", run script "add-rdp-whitelist", DROP |
После правил "стука" добавьте правило разрешения доступа к порту 48000 только для избранных:
* Chain: Input
* Protocol: TCP
* Dst. Port: 48000
* Src. Address List: rdp_whitelist
* Action: Accept
---
Вариант 2: Linux (nftables)
Современный nftables пришел на смену iptables и отлично подходит для такой задачи. Механизм использует динамические наборы IP-адресов.
Добавьте этот код в ваш конфигурационный файл nftables.conf (или выполните команды в терминале):
bash
# Создаем наборы-этапы для отслеживания последовательности
nft add set ip filter knock_stage1 { type ipv4_addr\; flags timeout\; }
nft add set ip filter knock_stage2 { type ipv4_addr\; flags timeout\; }
nft add set ip filter knock_stage3 { type ipv4_addr\; flags timeout\; }
# Добавляем правило для запуска последовательности (шаг 1. Размер 300)
nft add rule ip filter input icmp type echo-request icmp length 300 add @knock_stage1 { ip saddr timeout 10s } drop
# Шаг 2. Размер 350 (сработает только если IP есть в stage1)
nft add rule ip filter input ip saddr @knock_stage1 icmp type echo-request icmp length 350 add @knock_stage2 { ip saddr timeout 10s } drop
# Шаг 3. Размер 650 (сработает только если IP есть в stage2)
# Добавляем IP в белый список для порта 48000, если "стук" верный
nft add rule ip filter input ip saddr @knock_stage2 icmp type echo-request icmp length 650 add @rdp_whitelist { ip saddr timeout 300s } drop
После этого разрешите подключение к RDP (порт 48000) только для IP-адресов из белого списка rdp_whitelist.
---
Вариант 3: Keenetic (Интернет-Центр)
На роутерах Keenetic это реализуется через систему компонентов.
1. Установите компоненты "Кластер" и "Системный планировщик Cron".
2. Скачайте и установите пакет knockd через меню Управление пакетами (или вручную).
3. Настройте демон knockd через конфигурацию (обычно файл knockd.conf), задав последовательность из трех ICMP-запросов с размерами 300, 350 и 650 байт.
4. В ответ на корректный "стук" пропишите выполнение скрипта, который добавит IP-адрес в исключения для порта 48000.
---
Важный совет по параметрам ICMP
Чтобы ваш скрипт с ping -f -l работал точно и не сбивался из-за сетевых заголовков, стоит учитывать небольшую техническую деталь.
Команда ping -l 300 на Windows отправляет 300 байт данных. Однако при прохождении по сети к ним добавляется 8 байт ICMP-заголовка и 20 байт IP-заголовка. В итоге маршрутизатор видит пакет полным размером 328 байт.
Поэтому на роутере нужно проверять длину пакета (ICMP length) с поправкой +28 байт:
* Для -l 300 → искать пакет размером 328.
* Для -l 350 → искать пакет размером 378.
* Для -l 650 → искать пакет размером 678.
Если в настройках файрвола есть поле Packet Length, используйте эти значения. Если нет — большинство систем (как в примерах выше) позволяют указывать длину именно *с заголовками*.
Эта настройка убережет вас от ситуации, когда "ключ" идеален, но дверь не открывается из-за технической разницы в подсчете байт.