Skip to content
Эта страница переведена с помощью ИИ и может содержать неточности. Помогите улучшить перевод на GitHub.

Port Knocking ​

Совместимая с fwknop односторонняя авторизация одним пакетом (SPA, Single Packet Authorization): защищённые порты обычно недоступны снаружи, клиент сначала отправляет зашифрованный пакет-«стук» с аутентификацией HMAC и защитой от повтора, и после проверки Gately открывает доступ только для адреса источника и только на ограниченное время. Обычно используется для защиты прямого SSH: сценарии, где Веб-терминал не подходит (scp, удалённая разработка в IDE, проброс портов), безопасно работают из внешней сети, а сканеры и перебор паролей порта не видят.

Возможности ​

  • Совместимость с клиентом fwknop: работает официальный клиент fwknop (Linux, macOS, WSL); формат ключей совпадает с KEY_BASE64 и HMAC_KEY_BASE64, которые создаёт fwknop -k; на странице правила одним нажатием создаются команда клиента и секция ~/.fwknoprc;
  • Безопасность: пакет шифруется AES-256-CBC, сначала проверяется HMAC (SHA-256 / 384 / 512) и только потом выполняется расшифровка, поэтому пакеты с неверным ключом до расшифровки не доходят; каждый пакет можно использовать только один раз (защита от повтора), пакеты с меткой времени за пределами срока действия (по умолчанию 120 секунд) отклоняются; можно ограничить имя пользователя и требовать, чтобы в пакете был указан адрес для открытия доступа;
  • Блокировка брандмауэром: защищённые порты записываются в системный брандмауэр (nftables, а при отсутствии nf_tables в ядре — iptables + ipset), и доступ получают только адреса, успешно «постучавшие»; так защищается sshd и другие службы этого хоста, не проходящие через Gately;
  • Допуск входов Gately по стуку: правила проброса портов, протокольной маршрутизации, встроенной переадресации STUN и отдельные маршруты протокольной маршрутизации могут требовать стука («Требовать стук»). Решение принимает сам Gately, права на брандмауэр не нужны, работает в Windows, macOS и контейнерах без NET_ADMIN;
  • Только один порт: протокольная маршрутизация распознаёт пакеты-стуки, приходящие по TCP (fwknop -P tcp), так что один порт принимает стук и по его результату открывает SSH и другие маршруты;
  • Связь с защитой от вторжений: отклонённые стуки публикуют событие «Отклонён стук Port Knocking»; встроенный шаблон защиты от вторжений «Неудачи Port Knocking» блокирует источники по числу попыток; стуки с уже заблокированных адресов отбрасываются сразу;
  • Список действующих авторизаций (оставшееся время, можно отозвать); успешные и отклонённые стуки записываются в журнал работы, на них можно подписаться в центре уведомлений.

Быстрый старт: защита SSH на этом хосте ​

  1. Откройте «Port Knocking» и добавьте правило: порт tcp/22, включите «Блокировка брандмауэром», ключи можно оставить пустыми — они создадутся автоматически;
  2. На карточке правила нажмите «Клиент», укажите домен или публичный IP сервера и скопируйте командную строку или секцию ~/.fwknoprc;
  3. Установите fwknop на клиенте: macOS brew install fwknop, Debian / Ubuntu apt install fwknop-client, в Windows установите в WSL;
  4. После стука подключайтесь по SSH в течение 30 секунд:
bash
fwknop -n gately-ssh && ssh user@example.com

По умолчанию пакеты-стуки отправляются на UDP-порт 62201. Если Gately стоит за роутером, UDP 62201 нужно пробросить на хост с Gately вместе с защищённым портом; при включённом «Автоматическом открытии брандмауэра» локальный брандмауэр (OpenWrt fw4, firewalld, ufw и т. д.) сам откроет порт стука, а после вступления блокировки в силу откроет и защищённый порт, так что возможность подключения определяется только стуком.

