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 на этом хосте
- Откройте «Port Knocking» и добавьте правило: порт
tcp/22, включите «Блокировка брандмауэром», ключи можно оставить пустыми — они создадутся автоматически; - На карточке правила нажмите «Клиент», укажите домен или публичный IP сервера и скопируйте командную строку или секцию
~/.fwknoprc; - Установите fwknop на клиенте: macOS
brew install fwknop, Debian / Ubuntuapt install fwknop-client, в Windows установите в WSL; - После стука подключайтесь по SSH в течение 30 секунд:
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. При копировании правила создаются новые ключи; изменение, отключение или удаление правила отзывает все созданные им авторизации |
| Алгоритм HMAC | SHA-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 на тот же порт:
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 нужно стучать заново (установленные соединения не затрагиваются). Записи защиты от повтора тоже хранятся только в памяти, поэтому после перезапуска отклоняется любой пакет с меткой времени раньше момента запуска; если часы клиента отстают от сервера, стук в первые секунды после перезапуска может быть отклонён — достаточно постучать ещё раз.