Port Knocking в MikroTik

🕒 6 мин.

В этой статье я опишу как настроить Port Knocking в Mikrotik. Я буду вести настройку на версии RouterOS 7.20.8, но на других версиях всё должно настраиваться и работать аналогично.

Port Knocking: что это и как работает

Port Knocking — это метод скрытия сетевых служб, при котором порт остаётся закрытым до тех пор, пока клиент не отправит заранее определённую последовательность соединений на другие порты.

То есть алгоритм примерно следующий:

  1. Порт какой-то службы, например ssh (порт 22), закрыт файерволом.
  2. Клиент отправляет последовательность пакетов на указанные порты в строгом порядке. Например: 7000 -> 8000 -> 9000 (tcp или udp).
  3. Файервол открывает порт 22, но только для ip-адреса того клиента, который постучался в правильной последовательности.

Преимущества Port Knocking:

  • Скрытие служб — порты не видны при сканировании.
  • Защита от брутфорса — злоумышленник не знает, куда стучаться, и не может напрямую атаковать сервис.
  • Двухфакторный доступ — нужно знать не только пароль, но и последовательность стука.
  • Лёгкость внедрения — не требует изменения кода приложения, работает на уровне фаервола.

Недостатки Port Knocking:

  • Возможность вычислить паттерн — продвинутый атакующий с доступом к трафику может вычислить последовательность портов для стука.
  • Сложность для пользователей — пользователю нужна программа или скрипт для отправки последовательности пакетов на определённые порты.

А также важно помнить что Port Knocking не заменяет другие меры, например: шифрование, SSH-ключи, fail2ban, 2FA и т.п.

В этой статье будем реализовывать следующую схему:

Доступ из сети Интернет к серверу осуществляется с помощью проброса порта. При этом проброс порта работает только для белого списка адресов (white-list). А чтобы попасть в white-list нужно отправить последовательно 3 пакета на udp порты: 7000, 8000, 9000. Дополнительно: исходящий ip-адрес клиента попадает в white-list не на всегда, а на 12 часов.

Настройка роутера MikroTik

Настройка правил файервола

Для начала произведём настройку файервола, для этого в окне WinBox открываем IP / Firewall / Вкладка Filter Rules.

Создаём первое, самое верхнее, правило:

Вкладка General:

  • Chain: input
  • Protocol: udp
  • Dst. Port: 7000
  • In. Interface: wan


Вкладка Action:

  • Action: add src to address list
  • Address List: knock-1
  • Timeout: 00:00:05

Объяснение! Если пакет приходит в цепочку input (то есть самому роутеру), на udp порт 7000, на интерфейс wan (интерфейс к которому подключен ваш провайдер). То помещаем исходящий ip-адрес этого клиента (add src to address list) в список — knock-1, на 5 секунд.

Второе правило:


Вкладка General:

  • Chain: input
  • Src. Address: knock-1
  • Protocol: udp
  • Dst. Port: 8000
  • In. Interface: wan

Вкладка Action:

  • Action: add src to address list
  • Address List: knock-2
  • Timeout: 00:00:05

Второе правило отличается от третьего только тем что мы ловим пакеты только из списка ip-адресов knock-1 (те кто уже стучались 1-ый раз). Но теперь они должны постучаться на порт udp 8000. Тогда мы поместим исходящий ip-адрес такого клиента во второй список — knock-2.

Третье правило:

Вкладка General:

  • Chain: input
  • Src. Address: knock-2
  • Protocol: udp
  • Dst. Port: 9000
  • In. Interface: wan

Вкладка Action:

  • Action: add src to address list
  • Address List: white-list
  • Timeout: 12:00:00

Третье правило ловит только пакеты с ip-адресов из списка knock-2 (т.е. уже 2-а раза должны были правильно постучаться). А третий раз должны постучаться на порт udp 9000. И в этом случае исходящий ip-адрес такого клиента попадёт в список адресов white-list на 12 часов.

По своему усмотрению вы можете:

  • менять номера портов,
  • менять протоколы (tcp / udp),
  • менять время нахождения в ip адрес листах.