Не заблокируйте себя

  • По умолчанию включён режим «Локальная сеть без стука»: частные адреса, link-local адреса и публичные диапазоны IPv6 сетевых интерфейсов хоста (префикс интерфейса, если он /64 или короче; для типичных у облачных серверов /124 и /128 — только сам этот префикс) обходятся без стука; в настройках можно добавить собственный белый список адресов без стука. Адреса операторского NAT (100.64.0.0/10) сюда не входят: ими пользуются и другие абоненты того же провайдера; пользователям Tailscale следует добавить 100.64.0.0/10 в белый список;
  • При включённой блокировке брандмауэром уже установленные соединения не затрагиваются, и после окончания авторизации установленные соединения тоже сохраняются;
  • При обычной остановке Gately правила блокировки удаляются; при принудительном завершении (kill -9, docker rm -f) правила остаются до следующего запуска Gately. Убедитесь, что можете войти на эту машину из локальной сети или другим способом.

Правила ​

ПолеОписание
ПортПорты, открытия которых может запросить клиент, например tcp/22, udp/51820, не более 16. Все порты в параметре -A клиента должны быть в этом списке, иначе весь стук отклоняется
Блокировка брандмауэромПри включении эти порты блокируются в системном брандмауэре, доступ получают только адреса, успешно «постучавшие»; при выключении брандмауэр не изменяется, а правило используется только входами с «Требовать стук»
Ключ шифрования / ключ HMACВ кодировке base64; если оставить пустыми, создаются автоматически (32 / 64 байта, как у fwknop -k); можно указать ключи существующего сервера fwknop. При копировании правила создаются новые ключи; изменение, отключение или удаление правила отзывает все созданные им авторизации
Алгоритм HMACSHA-256 (по умолчанию в fwknop), SHA-384, SHA-512; должен совпадать с --hmac-digest-type клиента
Длительность доступаВремя после успешного стука, в течение которого можно устанавливать новые соединения, по умолчанию 30 секунд
Максимум для клиентаПредел, если клиент запрашивает большую длительность через -f (по умолчанию 300 секунд); 0 означает игнорировать запрошенную клиентом длительность; если запрошена меньшая длительность, всегда используется она
Ограничение имени пользователяПринимаются только стуки, в которых имя пользователя равно этому значению (fwknop по умолчанию отправляет имя локального пользователя, его можно задать через -U)
Требовать адресОтклонять пакеты без адреса (fwknop -s); клиент обязан указать адрес для открытия через -R или -a

Правило, на которое ссылаются проброс портов, протокольная маршрутизация или STUN, удалить нельзя; на карточке перечислены ссылающиеся стороны.

Какой адрес открывается ​

  • -R (рекомендуется): клиент сначала узнаёт свой публичный IPv4 и записывает его в пакет; даже перехваченный в пути пакет нельзя использовать для другого адреса;
  • -s: пакет без адреса, открывается адрес источника пакета. Перехватчик пакета может успеть повторить его со своего адреса; такие пакеты можно отклонять, включив в правиле «Требовать адрес»;
  • -a адрес: открывается указанный адрес, например чтобы постучать за другое устройство.

Клиент fwknop 2.6 отправляет пакеты стука только по IPv4 и открывает только адреса IPv4, поэтому сервер должен быть доступен по IPv4; сам Gately также принимает пакеты стука, пришедшие по IPv6, и открывает их адрес источника.

Глобальные настройки ​

  • UDP-порт стука: по умолчанию 62201 (порт по умолчанию клиента fwknop); 0 означает не слушать UDP и принимать только стуки, пришедшие через протокольную маршрутизацию. Без включённых правил прослушивания нет;
  • Автоматическое открытие брандмауэра: см. выше;
  • Локальная сеть без стука / белый список без стука: влияют только на блокировку брандмауэром; входы с «Требовать стук» управляются собственными списками IP;
  • Срок действия пакета: максимальное расхождение между меткой времени пакета и временем этой машины, по умолчанию 120 секунд; часы клиента и сервера должны быть точными.

Блокировка брандмауэром ​

