MASQUE / usque — справочник для zapret-gui

SkillCloud & infra

Complete reference for MASQUE / usque (Cloudflare WARP over HTTP/3) in the zapret-gui project (Keenetic routers on Entware / OpenWrt / Linux). Use for any tasks about: the MASQUE protocol and CONNECT-IP (RFC 9484 / RFC 9298), the usque CLI (register/enroll/nativetun/socks/http-proxy/l4-socks/l4-http

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the MASQUE / usque — справочник для zapret-gui skill

What this skill tells your AI

The instructions your AI receives, as published by avatardd/zapret-gui in .claude/skills/masque-usque/SKILL.md and read by ahel’s review.

Единый источник истины о том, как работает usque (клиент Cloudflare WARP по протоколу MASQUE) и как с ним обращаться в zapret-gui. Читать перед тем, как трогать менеджер, watchdog, установку бинарника, WARP-in-WARP или объяснять «почему туннель не поднимается».

Источники истины (в порядке убывания авторитета):

  1. Сам бинарник. usque <cmd> --help — единственный достоверный список флагов и дефолтов для КОНКРЕТНОЙ версии. Всё в §3 сверено с реальным выводом --help бинарника usque v4.2.0, собранного из тега v4.2.0 (go build, linux/amd64), а не пересказано по README.

  2. Diniboy1123/usque — апстрим (неофициальный клиент WARP на MASQUE). README + _docs/ + wiki. Актуальный релиз — v4.2.1; §3 остаётся валиден и для него, см. ниже.

    v4.2.0 → v4.2.1 — ровно один коммит и ни одного изменения в CLI, флагах или формате config.json: в api/masque.go и api/l4proxy.go соединение поднимается через quic.Transport{ConnectionIDLength: 20} вместо голого quic.Dial. Без явной длины Connection ID бэкенд Cloudflare периодически отвечал PROTOCOL_VIOLATION и рвал установленное соединение. Практический симптом на 4.2.0: туннель поднимается, какое-то время работает, потом отваливается без внятной причины — если такое видите, проверьте версию бинарника (usque version) и обновите. Наша сборка тянет апстрим автоматически (job auto-tag в build-usque-binaries.yml), так что достаточно переустановить бинарник из GUI.

  3. Наша сборка.github/workflows/build-usque-binaries.yml кросс-компилирует апстрим и публикует релизы usque-bin-v<версия>. Именно оттуда GUI ставит бинарник (§2). side-effect-tm/usque-keenetic (.ipk, последний релиз v0.3.0 с usque v4.2.0) остался только запасным источником.

  4. Наш кодcore/usque_manager.py (жизненный цикл, детект, импорт конфигов, лог), core/usque_watchdog.py (проба и рестарт), api/usque.py (REST), web/js/pages/usque.js + usque_setup.js (страницы), core/warp_in_warp.py (двойной туннель), core/ext_binary_installer.py (BINARIES["usque"]), core/cli.py (zapret-gui usque), core/config_manager.py (секция usque), app.py (_apply_usque_autostart_on_boot), core/tunnel_monitor.py.

⚠️ Две главные ловушки, на которых горит отладка (обе проверены экспериментально, см. §6 и §5):

  1. --no-iproute2 не поднимает интерфейс. Флаг означает «не назначай адреса и не поднимай link». TUN появляется, но остаётся operstate=down и без единого IP-адреса. Кто-то должен сделать это за usque — иначе интерфейс есть, а трафика нет.
  2. «Tunnel established» ≠ «подключено». Эта строка печатается сразу после создания TUN, ДО какого-либо сетевого обмена. Реальное MASQUE-соединение устанавливается лениво, при первом исходящем пакете. Поэтому неподнявшийся туннель выглядит в логе как успешный.

1. Что это такое и чем НЕ является

MASQUE (Multiplexed Application Substrate over QUIC Encryption) — набор IETF-механизмов проксирования поверх HTTP/3:

  • RFC 9298 (CONNECT-UDP) — проксирование UDP-датаграмм;
  • RFC 9484 (CONNECT-IP) — проксирование IP-пакетов целиком; именно его использует usque, поэтому туннель может нести любой IP-трафик.

usque — неофициальный клиент Cloudflare WARP, говорящий с WARP по MASQUE вместо WireGuard. Всё идёт внутри обычного HTTPS/QUIC на 443/udp (или HTTP/2 поверх TCP:443 — см. §4), поэтому трафик неотличим от обычного веба на уровне протокола.

Чем НЕ является:

  • Это не WireGuard и не AmneziaWG. Разные протоколы и разные ключи: у WireGuard/AWG — X25519, у usque — ECDSA на кривой P-256. Апстрим прямо пишет «no support for WireGuard». Практический вывод, который надо повторять пользователям: сессию usque НЕЛЬЗЯ собрать из .conf AmneziaWG/WireGuard, и наоборот. Единственные пути получить сессию — usque register или импорт готового config.json самого usque (UsqueManager.import_config).
  • Это не MASQUERADE. В нашем коде есть core/routing/masquerade.py — это NAT-правило (SNAT) для selective-routing, к протоколу MASQUE отношения не имеет. Совпадение имён; не путать при grep.
  • Это не замена WireGuard по производительности. usque — userspace на quic-go, congestion control только Reno (BBR нет). Апстрим измерял ~833 Mbit/s на десктопе; на MIPS-роутере ожидания должны быть куда скромнее.

Зачем нужен: WireGuard-транспорт WARP местами режется по протоколу/портам, а MASQUE выглядит как HTTPS. Плюс работает там, где UDP/51820 закрыт.


2. Установка: НАША сборка usque

Бинарник usque собираем сами — .github/workflows/build-usque-binaries.yml, как amneziawg-go и sing-box. usque — чистый Go без cgo, поэтому кросс-компиляция тривиальна (проверено: все пять архитектур собираются из тега v4.2.0).

ЧтоЗначение
Репозиторий сборокavatarDD/zapret-gui, релизы usque-bin-v<версия usque>
Апстрим-исходникиDiniboy1123/usque
Ассетыusque-<ver>-<arch>.gz + manifest.json
Путь бинарника/opt/usr/bin/usque (install_kind: "binary")
Архитектурыmipsel, mips, aarch64, armv7, x86_64
Проверкаsha256 из manifest.json релиза, fail-closed

Почему ушли со стороннего .ipk (side-effect-tm/usque-keenetic):

  • тот отстаёт от самого usque (в v0.3.0 лежал usque 4.2.0, когда апстрим выпустил уже 4.2.1) — версией теперь управляем мы;
  • в его .ipk нет x86_64, поэтому на Linux-ПК/VPS usque было не поставить вообще, хотя GUI там работает;
  • .ipk требует opkg/apk, сырой бинарник ставится всюду;
  • на одну стороннюю зависимость в цепочке поставки меньше.

Сборка зашивает версию через -ldflags "-X <module>/cmd.version=<ver>" — иначе usque version печатает dev (§3.1), и GUI не может сказать, что установлено.

sha256 живёт в manifest.json релиза, а не в манифесте кода: хэш сборки известен только после неё. Проверка при этом обязательна и fail-closed — расхождение отменяет установку.

Запасной источник. В BINARIES["usque"]["legacy_source"] остался прежний .ipk с закреплёнными хэшами: он используется, если наш релиз недоступен или в нём нет сборки под эту архитектуру. Это же покрывает период до публикации первого usque-bin-*.

Одна система версий. Тег нашей сборки кодирует версию usque (usque-bin-v4.2.14.2.1), поэтому «установлено» и «в релизе» — одна величина, и их сравнение осмысленно. Раньше сравнивались версия движка (4.2.0) и тег стороннего пакета (v0.3.0) — разные пространства, отсюда вечное «доступно обновление».

Требования на роутере: Entware (лучше на USB), модуль TUN (kmod-tun, устройство /dev/net/tun).

Пакет usque-keenetic (если он всё же стоит у пользователя) кладёт свой /opt/etc/init.d/S51usque и /opt/etc/usque/usque.conf. Мы ими не пользуемся: GUI запускает usque сам (см. §7) и хранит конфиги в platform_dirs.config_dir()/usque. Если включены и штатный S51usque, и наш автозапуск — получится два процесса и два TUN; это первое, что надо проверять при «интерфейсов больше, чем я создавал».

Поиск бинарника (UsqueManager._find_binary, по порядку): /opt/usr/bin/usque/opt/bin/usque/usr/local/bin/usque/usr/bin/usque.


3. CLI usque — полная карта (сверено с v4.2.0)

3.1 Корневая команда

usque [command]

Available Commands:
  account       Manage account and license keys
  completion    Generate the autocompletion script for the specified shell
  enroll        Enrolls a MASQUE private key and switches mode
  help          Help about any command
  http-proxy    Expose Warp as an HTTP proxy with CONNECT support
  l4-http-proxy Expose Warp as an L4 TCP-only HTTP proxy with CONNECT support
  l4-socks      Expose Warp as an L4 TCP-only SOCKS5 proxy
  nativetun     Expose Warp as a native TUN device
  portfw        Forward ports through a MASQUE tunnel
  register      Register a new client and enroll a device key
  socks         Expose Warp as a SOCKS5 proxy
  version       Print the version number of usque

Flags:
  -c, --config string   config file (default is config.json) (default "config.json")
  -h, --help            help for usque

Глобальный флаг ровно один — -c/--config. -s, --http2 и прочее принадлежат подкомандам, а не корню.

🔴 usque --version НЕ СУЩЕСТВУЕТ. Cobra-команда не объявляет поле Version, поэтому вызов падает:

$ usque --version
Error: unknown flag: --version
... (usage) ...
$ echo $?
1

Версию печатает подкоманда usque version, в stdout, тремя строками:

usque version: dev
Commit: none
Build Date: unknown

Строка dev — это значение по умолчанию: если сборка сделана без -ldflags "-X ...version=<x>", номера версии не будет вообще. Парсер обязан переживать и 4.2.0, и dev.

Ещё нюанс: usque version всё равно пытается прочитать конфиг и, не найдя его, пишет в stderr две строки («Config file not found…» / «You may only use the register command…»), но возвращает rc=0. Поэтому версию надо брать из stdout, а stderr при детекте игнорировать.

3.1.1 Регистрация через прокси: usque уважает HTTPS_PROXY

Практически важный факт, которого нет в README апстрима. Все запросы к API Cloudflare идут через http.DefaultClient (api/cloudflare.go), а у него Proxy: http.ProxyFromEnvironment. Значит usque register подчиняется переменным окружения HTTP_PROXY / HTTPS_PROXY / NO_PROXY, включая схему socks5://.

Проверено на живом бинарнике:

$ HTTPS_PROXY=http://127.0.0.1:1 usque register -a -c out.json
Failed to register: ... Post "https://api.cloudflareclient.com/v0a4471/reg":
  proxyconnect tcp: dial tcp 127.0.0.1:1: connect: connection refused

$ HTTPS_PROXY=socks5://127.0.0.1:11080 usque register -a -c out.json
Successful registration. Saving config...
   [прокси видит ровно один CONNECT api.cloudflareclient.com:443]

Это единственный вменяемый способ зарегистрироваться там, где провайдер режет сам api.cloudflareclient.com (симптом — net/http: TLS handshake timeout). На этом построена наша «Регистрация через» (§8.1).

Отдельно: --http2 тоже ходит через ProxyFromEnvironment (api/masque.go), а QUIC-режим — нет. То есть прокси-переменные в окружении процесса влияют на регистрацию и на H2-туннель, но не на H3.

3.2 register — создать сессию WARP

usque register [flags]
  -a, --accept-tos      accept Cloudflare TOS (not interactive setup)
      --jwt string      team token
  -l, --locale string   locale (default "en_US")
  -m, --model string    model (default "PC")
  -n, --name string     device name

Регистрирует новый аккаунт, энроллит ключ устройства, переключает аккаунт в режим MASQUE и сохраняет config по пути -c. Без -a уходит в интерактивный режим — в GUI это означало бы вечное ожидание, поэтому --accept-tos обязателен.

  • -n — имя устройства в аккаунте Cloudflare (иначе все туннели выглядят одинаково).
  • --jwt — регистрация в ZeroTrust вместо обычного consumer-WARP.

⚠️ В register -n — это имя устройства, а в nativetun -nимя интерфейса. Один короткий флаг, два разных смысла.

3.3 nativetun — туннель как TUN-интерфейс

Основной режим для роутера. Требует root, tun.ko и (по умолчанию) iproute2.

usque nativetun [flags]
      --always-reconnect             Always reconnect after tunnel loss, even when idle
  -P, --connect-port int             Used port for MASQUE connection (default 443)
      --http2                        Use HTTP/2 over TCP+TLS instead of HTTP/3 over QUIC
  -i, --initial-packet-size uint16   Custom initial packet size (default: auto with PMTU discovery)
      --insecure                     Disable endpoint certificate pinning and trust any certificate
  -n, --interface-name string        Custom interface name for the TUN interface
  -6, --ipv6                         Use IPv6 for MASQUE connection
  -k, --keepalive-period duration    Keepalive period for MASQUE connection (default 30s)
  -m, --mtu int                      MTU for MASQUE connection (default 1280)
  -I, --no-iproute2                  Linux only: Do not set up IP addresses and do not set the link up
  -F, --no-tunnel-ipv4               Disable IPv4 inside the MASQUE tunnel
  -S, --no-tunnel-ipv6               Disable IPv6 inside the MASQUE tunnel
      --on-connect string            Path to an executable to run after each successful tunnel connect
      --on-disconnect string         Path to an executable to run after each tunnel disconnect
      --persist                      Linux only: Keep the TUN interface after exit
  -r, --reconnect-delay duration     Delay between reconnect attempts (default 1s)
  -s, --sni-address string           SNI address for MASQUE connection (default "consumer-masque.cloudflareclient.com")

Чего нет и выдумывать нельзя: --tcp-nodelay, --keepalive (только --keepalive-period), --dns/--local-dns (DNS есть только у прокси-режимов), --sni (только --sni-address / -s).

-6/--ipv6 относится к транспорту наружу (стучаться на endpoint_v6), а -F/-S — к тому, какие семьи работают внутри туннеля. Это разные вещи.

3.4 Прокси-режимы

socks, http-proxy и их «лёгкие» TCP-only варианты l4-socks, l4-http-proxy (без UDP/датаграмм и без userspace-стека — заметно дешевле по CPU, что для MIPS-роутера существенно). Общие флаги:

  • -b <addr> — bind (SOCKS5 по умолчанию 0.0.0.0), -p <port> (SOCKS5 — 1080);
  • -u/-w — логин/пароль;
  • -d <dns> — DNS-сервер, повторяемый (по умолчанию Quad9);
  • --on-connect / --on-disconnect.

Мы эти режимы не используем — GUI работает только через nativetun. Если понадобится «WARP как прокси без TUN» (роутер без kmod-tun), это готовый путь, но кода под него сейчас нет.

3.5 Прочее

  • enroll — переэнроллить существующий ключ / обновить данные серверов; полезно при миграции устройства или переключении с WireGuard на MASQUE.
  • account — управление аккаунтом и лицензионными ключами (WARP+).
  • portfw — проброс портов (-L, -R) для ZeroTrust WARP-to-WARP.

3.6 Хуки

Все туннельные режимы поддерживают --on-connect / --on-disconnect: путь к исполняемому файлу, без аргументов, контекст передаётся через переменные окружения USQUE_EVENT, USQUE_MODE, USQUE_IFACE, USQUE_IPV4, USQUE_IPV6, USQUE_ENDPOINT.

Это правильное место, чтобы вешать маршруты/DNS «когда туннель реально поднялся» — в отличие от факта запуска процесса, хук срабатывает по фактическому соединению.


4. Транспорт: H3/QUIC против H2/TCP

performance (дефолт)restricted (--http2)
ПротоколHTTP/3 поверх QUICHTTP/2 поверх TCP+TLS
Порт443/udp443/tcp
Endpoint из конфигаendpoint_v4 / endpoint_v6endpoint_h2_v4 / endpoint_h2_v6
Когда нуженнормальная сетьUDP/443 зарезан или сильно деградирован
Ценавыше latency, TCP-over-TCP при вложенности

Проверено на живом бинарнике: при --http2 в лог уходит HTTP/2 mode enabled и Using HTTP/2 endpoint <ip>:443.

⚠️ endpoint_h2_v6 у свежей бесплатной регистрации ПУСТОЙ. Реальный config.json от usque register (v4.2.0) содержит непустой endpoint_h2_v4 и пустую строку в endpoint_h2_v6. Значит связка --http2 -6 на consumer-аккаунте работать не будет; про это же предупреждает README usque-keenetic («HTTP/2 требует настроенного IPv6-endpoint»).

⚠️ HTTP/2-режим уважает HTTP_PROXY/HTTPS_PROXY из окружения (это обычный Go http.Transport), а QUIC-режим — нет. Если процесс GUI запущен с прокси-переменными, H2-туннель молча пойдёт через прокси и упрётся в него. На роутере это редкость, но при отладке в контейнере — постоянный источник ложных выводов вида failed to dial connect-ip over HTTP/2: ... Connect "https://cloudflareaccess.com": connection reset by peer.

Профиль auto в нашем коде — не то, чем кажется. Он делает ровно один повтор с --http2, и только если процесс упал или интерфейс не появился на старте. Но при заблокированном UDP процесс не падает и интерфейс появляется (§5) — падает лишь ленивое соединение, уже после того как start() вернул успех. Поэтому на «UDP зарезан» auto сам по себе не переключится; вытягивает ситуацию только watchdog (§9), который после неудачных проб перезапускает туннель и в режиме auto понижает транспорт до restricted.

SNI. -s подменяет только SNI в TLS-хендшейке; сертификат при этом по-прежнему пиннится по endpoint_pub_key. Наш дефолт — usque.default_sni = "ozon.ru" (крупный российский домен), апстримовский — consumer-masque.cloudflareclient.com. Пустая строка = «не подменять».


5. Жизненный цикл соединения (и почему лог врёт)

Порядок событий у nativetun, дословно из stderr живого бинарника:

Created TUN device: warp0
Tunnel established, you may now set up routing and DNS
Tunnel idle. Waiting for outbound activity before reconnecting...

…и только когда через интерфейс пойдёт первый пакет:

Detected outbound activity (60 bytes). Reconnecting...
Establishing MASQUE connection to 162.159.198.2:443

Дальше либо тишина (успех), либо:

Failed to connect tunnel: failed to dial connect-ip: timeout: no recent network activity
Tunnel idle. Waiting for outbound activity before reconnecting...

Выводы, критичные для кода и для поддержки:

  1. «Tunnel established» печатается ДО сети. Это значит «TUN создан, можно настраивать маршруты», а не «WARP подключён». Считать его признаком успеха нельзя.
  2. Соединение ленивое. Пока через интерфейс нет исходящего трафика, usque не подключается вообще (--always-reconnect меняет это поведение). Следствие: проверять «работает ли туннель» можно только проведя через него трафик — что и делает наш watchdog (SO_BINDTODEVICE + TCP-проба).
  3. Ретраи вечные, с паузой --reconnect-delay (1s) плюс собственный таймаут дозвона (~5 с). Процесс при этом жив и rc не отдаёт — «процесс есть» ничего не доказывает.
  4. Сообщения об ошибках дозвона надо читать буквально:
    • failed to dial connect-ip: timeout: no recent network activity — QUIC/UDP до endpoint не доходит → пробовать --http2;
    • failed to dial connect-ip over HTTP/2: ... connection reset — TCP/443 перехвачен или зарезан (часто — прокси из окружения);
    • x509: cannot verify signature: algorithm unimplemented / любые cert-ошибки — на пути TLS-MITM, пиннинг сработал как задумано;
    • server responded with 403 — до Cloudflare достучались, но CONNECT-IP-запрос отвергнут (протухшая/чужая сессия, либо всё тот же MITM).

6. TUN-интерфейс: кто назначает адреса

Самая дорогая ловушка. Дословная справка флага:

-I, --no-iproute2   Linux only: Do not set up IP addresses and do not set the link up

То есть --no-iproute2 отключает и адреса, и подъём link'а. Экспериментально, usque nativetun --no-iproute2 -n utest0:

Skipping IP address and link setup. You should set the link up manually.
Config has the following IP addresses:
IPv4: 172.16.0.2
IPv6: 2606:4700:110:...
Created TUN device: utest0

и в системе:

/sys/class/net/utest0/operstate → down      ← НЕ "unknown", а именно down
адресов на интерфейсе нет

Для сравнения, без --no-iproute2 usque настраивает всё сам (через netlink, бинарник ip ему не нужен):

/sys/class/net/utest2/operstate → unknown
IPv4 на интерфейсе: 172.16.0.2
MTU: 1280

Практические следствия:

  • Проверять готовность интерфейса по operstate ∈ {up, unknown} валидно только для режима без --no-iproute2. С --no-iproute2 эта проверка не пройдёт никогда, и туннель будет убит как «не поднявшийся».
  • Если мы передаём --no-iproute2, мы обязаны сами: назначить ipv4ipv6, если он есть) из config.json, выставить MTU и поднять link. Именно это делает UsqueManager._configure_iface() (§7).
  • Обратная сторона: на хосте без IPv6 обычный режим падает целикомFailed to create TUN device: failed to add IPv6 address: operation not supported. Спасают либо -S/--no-tunnel-ipv6, либо --no-iproute2 с ручной настройкой. Мы выбрали второе: настраиваем сами и делаем IPv6 best-effort, чтобы отсутствие v6 не роняло туннель.
  • --persist мы не передаём: TUN должен исчезать вместе с процессом, иначе после падения остаётся мёртвый интерфейс, который занимает имя.