Проброс портов

После того, как мы настроили файервол, можем приступить к настройке проброса портов: IP / Firewall / Вкладка NAT.

Например, у нас есть какой-нибудь сервер Linux с адресом в локальной сети: 192.168.10.15. К нему можно подключаться по ssh (22 порт). И мы хотим дать к этому серверу доступ из интернета. То-есть, пробросим порт 22022 из интернета на 22 порт к этому серверу. Но только для тех, кто есть в списке адресов white-list.

Вкладка General:

  • Chain: dstnat
  • Src. Address List: white-list
  • Protocol: tcp
  • Dst. Port: 22022
  • In. Interface: wan

Вкладка Action:

  • Action: dst-nat
  • To Addresses: 192.168.10.15
  • To Ports: 22

Скрипты и утилиты для стука по портам

Теперь разберёмся, как нам (или нашим клиентам / сотрудникам) можно последовательно стучаться по указанным портам (7000 -> 8000 -> 9000).

Windows

Для windows можем использовать такой скрипт на Powershell (он стучится по udp портам):

# Адрес сервера
$Server = "192.168.1.100"

# Порты для knocking (UDP)
$Ports = @(7000, 8000, 9000)

foreach ($Port in $Ports) {
    Write-Host "Knocking UDP port $Port..."

    $UdpClient = New-Object System.Net.Sockets.UdpClient
    $Bytes = [System.Text.Encoding]::ASCII.GetBytes("knock")
    $UdpClient.Send($Bytes, $Bytes.Length, $Server, $Port) | Out-Null
    $UdpClient.Close()

    Start-Sleep -Milliseconds 500
}

Write-Host "Knocking sequence completed."

А если вы используете не UDP а TCP порты, то скрипт нужно будет немного исправить:

$Server = "192.168.1.100"
$Ports  = @(7000, 8000, 9000)

foreach ($Port in $Ports) {
    Write-Host "Knocking TCP port $Port..."

    try {
        $TcpClient = New-Object System.Net.Sockets.TcpClient

        # Асинхронное подключение
        $Async = $TcpClient.BeginConnect($Server, $Port, $null, $null)

        # Ждём максимум 200 мс
        if (-not $Async.AsyncWaitHandle.WaitOne(200)) {
            $TcpClient.Close()
        }
    }
    catch {
        # Игнорируем ошибки
    }

    Start-Sleep -Milliseconds 500
}

Write-Host "Knocking sequence completed."

Linux

Для Linux будем использовать скрипты написанные на bash. Также сделаем 2 отдельных скрипта для udp и для tcp.

  • Для udp:
#!/bin/bash

SERVER="192.168.10.1"
PORTS=(7000 8000 9000)

for PORT in "${PORTS[@]}"; do
    echo "Knocking UDP port $PORT..."
    echo "knock" | nc -u -w1 "$SERVER" "$PORT"
    sleep 0.5
done

echo "Knocking sequence completed."
  • Для tcp:
#!/bin/bash

SERVER="192.168.10.1"
PORTS=(7000 8000 9000)

for PORT in "${PORTS[@]}"; do
    echo "Knocking TCP port $PORT..."
    nc -z -w1 "$SERVER" "$PORT" 2>/dev/null
    sleep 0.5
done

echo "Knocking sequence completed."

Android

Для Android я буду использовать не скрит а приложение, которое легко установить из Google Play. Называется оно Knock on Ports.

С помощью этого приложения вы создаёте различные комбинации портов для стука.

В этом приложении также есть интересные дополнительные функции:

  • Запуск программы после стука.
  • Стук по расписанию.
  • Проверка определённого ресурса (tcp, udp, icmp) и выполнение автоматического стука если ресурс окажется не доступен.

Возможно вам понравятся и другие мои статьи:

Если понравилась статья, подпишись на мой канал в VK или Telegram.

Мы используем cookie-файлы для наилучшего представления нашего сайта. Продолжая использовать этот сайт, вы соглашаетесь с использованием cookie-файлов.
Принять
Отказаться
Политика конфиденциальности