СредаБлокировка брандмауэромДопуск входов Gately по стуку
Linux (root или CAP_NET_ADMIN, есть nftables)ДоступнаДоступен
Docker (сеть host + cap_add: NET_ADMIN)Доступна, правила записываются на хостДоступен
Linux без nf_tables, например Synology DSMИспользуются iptables (legacy) + ipset, в официальный образ Docker они уже включеныДоступен
Windows, macOS, FreeBSD, Linux без правНедоступна, причина показана вверху страницыДоступен

Gately создаёт в nftables отдельную таблицу inet gately_knock и не изменяет уже существующие правила системы: цепочка prerouting (приоритет -160, после отслеживания соединений и до преобразования адресов назначения) передаёт пакеты, идущие на защищённые порты, в цепочку gate, которая по порядку пропускает трафик, предназначенный не этому хосту (соединения, пересылаемые через эту машину на другие устройства, не затрагиваются), loopback-интерфейс, установленные соединения, TCP-пакеты, не начинающие соединение, а также адрес + протокол + порт из сетей без стука и из набора допущенных стуком; остальное отбрасывается. Проверка выполняется в prerouting, поэтому порты, отображённые на контейнеры Docker, блокируются по порту до отображения. Допуск записывается элементами набора с тайм-аутом, по окончании которого ядро удаляет их само.

Без nf_tables используется таблица mangle в iptables: PREROUTING переходит в GATELY_KNOCK, на каждый защищённый порт создаётся набор ipset (gkn4_tcp_22 и т. п., с тайм-аутом). Если таблица или переход удалены перезагрузкой брандмауэра, nft flush ruleset и т. п., в течение 10 секунд они автоматически записываются заново вместе с ещё действующими допусками. «Показать правила брандмауэра» на странице показывает записанные сейчас правила.

SSH, приходящий через проброс портов

Соединения, которые Gately пробрасывает на 127.0.0.1:22 этого хоста, приходят с loopback-интерфейса и блокировкой брандмауэром не затрагиваются. В этом случае выберите в правиле проброса портов «Требовать стук» или защитите блокировкой брандмауэра внешний порт проброса.

Важно

  • Проброс портов Docker подменяет адрес источника: если Gately работает в сети bridge, порт стука проброшен через -p 62201:62201/udp, а этот проброс обслуживает userland-proxy Docker (например, при обращении по IPv6 или через loopback-адрес либо при отключённой интеграции с iptables), Gately видит источником адрес шлюза Docker. Пакет -s тогда разрешает адрес шлюза вместо настоящего клиента и может открыть порт всем соединениям, идущим через этот шлюз. Запускайте Gately в сети host (это нужно и для блокировки брандмауэром) или пусть клиенты указывают адрес через -R / -a, и включите «Требовать адрес»;
  • Компромисс блокировки только SYN: чтобы не разрывать соединения, установленные до включения блокировки и ещё не учтённые отслеживанием соединений, для TCP отбрасываются только SYN-пакеты, открывающие соединение, а пакеты без SYN пропускаются. Теоретически система с включёнными SYN cookies (net.ipv4.tcp_syncookies) при переполнении очереди SYN примет одиночный ACK с угаданным действительным cookie и установит соединение; cookie — это 32-битный начальный номер последовательности, вычисленный из секрета ядра и времени, поэтому угадать его практически невозможно; при очень высоких требованиях к безопасности можно отключить SYN cookies (sysctl net.ipv4.tcp_syncookies=0).

Допуск входов Gately по стуку ​

В «Контроле доступа по IP» проброса портов, протокольной маршрутизации и STUN (встроенная переадресация) можно выбрать правило стука как «Требовать стук»: новое соединение допускается, только если у адреса источника есть неистёкшая авторизация этого правила (для UDP — при создании нового сеанса: после истечения авторизации существующие сеансы, например WireGuard, продолжают пересылаться, так же как установленные соединения при блокировке брандмауэром; белые / чёрные списки по-прежнему проверяются для каждого пакета), остальные соединения сразу разрываются; если одновременно задан белый / чёрный список, нужно удовлетворять обоим. В правиле стука можно выключить «Блокировку брандмауэром», и оно будет использоваться только этими входами.