7. Наш менеджер: core/usque_manager.py

Синглтон get_usque_manager(). Реентрантный RLock (не Lock: start() зовёт _is_running() уже под локом — с обычным Lock это гарантированный самодедлок).

Команда, которую мы строим

usque nativetun --config <path> --interface-name <iface> --no-iproute2
                [-s <sni>] [--http2] [--keepalive-period 10s]
  • --no-iproute2 — намеренно: адреса и link настраиваем сами (§6), иначе на хостах без IPv6 usque падает целиком.
  • --http2 — только для профиля restricted.
  • --keepalive-period 10s — при low_latency (дефолт usque — 30s).

Ключевые методы

МетодЧто делает / на что смотреть
detect(){installed, binary, version, arch}. Версия — через usque version, из stdout.
register(path, device_name, team_token)usque register --accept-tos -c <path> [-n] [--jwt], таймаут 30 с.
import_config(name, text)Импорт готового config.json. Валидирует обязательные поля, режет path-traversal, chmod 600.
list_configs()Файлы .conf/.toml/.json из конфиг-каталога + iface/active.
allocate_iface(prefix)Свободное имя opkgtun<N> (≤15 символов), с оглядкой на /sys/class/net и pid-файлы.
start(iface, path, …)См. ниже.
stop(iface)SIGTERM всей группе (start_new_session=Truekillpg), затем SIGKILL; чистит pid/.run.
status(iface){running, iface_exists, pid, diagnostic}.
read_log(iface, lines)Хвост stderr из кольцевого буфера в ОЗУ.

