Port knocking — это сетевой защитный механизм, действие которого основано на следующем принципе: сетевой порт является по-умолчанию закрытым, но до тех пор, пока на него не поступит заранее определённая последовательность пакетов данных, которая «заставит» порт открыться. Например, вы можете сделать «невидимым» для внешнего мира порт SSH, и открытым только для тех, кто знает нужную последовательность.

Настройка Nftables

Настроим nftables для открытия порта 22 через port knocking

Данный метод можно переделать для защиты любого порта

Для примера рассмотрю комбинацию из четерех пакетов ICMP (Ping) разного размера (128, 138, 148 и 158 байтов).

#!/usr/sbin/nft -f

flush ruleset

define SSH_KNOCK_PING_LEN1 = 128
define SSH_KNOCK_PING_LEN2 = 138
define SSH_KNOCK_PING_LEN3 = 148
define SSH_KNOCK_PING_LEN4 = 158

table inet filter {
  set s_ip_ssh_knock_step1 { type ipv4_addr; timeout 10s; gc-interval 5s; }
  set s_ip_ssh_knock_step2 { type ipv4_addr; timeout 10s; gc-interval 5s; }
  set s_ip_ssh_knock_step3 { type ipv4_addr; timeout 10s; gc-interval 5s; }
  set s_ip_ssh_knock_step4 { type ipv4_addr; timeout 8hs; gc-interval 30s; }

  chain input {
    type filter hook input priority filter;

    ct state invalid counter drop
    ct state established,related,untracked ip protocol != icmp accept

    ct state new tcp dport ssh ip saddr @s_ip_ssh_knock_step4 counter accept
    icmp type echo-request jump input_knock
    ct state new tcp dport ssh counter drop
  }
  chain input_knock {
    ip saddr @s_ip_ssh_knock_step3 meta length $SSH_KNOCK_PING_LEN4 add @s_ip_ssh_knock_step4 { ip saddr } counter
    ip saddr @s_ip_ssh_knock_step2 meta length $SSH_KNOCK_PING_LEN3 add @s_ip_ssh_knock_step3 { ip saddr } counter
    ip saddr @s_ip_ssh_knock_step1 meta length $SSH_KNOCK_PING_LEN2 add @s_ip_ssh_knock_step2 { ip saddr } counter
    meta length $SSH_KNOCK_PING_LEN1 add @s_ip_ssh_knock_step1 { ip saddr } counter
    }
}

Проверка работы секрипта с windows

ping 172.16.1.67 -l 100 -n 1
ping 172.16.1.67 -l 110 -n 1
ping 172.16.1.67 -l 120 -n 1
ping 172.16.1.67 -l 130 -n 1

Обратите внимание, что размер пакета должен быть на 28 байт меньше чем указан в nftanles. Потому что добавляется 28 бит это заголовков пакета.

Посмотреть правила nftables можно командой

nft list ruleset