Fwknop - современный port knocking для Linux

fwknop реализует схему авторизации, известную как Single Packet Authorization (SPA), для надежной защиты сервисов. Для авторизации SPA требуется всего один зашифрованный пакет, который невозможно воспроизвести повторно и который проходит аутентификацию с помощью HMAC.

Описание Fwknop

Fwknop (FireWall KNock OPerator) - это инструмент для динамического управления правилами брандмауэра на основе криптографической аутентификации. Он позволяет реализовать SPA (Single Packet Authorization) - авторизацию с помощью одного пакета.

Fwknop позволяет полностью скрыть порты приложений от сканеров и ботов. Порт необходимого сервиса открывается только после получения корректного SPA пакета. SPA пакет содержит зашифрованное сообщение с временной меткой и HMAC-подписью.

Схема работы следующая:

Клиент  
|  
| SPA пакет (UDP 62201)  
v  
fwknopd  
|  
| nft add element ...  
v  
Открытие SSH (или другого приложения) на некоторое время (только для этого клиента)

Полезные ссылки:

Сравнение с port knocking:

  • При использовании Port Knocking отправляют обычно 3 или больше пакетов. А при Fwknop - достаточно 1 пакета, это позволяет аутентифицироваться почти мгновенно.
  • В Port Knocking шифрование отсутствует, вы просто стучитесь в определённой последовательности на определённые порты. А в Fwknop шифрование это основа. Вы отсылаете зашифрованный пакет с подписью. А сервер в свою очередь расшифровывает пакет и проверяет подпись.
  • Port Knocking выглядит как последовательное сканирование портов. В отличие от этого Fwknop использует всего 1 пакет и не детектируется как сканирование.

Ограничения fwknop:

  • не спасает при компрометации клиента;
  • SPA пакет можно заблокировать файрволлом провайдера;
  • требует синхронизации времени;
  • усложняет автоматизацию некоторых сценариев.

Процесс настройки будет показан на Debian 13, а для административных действий будет использован sudo.

Установка и настройка файрволла nftables

Устанавливаем nftables, если он ещё не установлен:

sudo apt update && \
  sudo apt install nftables

Настраиваем файрволл:

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
        set ssh_allowed {
                type ipv4_addr
                elements = { 172.28.90.80 }
        }
        
        set fwknop_allowed {
                type ipv4_addr
                flags timeout
                timeout 60s
        }
        
        chain input {
                type filter hook input priority filter; policy drop;
                
                # Loopback
                iifname "lo" accept
                
                # Уже установленные соединения
                ct state established,related accept
                ct state invalid drop
                
                # ICMP
                icmp type echo-request accept
                
                # SSH из ssh_allowed
                iifname "eth0" ip saddr @ssh_allowed tcp dport 22 accept
                
                # SSH из fwknop_allowed
                iifname "eth0" ip saddr @fwknop_allowed tcp dport 22 accept
                
                # fwknop SPA packet
                iifname "eth0" udp dport 62201 accept
        }
        
        chain forward {
                type filter hook forward priority filter; policy drop;
        }
        
        chain output {
                type filter hook output priority filter; policy accept;
        }
}        
  • разрешаем подключаться к серверу по ssh только из адрес-листа ssh_allowed и fwknop_allowed;
    • ssh_allowed - статичный адрес-лист в который я добавил свой ip-адрес, чтобы не потерять доступ к серверу;
    • fwknop_allowed - динамический адрес-лист, который будет пополняться с помощью fwknopd.
  • открываем порт 62201 для fwknop клиента.

Перезапускаем файрволл и проверяем его работу, посмотрев на текущий список правил:

sudo systemctl restart nftables
sudo nft list ruleset

Установка и настройка Fwknop сервера

Устанавливаем fwknop сервер:

sudo apt install fwknop-server

Генерируем ключи:

sudo fwknopd --key-gen

Настраиваем access.conf - файл с правилами авторизации и выполнения команд:

sudo nano /etc/fwknop/access.conf