Что делает start() по шагам

  1. Валидация имени интерфейса (^[a-zA-Z0-9_-]{1,15}$) и профиля.
  2. Под локом — проверка _is_running().
  3. Popen с stderr=PIPE, start_new_session=True; отдельный поток вычитывает stderr в deque (иначе pipe заполнится и usque встанет).
  4. Ждём появления интерфейса в /sys/class/net (до 5 с, шаг 0.1 с), попутно проверяя, не умер ли процесс.
  5. _configure_iface() — MTU, адреса из config.json, ip link set up.
  6. Пишем pid-файл и <config>.run (IFACE=/PID=), применяем tunnel_optimizer.

Шаг 4 смотрит именно на существование интерфейса, а не на operstate: с --no-iproute2 состояние остаётся down до шага 5 (§6).

Файлы состояния

  • <pid_dir>/usque-<iface>.pid — PID (_pid_dir = /opt/var/run);
  • <config>.runIFACE="…" / PID="…", по нему list_configs() восстанавливает привязку конфига к интерфейсу после рестарта GUI.

⚠️ /opt/var/run переживает перезагрузку, поэтому pid-файл после ребута почти наверняка указывает на чужой процесс. Отсюда _pid_is_usque(pid) (читает /proc/<pid>/cmdline): без неё _is_running() врал бы «уже запущен», а stop() слал бы killpg посторонней группе от root.

Формат config.json

Реальный конфиг от usque register v4.2.0 (значения сокращены):

{
  "private_key":      "<base64 ECDSA P-256, ~164 симв.>",
  "endpoint_v4":      "162.159.198.2",
  "endpoint_v6":      "2606:4700:103::2",
  "endpoint_h2_v4":   "162.159.198.2",
  "endpoint_h2_v6":   "",
  "endpoint_pub_key": "<PEM, ~178 симв.>",
  "id":               "<uuid устройства>",
  "access_token":     "<uuid токена>",
  "ipv4":             "172.16.0.2",
  "ipv6":             "2606:4700:110:...."
}

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
133
Forks
10
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
masque-usque
Source
github.com/avatardd/zapret-gui