В протокольной маршрутизации «Требовать стук» можно выбрать и для отдельного маршрута: например, на порту 443 маршрут HTTPS открыт для всех, а маршрут SSH только для адресов, успешно «постучавших».

Открыть только один порт ​

Добавьте в правило протокольной маршрутизации маршрут «Port Knocking» (протокол spa); клиент отправляет пакет-стук по TCP на тот же порт:

bash
fwknop -A tcp/443 -P tcp -p 443 -R -D example.com --use-hmac \
  --key-base64-rijndael <encryption key> --key-base64-hmac <HMAC key>
ssh -p 443 user@example.com
  • Маршрут стука передаёт пакет модулю Port Knocking, не пересылает и не отвечает; порт из -A должен быть в списке портов правила стука (например tcp/443);
  • Если правило целиком требует стука, источник без стука может использовать только маршрут стука, а после стука — остальные маршруты и цель по умолчанию;
  • Пакеты стука распознаются, только если в правиле есть маршрут стука; на распознавание протоколов в других правилах это не влияет;
  • UDP-порт правила стука можно установить в 0 и открыть наружу только порт протокольной маршрутизации;
  • Порты маршрутизации по протоколу с маршрутом стука и UDP-порт стука нельзя указывать в правиле с блокировкой брандмауэром (проверяется при сохранении и включении: блокировка не пропустила бы сами пакеты стука); при формировании правил брандмауэра они также всегда исключаются.

Связь с защитой от вторжений ​

Отклонённые стуки публикуют событие «Отклонён стук Port Knocking» (поле via — udp или tcp), не чаще одного раза в 5 секунд для одного источника. Адрес источника UDP-пакета можно подделать, поэтому, чтобы злоумышленник не мог руками защиты от вторжений заблокировать произвольный IP, UDP-пакеты, не прошедшие проверку HMAC, только учитываются и событий не создают; событие публикуется, только если пакет прошёл HMAC (его создал клиент, владеющий ключом), но был отклонён правилом (ошибка расшифровки, повтор, истёкший срок, запрос неразрешённого порта, другое имя пользователя и т. п.). Пакеты, пришедшие через TCP-порт маршрутизации по протоколу, приходят после рукопожатия и подделать источник нельзя, поэтому там событие публикуется и при несовпадении HMAC. Создайте в защите от вторжений правило по шаблону «Неудачи Port Knocking» (по умолчанию 5 раз за 10 минут — блокировка на 1 день): источники, постоянно присылающие поддельные пакеты, блокируются, а стуки с заблокированных адресов сразу отбрасываются. Данные не в формате стука (сканирование портов, другие протоколы) только учитываются и событий не создают.

Перед аутентификацией скорость ограничивается по диапазону источника (не более 10 пакетов в секунду на каждую IPv4 /24 и IPv6 /64), а затем общим пределом 200 пакетов в секунду; остальные сразу отбрасываются. Поток поддельных пакетов не займёт весь процессор, а поток от одного источника не вытеснит обычные стуки других. Пакеты, не прошедшие проверку HMAC, не записываются в журнал по одному: раз в минуту они сводятся в одну строку «M недействительных пакетов стука от N источников».

Ограничения ​

  • Поддерживается только режим Rijndael (AES) CBC fwknop с HMAC; GnuPG, старый режим IV и пакеты без HMAC не поддерживаются;
  • Командные сообщения (fwknop -C) не выполняются, запросы доступа NAT (-N) не поддерживаются;
  • Авторизации стука хранятся в памяти, после перезапуска Gately нужно стучать заново (установленные соединения не затрагиваются). Записи защиты от повтора тоже хранятся только в памяти, поэтому после перезапуска отклоняется любой пакет с меткой времени раньше момента запуска; если часы клиента отстают от сервера, стук в первые секунды после перезапуска может быть отклонён — достаточно постучать ещё раз.

Распространяется по лицензии Apache-2.0.