SOURCE              ANY
KEY_BASE64          <ключ>
HMAC_KEY_BASE64     <ключ>
HMAC_DIGEST_TYPE    sha256
CMD_CYCLE_TIMER    1
CMD_CYCLE_OPEN     /usr/sbin/nft add element inet filter fwknop_allowed { $PKT_SRC timeout 60s }
CMD_CYCLE_CLOSE    /usr/bin/true
  • SOURCE ANY - принимаем подключения со всех адресов, можно указать адреса и подсети, например 192.168.10.0/24,10.1.1.123;
  • KEY_BASE64 <ключ> - ключ шифрования;
  • HMAC_KEY_BASE64 <ключ> - подпись (хеш) сообщения;
  • HMAC_DIGEST_TYPE sha256 - алгоритм хеширования;
  • CMD_CYCLE_TIMER 1 - после команды OPEN через 1 секунду выполнится команда CLOSE;
  • CMD_CYCLE_OPEN - команда OPEN, добавляет ip (именно src-ip) в динамический адрес-лист на 60 секунд;
  • CMD_CYCLE_CLOSE - команда CLOSE, но так как nftables сам удалит ip-адрес, то используем заглушку /usr/bin/true.

Настроим fwknopd.conf - это конфиг службы fwknopd:

sudo nano /etc/fwknop/fwknopd.conf

ENABLE_NFQ_CAPTURE          N;
NFQ_INTERFACE               eth0;
NFQ_PORT                    62201;
ENABLE_SPA_PACKET_AGING     Y;
MAX_SPA_PACKET_AGE          120;
ENABLE_DIGEST_PERSISTENCE   Y;
  • ENABLE_NFQ_CAPTURE N; - выключаем ENABLE_NFQ_CAPTURE для упрощения. Если включить, то служба fwknopd не будет слушать порт 62201. Вместо этого будет перехватывать пакет на более низком уровне, что более безопасно. Но настройка NFQ_CAPTURE выходит за рамки статьи.
  • NFQ_INTERFACE eth0; - интерфейс для работы;
  • NFQ_PORT 62201; - порт;
  • ENABLE_SPA_PACKET_AGING Y; - клиент в сообщении оставляет временную метку, а этой настройкой мы заставляем сервер проверять эту метку;
  • MAX_SPA_PACKET_AGE 120; - если возраст SPA пакета превышает 120 секунд, то пакет отклоняется;
  • ENABLE_DIGEST_PERSISTENCE Y; - включаем сохранение предыдущих SPA сообщений в кеше. Если сервер получит повторно тот же SPA пакет, он отклонит его. Это защита от Replay attack (Атак повторного воспроизведения).

Запускаем fwknop сервер:

sudo systemctl start fwknop-server

С помощью следующих команд можем смотреть логи fwknop сервера и наблюдать за появлением новых ip-адресов в файрволле:

journalctl -u fwknop-server -n 50 --no-pager
journalctl -u fwknop-server -f
watch "sudo nft list ruleset"

Настройка клиента на Debian

Устанавливаем fwknop клиент на другую машину:

sudo apt install fwknop-client

Подготавливаем конфиг:

nano .fwknoprc

[default]
SPA_SERVER              <ip сервера>
SPA_SERVER_PORT         62201

KEY_BASE64              <ключ>
HMAC_KEY_BASE64         <ключ>

USE_HMAC                Y
HMAC_DIGEST_TYPE        sha256

ACCESS udp/1
  • ACCESS udp/1. ACCESS - обязательное поле SPA запроса, поэтому здесь нужно хоть что-нибудь написать. В нашем сценарии сервер игнорирует его содержимое и всегда выполняет CMD_CYCLE_OPEN.
  • Остальные параметры достаточно очевидны.

Выполняем стук:

fwknop -n default -s
  • -s - подставить свой исходящий адрес.

Можно подставить любой ip-адрес, например так:

fwknop -n default -a 1.1.1.1
  • Но мы на сервере в любом случае подставляем $PKT_SRC - то есть исходящий а не указанный адрес.

Настройка клиента на Windows

Сообщество разработало клиент для Windows: https://github.com/jp-bennett/fwknop-gui , бинарный файл можно скачать здесь - https://incomsystems.biz/fwknop-gui/downloads.php .

Внешний вид Fwknop-gui:

Внешний вид Fwknop-gui

Вам нужно только заполнить поля, указать верные ключи и нажать Save Config. Затем нажимаем Send Knock и выполняем SPA авторизацию на сервере.


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