Repository navigation
Conversation
Фундамент этапа 1: Hysteria 2 и AmneziaWG 2.0 не должны притворяться Xray-путями. Состояние бэкендов — /usr/local/etc/xrayebator/backends.json (BACKENDS_ROOT переопределяем для тестов, паттерн P2-fix); клиентские креденшелы бэкендов будут жить в профиле (.backends) как единый источник для revoke/expire, серверные конфиги регенерируются из профилей. - хелперы реестра: ensure/installed/field/set (мутации через safe_jq_write, jq-опции строго до фильтра), port_busy_udp, unit_state - _backend_status_json + диспетчер CLI backend-status (только JSON на stdout) - _backend_apply_profile_lifecycle — единая точка жизненного цикла (created|deleted|revoked|expired|restored); вызовы подключаются в срезах 3/5 вместе с реальными обработчиками, сейчас безопасный no-op - validation/test-backend-registry.sh: source-режим + временный BACKENDS_ROOT/LOCK_FILE; тест поймал реальный баг set -u unbound variable в local out/prev одной строкой (bash 5.2) — исправлено разнесением - help и CLAUDE.md синхронизированы Меню намеренно не тронуто: пункты 11/12/13 добавляются вместе со своими бэкендами из-за строгой нумерации в test-main-menu-numbering.sh.
… меню 11)
Первый не-Xray backend. Поставка зеркалит update_xray_core: GitHub API HyNetworks/hysteria (тег app/vX.Y.Z, sha256 из поля digest API-ответа) -> /usr/local/bin/hysteria + self-test. Свой юнит hysteria-server.service (не get.hy2.sh): выделенный пользователь hysteria, CAP_NET_BIND_SERVICE, Restart=on-failure — та же модель доверия, что у xray.service; плюс sysctl-буферы QUIC.
TLS адаптивный: LE-серт подписки копируется в backends/hysteria с certbot deploy-hook на продление (клиенты insecure=0), иначе self-signed (insecure=1). masquerade 404 в обеих модах — proxy-маскарад только после живой проверки в срезе 3. Гранты per-profile (userpass) — срез 3, в yaml пока users: {}.
- CLI hysteria2-install [--port P] / hysteria2-uninstall / hysteria2-status: только JSON на stdout (человеческий вывод в stderr), rc=2 от воркера = already/not installed -> {already:true}
- install атомарен: скачивание во tmp + sha256 + self-test, откат артефактов при неудаче старта; реестр пишется последним шагом — записи только у живого бэкенда
- _hysteria2_safe_restart: бэкап server.yaml -> restart -> откат при неудаче (у hysteria нет -test)
- тест поймал потерю полей version/tls_mode в backend-status: статус теперь прокидывает всю запись реестра, state ставится живой проверкой
- меню 11 + осознанное расширение test-main-menu-numbering до 1..11
…лный жизненный цикл
Профиль — единственный источник креденшелов: .backends.hysteria2 {username, password} в profile JSON; server.yaml всегда РЕГЕНЕРИРУЕТСЯ из профилей (_hysteria2_regen_config: компактная users-карта, фильтр expire_disabled), применяется через _hysteria2_apply_config с откатом при неудачном рестарте. Благодаря фильтру события expired/restored — это просто реген: продление срока автоматически возвращает грант, снапшоты не нужны.
Lifecycle-хук подключён во все точки после успешной Xray-части: create_profile и _profile_cli_create_one (created), profile_delete (deleted), profile_revoke (revoked = ротация пароля), _expire_disable/_expire_enable (expired/restored). Массовая выдача: интерактивный вопрос при install, CLI --grant-all; один реген на всех.
Подписка: hysteria2-ссылка (_hysteria2_profile_link_pure, insecure из tls_mode) добавляется в ОБА тела — generic v2rayNG и HAPP (решение пользователя); флаг sub_body в реестре — выключатель без рестарта сервиса (реестр читается на каждый запрос). Миграция subhttp_hysteria2_2026 регенерирует handler на живых серверах, зарегистрирована в main_menu И quickstart (паритет).
Инфраструктурные находки: (1) subhttp работает от пользователя xray — реестр переведён на 644 root (без секретов, читается сервисом), секреты в 750-каталогах; (2) PROFILES_DIR переопределяем для тестов (P2-fix); (3) users-карта в yaml — компактный JSON (jq -sc). hysteria2-grant CLI + пункт меню 'Ссылка hysteria2' с QR. Живой тест HAPP-тела с hysteria2-строкой — срез 7.
…ninstall, меню 12/13) Спайк по README amneziawg закрыл главное допущение: официальный путь — PPA amnezia/ppa + apt install amneziawg (DKMS-модуль + tools), для Debian — ручная строка репо; фолбэк — сборка из исходников, где для ядра >=5.6 нужен ПОЛНЫЙ linux-source (headers недостаточно) с линком kernel-symlink в дерево модуля. Junk-параметры подтверждены по спеке: Jc 1..128, Jmin<Jmax<=1280, S1/S2 15..150 (S1+56!=S2), H1-H4 уникальные 5..2147483647 — генерируются случайно при install и попадают в server-params.json и в каждый клиентский конфиг. - _awg_install: PPA -> ручная сборка -> приёмка modprobe+lsmod+awg show awg0; реестр последним шагом; неудача = чистый откат артефактов (без полу-состояний) - интерфейс awg0 через awg-quick@awg0, конфиг 0600, Address 10.8.1.1/24, MTU 1280, PostUp/PostDown MASQUERADE на iface default-route (детект при install, литералом в конфиг) - ip_forward через /etc/sysctl.d/99-xrayebator-awg.conf; порт — случайный высокий 20000-59999 с проверкой занятости (ss) и конфликта с hysteria-портом - uninstall гасит интерфейс и убирает артефакты, пакеты/модуль остаются в системе (честно пишется в выводе) - меню 12 (AmneziaWG) и 13 (Статус бэкендов) + CLI awg-install/uninstall/status (JSON-гигиена, rc=2 -> already) - test-awg-lifecycle.sh (31-й): junk-параметры в спеке 5/5 прогонов, рендер конфига, keygen через fake awg, реестр/статус, статика диспетчера; полный install с сетью+DKMS — живой спайк среза 7 - нумерация меню расширена осознанно до 1..13
…лный жизненный цикл
Профиль — источник правды: .backends.awg {client_private_key, client_public_key, preshared_key, address} ; awg0.conf [Peer]-секции регенерируются из профилей (фильтр expire_disabled) и применяются рестартом интерфейса с откатом. Осознанный компромисс: рестарт коротко рвёт туннель всех peer-ов — гранты/отзывы редки, для этапа 1 приемлемо; живые awg set-мутации без рестарта — кандидат этапа 2.
- аллокация адресов: первый свободный .2..254 с учётом уже выданных в профилях (.2 -> .3 проверено тестом)
- события через общий lifecycle-хук диспетчеризуются автоматически: created (грант), revoked (ротация ключей с сохранением адреса — старые клиентские конфиги перестают подключаться), deleted/expired/restored (реген; restored возвращает peer после продления)
- клиентский .conf (_awg_client_conf_pure): клиентская тройка, серверный pubkey/endpoint, junk-параметры копируются с сервера (спека: должны совпадать кроме Jc/Jmin/Jmax), AllowedIPs full-tunnel, Keepalive 25
- CLI awg-grant/awg-conf (JSON, conf в поле для GUI) + пункт меню 'Конфиг клиента' с QR; --grant-all при install
- тест расширен до 12 проверок: адреса, peer-секции, форма клиентского конфига, все события; caught: no-op uninstall должен учитывать существование conf-файла
… (GUI-контракт)
GUI (этап 2) будет читать бэкенды из тех же JSON, что уже потребляет: profiles_command добавляет объект .backends профиля (гранты hysteria2/awg — креденшелы уровня оператора, как уже выданный sub_token), inspect_command — секрет-фри сводку реестра {installed, version, port} для импорта существующего сервера. STRICT read-only сохранён: inspect читает реестр только если файл существует и не создаёт его (гвардится test-quickstart-email-and-inspect.sh — прогнан, зелёный). Старые клиенты/GUI поля просто игнорируют — аддитивность.
…сервере
Срез 7, первая половина: сервер Ubuntu 24.04 (ядро 5.15, 16 ядер) — install.sh (канонический main) + перезапись менеджера dev-версией + quickstart --without-email (подписка 8443, IP-серт certbot 5.8, 7-маршрутный профиль). Затем hysteria2-install --grant-all.
Поймано и починено:
1. CHDIR Permission denied юнита: каталог backends/hysteria получал 750, но оставался root:root — добавлен chown root:hysteria на каталог (права группы без смены владельца не работают).
2. 'empty auth userpass': hysteria отвергает ПУСТУЮ userpass-карту — введён placeholder-пользователь _xrayebator_placeholder (случайный пароль в 0600-файле, в карте только пока нет грантов).
3. ГЛАВНОЕ: поле auth-карты называется userpass, а не users — с 'users:' hysteria игнорировал карту и падал с 'empty auth userpass' независимо от содержимого. Проверено живым запуском: server up and running.
4. В HAPP-теле hysteria2-строка слипалась с последним vless:// (command substitution съедает trailing newline) — printf '%s\n' в HAPP-ветке; handler перегенерирован, тела проверены curl'ом.
Результат на сервере: hysteria v2.12.3 активна на UDP/443, TLS=le (IP-серт), users-карта {happ: <грант>}, hysteria2:// строка в обоих телах подписки, флаг sub_body=true.
…сервере AWG установлен и проверен live на Ubuntu 24.04 / ядре 5.15: PPA недоступен для этой серии -> ручная сборка сработала (модуль в lsmod, tools v3.1), интерфейс awg0 поднялся, peer профиля виден в awg show, ip_forward+MASQUERADE работают. Поймано и починено: 1. Юнит awg-quick@awg0 ищет конфиг в /etc/amnezia/amneziawg/ — наш файл линкуется туда symlink'ом (источник правды остаётся в backends/awg/), uninstall снимает линк. 2. Mismatch имён jq-переменных в _backend_set: port/mtu/junk в awg-цепочке (expr \/\/\ против аргументов port/mtu/junk) —Registry-запись молча обрывалась на втором поле. Все 13 мест выверены grep'ом. 3. Откат при неудаче записи реестра оставлял висящий symlink и полу-запись .awg — теперь чистит и то, и другое (проверено: backend-status после отката чист). 4. Диспетчер awg-install не пробрасывал \$@ — CLI-флаги (например --grant-all) молча терялись. 5. _awg_install читал режим грантов из \, хотя у AWG нет аргумента порта — режим всегда падал в prompt. Теперь \ (у hysteria — \, там порт первый). Полный жизненный цикл подтверждён live: revoke ротирует пароль hysteria и ключи AWG peer-а синхронно в обоих конфигах; expire снимает грант и peer (placeholder в userpass-карте держит конфиг валидным); restore возвращает оба; подписка с ротированным токеном отдаёт 200 и hysteria2-строку в обоих телах.
Синхронизация всех доков с мультибэкенд-обновлениями и добавление раздела AWG 3.1 по статье Хабра (meshroom, 'AmneziaWG: от 2.0 к 3.1') с учётом специфики пассивного анализа ТСПУ/DPI. - architecture (en/ru/zh): дерево состояния с /usr/local/etc/xrayebator и новыми юнитами; секция Multi-protocol backends (реестр, lifecycle через профиль как источник правды, hysteria2/awg-модели); hysteria2-строка в обоих телах подписки - configuration (en/ru/zh): меню 1..13 (восстановлен потерянный пункт 7 bypass), все новые CLI-команды, секция Multi-protocol backends с таблицей 'должны совпадать побайтово vs локальные' и правилами миграции на 3.x; отремонтирован сломанный заголовок секции Bypass (висел текст без заголовка во всех трёх языках) - security (en/ru/zh): модель безопасности бэкендов — registry 644 без секретов (читается subhttp от xray), hysteria root:hysteria 750/0640, awg 700/0600, deploy-hook, placeholder-credential, ip_forward/MASQUERADE - testing (en/ru/zh): 28 -> 31 скрипт + три новых сюиты с описанием, граница 'CI с моками vs live-спайк' - troubleshooting (en/ru/zh): четыре новых раздела — Hysteria не стартует (userpass/CHDIR/placeholder), AWG без latest handshake (чек-лист must-match из статьи, версии клиентов AmneziaVPN >= 5.0.1.5), установка AWG (PPA/linux-source/symlink), отсутствие hysteria2-строки в подписке (sub_body) - README (en/ru/zh): чипы hysteria2/amneziawg + абзац о мультипротокольном этапе - CLAUDE.md синхронизирован ранее (31 тест, все команды)
…блер awg-31
Вопрос 'реализован ли 3.1' закрыт: раньше мы ставили бинари поколения 3.1, но генератор эмитил только набор 2.0. По исходникам kernel-модуля (master: 'feat: awg 3.1 features', 'prevent HeaderProtectionKey from setting if any Sx less then 12') модуль поддерживает 3.1 — недостающим был только наш генератор.
- _awg_gen_junk: S1-S4 все >=12 (12..150, уникальные; спека 3.x), HeaderProtectionKey (openssl rand -base64 32, общий секрет сервер/клиенты)
- рендеры server/client: S3/S4 всегда, HPK + RandomTrailers=on при three_enabled, DisableCookies=on опционально (по умолчанию off — сохраняем anti-amplification)
- awg-31 --on|--off [--disable-cookies] + пункт меню 12: тумблер для живых установок; _awg_ensure_31_params догенеряет S3/S4/HPK в старый server-params; смена = реген интерфейса с откатом + явное предупреждение о перевыпуске всех клиентских .conf (AmneziaVPN >= 5.0.1.5)
- live (2.26.125.147): awg-31 --on -> awg0.conf с S3/S4/HPK/RandomTrailers принят модулем (awg show), клиентский .conf содержит те же 3.1-ключи
Поймано и починено:
1. _backend_field с jq '// empty' проглатывал легитимный boolean false (three_enabled=false читался как пусто и дефолтил в true) — заменено на tostring с guard; тест-регресс добавлен
2. условные printf рендера писали в stdout вместо файла конфига
3. парсер awg (kernel UAPI) принимает булевы только on/off — 'RandomTrailers = true' отвергается ('Boolean value is neither on/off nor 0/1'); в доках и CLAUDE.md зафиксировано
4. формат булевых в docs (en/ru/zh) обновлён: реализация 3.1 вместо 'не эмитит 3.x-ключи'
GUI ничего не придумывает про сервер — только вызывает JSON-команды. Новый BackendManager повторяет паттерн ProfileManager (run + extractJson + describeFailure) и даёт IPC-каналы: backends:status (реестр), backends:hysteria2Grant/awgGrant (гранты per-профиль), backends:awgConf (клиентский .conf для AmneziaVPN — секреты уровня оператора), backends:awg31 (тумблер 3.1 с предупреждением о перевыпуске). Модель этапа 2 (согласована): бэкенды живут одновременно, доступ транспорта определяется грантами конкретного профиля, глобальных режимов запуска нет. - shared/types: ProfileBackends в ServerProfile (аддитивно), BackendEntry/BackendStatusResult/AwgConfResult/BackendToggleResult, секция backends в ElectronAPI - чистые парсеры parseBackendStatus/parseAwgConf вынесены отдельно и покрыты тестами (7): полный статус, пустой реестр, ANSI-загрязнение stdout, ошибка реестра, 3.1-ключи в .conf, отсутствие гранта - typecheck 0; vitest: 112 зелёных, единственный красный — задокументированный Windows-only shell-command (/bin/sh), CI на Ubuntu авторитетен - UI-экраны (срезы B/C) — следующие коммиты; renderer пока не менялся
…ings Карточки Hysteria 2 и AmneziaWG 3.1: статус (active/port/версия/режим 3.1), установка и удаление с диалогами подтверждения, тумблер 3.1 (явное предупреждение о перевыпуске .conf), kill-switch hysteria2-строк в подписке. У карточки AWG — пометка пользователя: «работает через клиент AmneziaVPN, а НЕ через V2Ray-клиентов (HAPP)». Серверная часть: новый CLI hysteria2-subbody --on|--off (kill-switch без рестартов — handler перечитывает реестр на каждый запрос); main-адаптеры hysteria2Install/Uninstall, awgInstall/Uninstall, hysteria2Subbody; IPC backends:hysteria2*/awg*; preload-секция расширена. Отказоустойчивость UI: backend-status недоступен/неизвестен на старом сервере -> секция показывает «обновите менеджер», не ломая страницу (load оборачивает загрузку бэкендов в отдельный try). i18n ru/en/zh — 22 новых ключа.
…HAPP) hysteria2-строка в подписке подписывалась голым именем профиля (#happ) и выглядела в HAPP иначе, чем VLESS-маршруты (🇩🇪 Germany · happ-tcp-xudp). _hysteria2_profile_link_pure теперь повторяет именование _generate_vless_url_pure: префикс 🇩🇪 Germany · из geo-маркера (флаг + страна; нет маркера — голое имя, как у VLESS) и URL-кодирование фрагмента через jq @uri. Живой тест: подписка отдаёт #🇩🇪 Germany · happ.
…анты)
Кнопка «Ключи» у каждого профиля в Server Settings открывает диалог: Hysteria 2 — hysteria2-ссылка (Chip HYSTERIA2·UDP, копирование, QR; пометка: работает в HAPP/Hiddify/v2rayN) и AmneziaWG — полный клиентский .conf (Chip AMNEZIAWG 3.1·UDP, pre-блок, копирование, QR; пометка пользователя: «AmneziaVPN — НЕ V2Ray/HAPP, импорт в AmneziaWG/AmneziaVPN, full-tunnel, >= 5.0.1.5»).
Нет гранта — в диалоге кнопка «Выдать грант» (hysteria2-grant/awg-grant) с автоматическим обновлением ключей. Это закрывает цикл выдачи AWG-ключей из GUI без CLI — тестовый путь пользователя для проверки AWG из РФ.
- новый CLI hysteria2-link --name N (JSON {ok,name,link}) — серверный билдер ссылки с флагом страны
- QR рендерится локально (qrcode toDataURL, Esc/клик закрывают) — серверный qrencode не нужен
- путь доставки AWG: GUI-диалог вместо ручного SSH — как договорились (текст+QR, без скачивания файла)
… ключей через GUI Клиентский .conf AWG начинается с шапки-пометки (требование этапа 2): транспорт AmneziaWG работает НЕ через V2Ray-клиенты (HAPP/v2rayNG), а через AmneziaVPN/AmneziaWG; имя профиля и напоминание перекачать конфиг после смены ключей. В приложении AmneziaVPN содержимое конфига видно — пометка едет вместе с файлом; в само чужое приложение мы не лазим. Доки (en/ru/zh, configuration.md): AWG-секция дополнена выдачей ключей через GUI («Ключи» в Server Settings: hysteria2-ссылка и AWG .conf текстом с QR + выдача гранта в один клик). Тест awg-lifecycle проверяет шапку (startswith '# Xrayebator:'). Live: шапка видна в awg-conf --name happ на 2.26.125.147.
Фидбек: карточки были похожи только цветом, между ними торчала полоска-разделитель, QR с AWG-конфигом не импортировался в приложение.
- каждый бэкенд теперь в СВОЁМ боксе (backendCard: bg-2/border/radius-16 — стилистика остальных карточек приложения), сетка auto-fit 340px
- полоска border-top между рядами убрана
- иконки в цветных бейджах (Zap — жёлтый для hysteria, Shield — голубой для AWG) + подзаголовки ('быстрый UDP · QUIC' / 'системный VPN · full-tunnel')
- тексты переписаны короче и по делу; у AWG-ноты явно: клиент AmneziaWG/AmneziaVPN, НЕ V2Ray/HAPP
- QR для AWG теперь из конфига БЕЗ комментариев-шапки: часть приложений спотыкается при импорте с камеры о строки до [Interface] (текст и копирование остаются с шапкой)
typecheck 0, unit-тесты зелёные.
… AWG-конфиги)
Пользователь не видел hysteria2/AWG «в самих ключах» — страница Ключей парсила из подписки только vless://. Теперь:
- subscription.ts: extractHysteria2Links() — hysteria2:// из HAPP- и generic-тел (включая base64-блоки); fetchSubscription возвращает {keys, hysteria2Links}; deployer/inspector-вызовы адаптированы
- страница Ключей: hysteria2-карточки (chip HYSTERIA2 · UDP :порт, копирование+QR — QR сканируется HAPP/Hiddify напрямую) и AWG-карточки per-profile (полный .conf с 3.1-ключами, копирование + QR без комментариев-шапки для совместимости импорта)
- AWG-конфиги тянутся по SSH с доступом из сохранённой карточки сервера (shouldAutoConnectServer гейтит секцию — секрет должен лежать в keychain)
- ServerSettings: карточки бэкендов поставлены одна под одной (фидбек «совместить 1 под 1»), подчёркнутые «ВНИМАНИЕ»-нотки заменены на нейтральные
- i18n keys.* ×3 языка
typecheck 0; vitest: только задокументированный Windows-only shell-command; bash -n чистый
…юч (не конфиг) Фидбек: протоколы грузятся в реальном времени (ожидание), карточки не совмещены, AWG выглядит конфигом, а не ключом; hysteria перекрывается amnezia. - загрузка бэкендов ПАРАЛЛЕЛЬНО с профилями (Promise.all в load) + скелетоны-заглушки вместо пустоты - карточки бэкендов объединены в ОДИН общий бокс (listCard), блоки протоколов один под другим с отступами (полосок нет) - кэш awg-conf в main-process (инвалидация при смене грантов/режима 3.1/uninstall): страница Ключей открывается мгновенно при повторном заходе, как с обычными коннекторами - AWG теперь показывается как КЛЮЧ: поля Endpoint и Адрес (parseAwgClientConf из нового shared/awg.ts), кнопки — копирование конфига и QR (QR без комментариев-шапки для совместимости импорта); простыня конфига убрана - hysteria2-карточки на странице Ключей — из подписки, грузятся вместе с vless (extractHysteria2Links); deployer/inspector адаптированы к новому возврату fetchSubscription - shared/awg.ts + тесты (10/10: shared + backend-manager) typecheck 0; vitest — только задокументированный Windows-only shell-command; bash -n чистый
…айминг с vless)
Фидбек: hysteria/awg подгружаются в реальном времени без сохранения, каждый раз и в разный тайминг; должны — как vless, ~моментально и из приложения.
- Server record: hysteria2Keys (строки из подписки) и awgConfs (per-profile) персистятся в store; normalizeServer даёт дефолты; store.updateBackendKeys — мерж/очистка
- subscription:fetch пишет hysteria2Keys рядом с vless-ключами
- backends:awgConf пишет конфиг в карточку сервера (store вместо in-memory Map); awgGrant/awg31/awgUninstall очищают кэш при ротации
- страница Ключей: мгновенная инициализация из server.hysteria2Keys/awgConfs, затем тихое фоновое обновление; ВСЕ запросы — одним Promise.all (profiles+backends+awgConf×N) — равный тайминг, без каскада
- карточки бэкендов в Server Settings: один общий бокс, блоки протоколов 1-под-1 (фидбек), параллельная загрузка + скелетоны
- AWG как ключ: поля Endpoint/Адрес (shared/awg.ts parseAwgClientConf), QR/копирование — конфиг без комментариев-шапки
- fetchSubscription -> {keys, hysteria2Links}; deployer/inspector адаптированы
typecheck 0; vitest — только задокументированный Windows-only shell-command; bash -n чистый
…вшая пропса) Фидбек: бэкенд-ключи 'не сохраняются после первой загрузки' и грузятся с разнобоем. Корень: ServerKeys инициализировался из пропсы server — устаревшего снимка Dashboard'а, где ещё нет hysteria2Keys/awgConfs, плюс два отдельных эффекта давали каскад. Единый эффект: (1) мгновенная отрисовка из ПЕРСИСТЕНТНОГО стора через servers.get — пропса больше не источник правды; (2) фоновое обновление одним Promise.all: подписка + profiles/backends + awgConf×N параллельно — равный тайминг с vless, без скелетон-мигания при повторных заходах (данные уже в сторе). typecheck 0; vitest — только задокументированный Windows-only shell-command; bash -n чистый
…нальный sync со стором Фидбек: AWG-конф 'не сохраняется' + спиннер висит после загрузки под карточкой. - неудачный refetch больше не стирает сохранённый конфиг (last known good: merge только по успешным) - после пакета загрузки — финальная синхронизация состояния со стором (servers.get): состояние == персистентные данные, расхождений нет - спиннер перенесён СТРАНИЦУ -> ВНУТРЬ карточки AWG: показывается только пока у конкретной карточки нет конфига и идёт загрузка; после загрузки ничего лишнего под карточкой не остаётся typecheck 0; vitest — только задокументированный Windows-only shell-command; bash -n чистый
…kends.status) Фидбек: AWG-конфиг появлялся только после SSH-ответа backends.status+profiles (~2 сек), хотя конфиг уже лежит в сторе. Карточки AWG на странице Ключей теперь строятся из Object.keys(awgConfs) стора напрямую — рисуются с первой отрисовкой (мгновенно), SSH-refresh догоняет тихо. Гейт awgActive убран: факт наличия конфига в сторе достаточен (uninstall очищает конфиги через стор). backends.status со страницы Ключей убран совсем — минус одно SSH-звено; profiles.list остаётся для имён granted-профилей без конфига (спиннер внутри карточки). typecheck 0; vitest — только задокументированный Windows-only shell-command; bash -n чистый
…емнённых под-боксах Фидбек: заголовок/hint секции висели вне бокса, ноты протоколов — просто текстом под статусом. Теперь: заголовок и hint перенесены ВНУТРЬ общего бокса (текста вне боксов нет), описательные ноты Hysteria/Amnezia обёрнуты во внутренний более затемнённый под-бокс (backendInfo, как затемнённые inner-box у ключей) — визуально отделены от действий. Справочно: последняя версия AmneziaWG подтверждена GitHub API — v3.1.20260812 (tools), генерация протокола 3.1; 3.2 не существует. Live-сервер 2.26.125.147 уже на ней. typecheck 0; vitest — только задокументированный Windows-only shell-command; bash -n чистый
Вместо двух маленьких под-боксов под ноты — ОДНА большая затемнённая выемка (backendsInner, стиль inner-box ключей), в которой лежат оба блока протоколов: сверху заголовок/hint секции, под ними выемка с Hysteria и AmneziaWG один под другим. Ноты — обычным текстом внутри выемки. Внешнее округление — существующий сероватый listCard. typecheck 0; vitest — только задокументированный Windows-only shell-command; bash -n чистый
…иагностика AWG) - configuration.md (en/ru/zh): в CLI-таблицах отсутствовали команды, которые есть в диспетчере: hysteria2-subbody, hysteria2-link, awg-31; GUI-секции дополнены панелью бэкендов (установка/ключи/килл-свитч/3.1) - desktop-gui.md (en/ru/zh): страница «Ключи» — карточки бэкендов из персистентного стора (Endpoint/Address полями, QR без служебной шапки, параллельная загрузка); Server Settings — пул бэкенд-действий; блок backend-команд в списке exposed - troubleshooting.md (en/ru/zh): в секции «нет latest handshake» — диагностика сетевого пути: AWG-сокет в ядре невидим для ss, tcpdump -l (без -l блочный буфер), пустой захват = оператор/DPI, пакеты есть а handshake нет = версия приложения или awg-31 --off fallback. Отработано на живом 2.26.125.147 (пробы РФ->45467 дошли) - ru configuration.md: починена оборванная фраза «предоставляет / и группы» - CLAUDE.md: CLI-список Hysteria 2 дополнен subbody/link
Корень: телефон шлёт junk с собственными параметрами приложения (5 пакетов/попытку при наших Jc=10 — tcpdump 2.26.125.147), т.е. сырой .conf при импорте в AmneziaVPN теряет junk-группу. По исходникам amnezia-client (importController.cpp) правильная доставка — контейнер amnezia-awg с last_config, куда импортёр переносит все AWG-ключи (awgProtocolKeys); сырой текст не гарантирует этого пути. - shared/awg.ts: parseAwgConfMap + buildAwgVpnConfig + buildAwgVpnUrl — чистый Builder структуры extractWireGuardConfig (hostName/port/ client_priv_key/psk_key/server_pub_key/allowed_ips + AWG-ключи), vpn:// + base64url без qCompress (импортёр деликатно принимает несжатое тело — проверено по исходникам dev-ветки) - Ключи (ServerKeys) и диалог ключей (ServerSettings): вторая кнопка QR «AmneziaVPN» рядом с QR для AmneziaWG; чип без жёсткой версии - i18n ru/en/zh: keys.backendsQrVpn - vitest: 7 тестов (структура, base64url-чистота, кириллица, минимум)
error 1000 + предупреждение «старая версия»: last_config без явной версии протокола AmneziaVPN трактует как legacy и запускает туннель не тем поколением. Добавлен protocol_version в last_config и контейнер (значения из их protocolConstants: 1.5/2/3.1), версия выводится из содержимого конфига: HPK/RandomTrailers -> 3.1, I1-I5/ContentPadding -> 2, иначе 1.5. detectAwgVersion экспортирован и протестирован.
…amnezia-awg2) По исходникам amnezia-client (containerUtils.cpp + AwgProtocolConfig::toJson): их формат кладёт серверные junk-параметры (Jc/S1/H1/HPK/...) на уровень объекта 'awg' рядом с last_config (модель сервера читает их оттуда), специальный junk I1..I5 пишет безусловно (пустые строки валидны), а новый контейнер называется 'amnezia-awg2'. Наш прошлый формат с junk только внутри last_config оставлял серверную часть модели пустой, из-за чего сервис терял client_ip (error 1000, подтверждено логом телефона).
…qCompress) Эталон — реальный экспорт рабочего docker-сервера (LV): серверные junk на уровне awg + range-таймеры go-туннеля (Rekey/Keepalive/Reject/Max- Handshake 100-120/3-7/150-180/5-15/15-20) + ContentPaddingAddition в JSON (не kernel), client_ip без маски, client_pub_key+clientId в last_config, subnet_address, persistent_keep_alive, qCompress-payload. Симуляция конвейера 5.0.1.5 (import→model→service-config) подтвердила прохождение client_ip; error 1000 у пользователя — следствие отсутствия серверной части модели в прошлых форматах.
Живое подтверждение (телефон, LTE, AmneziaVPN 5.0.1.5): наш кастомный junk (Jc=10, крупные пакеты 130-452, случайные H1-H4) go-туннель приложения применяет не целиком — всплески по 5 пакетов против ожидаемых ~11, handshake не собирается. LV-сервер Amnezia с дефолтным диалектом с того же телефона работает. - _awg_gen_junk: Jc=5, Jmin=10, Jmax=50, H1-H4=1..4 (WG-магия), S1/S2 rand 12..150, S3/S4 rand 12..64 (лимиты их валидатора), уникальность и S1+56≠S2 сохранены; HPK/RandomTrailers без изменений (3.1-маскировка полная) - test-awg-lifecycle: ассерты на дефолтный диалект Amnezia - docs en/ru/zh: junk = дефолты Amnezia; awg-install row; testing.md; новый кейс troubleshooting «AmneziaVPN error 1000 / No value for client_ip» (нативный shape vpn://, QR · AmneziaVPN); CLAUDE.md Своя логика осталась там, где ей место: Hysteria 2 и VLESS/Reality. AWG теперь = 1:1 с Amnezia + наши HPK/RT и выдача ключей через GUI.
Аудит синхронизации en/ru/zh после 71f6bfc и d17a916. Найдено и исправлено: 1. configuration.md ×3: buffer-текст привязывал 32k только к `location /sub/` — d17a916 поднял буферы и в IP-mode vhost (quickstart, `location /`); формулировка обобщена на «вхост подписки, оба режима». 2. configuration.md ×3: строка sni-list дополнена контрактом из 71f6bfc — первая незакомментированная строка sni_list.txt = SNI по умолчанию для новых профилей (www.cloudflare.com). 3. README ×3: «AmneziaWG 2.0» → «AmneziaWG 2.0/3.1» — 3.1 давно реализована и включена по умолчанию (секции «2.0 vs 3.x» в доках уже были). 4. CLAUDE.md: 31 → 33 Bash-теста (реальное число в validation/), в перечне покрытий добавлен HAPP client-routing generator. Проверено: устаревших утверждений о приоритетах/дефолтах SNI в доках не было; architecture.md не детализирует junk/буферы; исторические числа в CHANGELOG/releases не тронуты (они про свой период).
…и профилей
Запрос пользователя на компоновку Server Settings:
1. В боксе «Создать профиль» под сеткой VLESS-транспортов — подзаголовок
«Мультипротокольные бэкенды» и две широкие карточки (Hysteria 2,
AmneziaWG 3.1) с логотипами и описаниями в стиле protocolHint. Клик
создаёт профиль через обычный profiles.create (имя/количество/срок/транспорт —
из общей формы) и сразу выдаёт ключ бэкенда (hysteria2Grant/awgGrant).
Если бэкенд не установлен — внятная ошибка с указанием на раздел ниже
(установку сознательно не прячем в клик: DKMS-сборка AWG долгая).
Fallback-перечитывание списка — как в обычном create (профили могли
создаться даже при ошибке парсинга). Частичный отказ выдачи ключей
показывается отдельным сообщением.
2. Бокс «Мультипротокольные бэкенды» остаётся (серверные операции:
install/uninstall, вкл/выкл, Revoke всех, Срок) и помечается бейджем
«в разработке · запасной» — по решению пользователя он запасной,
а основной путь — карточки в профилях.
3. В списке профилей: у профиля с ключом бэкенда появляются отдельные
карточки Hysteria 2 / AmneziaWG 3.1 (дубликаты стиля бэкенд-блока,
разделённые по протоколам): логотип, имя профиля, статус-чип,
Ссылка/Конфиг + QR (+ QR · AmneziaVPN для AWG через buildAwgVpnUrl),
Срок (профильный expiry — он же гасит ключ бэкенда) и Перевыпустить
(profile-revoke — ротация и sub_token, и креденшелов бэкенда через
lifecycle-хук). Кнопки выдачи дизейблятся, когда бэкенд не active.
i18n: новые ключи settings.backends{DevBadge,CreateHint,CreateHystDesc,
CreateAwgDesc,CreateNotInstalled,Created,CreatedPartial,CardLink,CardConf}
в ru/en/zh; остальные подписи переиспользованы (backendsTitle, keys.qr,
keys.backendsQrVpn, backendsExpiryBtn, backendsReissue, backendsActive).
Проверки: npm run typecheck ✓; vitest 119/120 — единственный фейл
shell-command.test.ts воспроизводится на чистом HEAD (Windows: spawn
stderr = null), к изменениям не относится. Слово «грант» в UI не
используется — по фидбеку пользователя.
…м в ряд Корень: .profileCard — flex-строка (main | actions, space-between); две новые .backendProfileCard стали её третьим/четвёртым элементом, легли справа от кнопок, распирили карточку и растянули страницу — пользователь видел «отдельные квадратные профили» вне бокса. Фикс: flex-wrap: wrap у .profileCard (main+actions остаются на первой строке, при узком окне actions аккуратно уходят вниз) + flex-basis: 100% у .backendProfileCard — каждая бэкенд-карточка занимает собственную строку внутри карточки профиля. На узких экранах перенос теперь работает и для обычных детей, что само по себе улучшение.
- Revoke показывал сырой i18n-ключ settings.backendsReissue (ключа нет — Перевыпустить живёт в keys.backendsReissue): кнопка светила литерал 'settings.backendsReissue'. Исправлено на keys.backendsReissue. - Кнопки копирования Ссылка/Конфиг убраны — копирование делается в Ключах (решение пользователя); остались QR (+ QR · AmneziaVPN). - Чип «Активен» убран: у других карточек в списке статус-надписей нет, визуального паритета не было. Неактивный бэкенд по-прежнему гасит кнопки выдачи. - Добавлена кнопка Удалить (с тем же protected-гвардом multi_route, что у основной карточки) — бэкенд-карточка вела себя как неполноценный профиль без удаления. - Мёртвые i18n-ключи settings.backendsCardLink/CardConf удалены из ru/en/zh; обработчики copyProfile* удалены (noUnusedLocals). Проверки: typecheck чисто; vitest 119/120 — фейл только известный Windows-флейк shell-command (stderr=null на чистом HEAD).
По фидбеку пользователя: 1. «Основной профиль»-замок убран с бэкенд-боксов — они не основные; на multi_route просто нет кнопки Удалить (защита сохранена), без поясняющей плашки. 2. Метка кнопки унифицирована с основными карточками: settings.revokeBtn («Revoke») вместо keys.backendsReissue («Перевыпустить») — раньше основной профиль назывался Revoke, бэкенд — Перевыпустить, разнобой. 3. Главное: бэкенд-боксы больше не вложены в карточку профиля — это отдельные сиблинги во Fragment (как доп. протоколы рядом с основным боксом): профиль-VLESS, ниже отдельный тёмный бокс Hysteria 2, ниже отдельный бокс AmneziaWG 3.1, каждый с бортом/фоном карточки. flex-wrap/basis хак из предыдущего фикса откатан за ненадобностью. Проверки: typecheck чисто; vitest 119/120 (известный Windows-флейк shell-command, не связан).
По фидбеку пользователя: 1. Кнопка Удалить не была видна: я прятал её за гвардом multi_route, а бэкенд-боксы висят на основном happ-профиле. Теперь Удалить показывается всегда — как у других профилей; подтверждение удаления остаётся. 2. Подзаголовок «happ · UDP» читался как название протокола («почему пишется Happ?» — Hysteria работает и в Hiddify/других v2ray-клиентах, а Amnezia в HAPP вообще не подходит). Заменено на протокольные подписи из бэкенд-бокса: settings.backendsHystSub / backendsAwgSub. Проверки: typecheck чисто; vitest 119/120 (известный Windows-флейк).
…ll-tunnel» По фидбеку: «системный VPN · full-tunnel» — не фишка, которую надо выводить; пользователь хочет идентификаторы соединения и живость: - Hysteria 2: «Активен · SNI <sni>» (SNI берётся из backend-status, поле sni у BackendEntry — синхронно, без дозвонов; если пусто — «Активен · UDP <port>») - AmneziaWG: SNI нет по природе протокола — «Активен · UDP <port>» - неактивный бэкенд — серое «Не установлен», как в нижнем боксе Стиль строки — тот же зелёный backendState/Ok, что в секции «Мультипротокольные бэкенды». Проверки: typecheck чисто; vitest 119/120 (известный Windows-флейк).
Решение пользователя: функция выдачи/копирования ключей жила в трёх
местах (диалог на карточке профиля, бэкенд-боксы, страница Ключей) —
дублирование. Удалены:
- кнопка «Ключи» (beKeysBtn) из карточек профилей Server Settings;
- сам диалог ключей бэкендов (AlertDialog keysTarget) со состояниями
keysTarget/keysHyst*/keysAwg*/keysBusy и обработчиками
fetchBackendKeys/openBackendKeys/closeBackendKeys/grantBackend/
copyKeysText/keysAwgFields; из импортов выпал parseAwgClientConf;
- мёртвые ветки hysteria2-regrant/awg-regrant в confirmBackend (сеттеров
не существовало после рефакторинга Среза C) + члены union-типа;
- мёртвые i18n-ключи ru/en/zh: settings.beKeys* (7 шт),
backendsConfirmReissue{Hyst,Awg}.
Осталось: QR-кнопки на бэкенд-боксах (showKeysQr/keysQrUrl — используются),
Срок/Revoke/Удалить на боксах, полное копирование — только страница Ключей.
Проверки: typecheck чисто (пойман и исправлен дубль keysQr-состояний);
vitest 119/120 — известный Windows-флейк shell-command.
…офиля Найдено живой приёмкой кнопок GUI на 2.26.125.147: 1. profile-delete печатал цветную строку backup_config в stdout ПЕРЕД redirect-ом (exec 1>&2 стоял после вызова) — GUI получал 'color-line + JSON' и ломал парс: кнопка Удалить показывала ошибку при фактически успешном удалении. Redirect поднят выше backup_config, её ошибка уходит в >&3 как положено. 2. _awg_on_profile_event/_hysteria2_on_profile_event: кейс deleted гвардил [[ -f profile_file ]], но вызывающий удаляет файл ДО lifecycle-вызова — реген молча пропускался, и осиротевший peer (awg0.conf) / пароль (server.yaml) оставались навсегда: удалённый пользователь сохранял доступ к VPN. deleted отделён от expired|restored и регенит безусловно. Регрессионные кейсы в test-awg-lifecycle (carol: rm -> event deleted -> peer снят, активный peer цел) и test-hysteria2-lifecycle (cleo: rm -> event deleted -> грант исчез из users-map, alice не задета). Проверки: bash -n; оба lifecycle-теста зелёные; полный сьют 33/33.
…рофилей По фидбеку пользователя после живой проверки: 1. Анимация: клик по карточке Hysteria/AWG дёргал синий спиннер в самой карточке. Теперь создание включает общий creating — весь бокс «Создать профиль» получает жёлтую обводку (createCardBusy) и штатный индикатор, ровно как у VLESS-протоколов. 2. Семантика: клик по карточке больше НЕ создаёт профиль немедленно (раньше получалось 2 ключа: VLESS по выбранному транспорту + бэкенд по клику). Карточки Hysteria 2 / AmneziaWG 3.1 стали радиовыбором в общем селекте с транспортами (выбор транспорта сбрасывает бэкенд и наоборот, активная карточка подсвечивается accent-ом), профиль создаётся только кнопкой «Создать профиль». У бэкенд-профиля подкапотный транспорт — xhttp. 3. Имена профилей: бэкенд-боксы в Server Settings озаглавлены именем профиля (Hysteria 2/AWG — в подписи с дескриптором), на странице Ключей в чип Hysteria-карточки добавлено имя профиля (user из ссылки) — раньше по чипу было невозможно отличить ключи разных профилей. i18n: backendsCreateHint переписан под модель «выбери и нажми» (ru/en/zh). Проверки: typecheck чисто; vitest 119/120 (известный Windows-флейк shell-command, к изменениям не относится).
Корень жалобы «создаётся 3 профиля (XHTTP+Hysteria+Amnezia), а не выбранный»: событие lifecycle 'created' автоматически выдавало ключи ВСЕХ установленных бэкендов каждому новому профилю (_hysteria2_on_profile_event/ _awg_on_profile_event, кейс created -> grant). Выбор протокола в GUI перекрывался авто-выдачей. Фикс: created = no-op в обоих хендлерах — ключ бэкенда выдаётся только явным grant (выбор протокола в GUI / меню 11-13 / grant CLI). wiring в create_profile/_profile_cli_create_one сохранён (created-событие ещё понадобится), семантика задокументирована в CLAUDE.md. Pre-check имени (запрос пользователя): удаление по имени снимает ВСЕ ключи профиля, поэтому коллизия имени ловится ДО создания в обоих GUI-потоках (create и createBackendProfiles) — понятная ошибка с именем вместо частичного создания. i18n errorNameExists ru/en/zh. Регрессионные кейсы: event created = no-op (нет .backends после события) в test-awg-lifecycle и test-hysteria2-lifecycle. Проверки: typecheck чисто; оба lifecycle-теста зелёные; vitest 119/120 (известный Windows-флейк).
Синхронизация документации с 2d17ea0 и c2f746a: - desktop-gui.md ×3: создание — выбор протокола (6 VLESS-транспортов или карточки Hysteria 2 / AmneziaWG 3.1) + кнопка «Создать профиль» (клик по карточке только выбирает, ключ выдаётся только выбранному бэкенду, подкапотный транспорт xhttp); pre-check коллизии имени (удаление по профилю целиком, уникальность имён делает его прицельным); бэкенд-боксы в списке профилей озаглавлены именем профиля с зелёной строкой статуса (SNI/порт) и действиями QR/Срок/Revoke/Удалить; панель бэкендов помечена «WIP · fallback»; кнопка «Ключи» и её диалог исключены из описания — полное копирование на странице Server keys; в чип Hysteria-карточки на странице Ключей добавлено имя профиля. - configuration.md ×3: строки profile-create (существующие имена не перезаписываются — в errors, GUI пре-чек) и profile-delete (бэкенд-гранты отзываются сразу: peer из awg0.conf, пароль из server.yaml, без осиротевших креденшелов, имя освобождается). - testing.md ×3: описания lifecycle-тестов дополнены кейсами deleted-regen (файл удалён до события) и created-no-op. - CLAUDE.md: profile-create/profile-delete bullets дополнены GUI pre-check и отзывом бэкенд-грантов при удалении.
Найдено живой проверкой обоих режимов revoke на 2.26.125.147: режим
«только новая ссылка» работает полностью (sub_token ротирован, старая
ссылка 404, uuid цел, Hysteria-пароль и AWG-ключи ротированы с
инвалидацией старых), а «полный отзыв» на single-route профилях
возвращал {ok:false, "Не удалось записать profile JSON"} и откатывался.
Корень: (.routes // []) |= map(...) — невалидный path в jq («Invalid
path expression with result []»), когда routes = null (все CLI/GUI-
созданные профили — single-route). На multi-route профиле (.routes) —
валидный path, поэтому тест-фикстура с 7 маршрутами баг не ловила.
Фикс: каноничный для кодовой базы guard has("routes") — как в
update_all_profiles_on_port.
Регрессия: test-profile-revoke-expire-cli.sh +2b — revoke --full на
single-route (uuid ротирован в профиле и в config, старый удалён,
состояние секции 2 восстановлено). Полный сьют 33/33.
По запросу пользователя: для Hysteria 2 и AmneziaWG оба режима revoke дают одинаковый результат (пароль/ключи ротируются, разница только в судьбе VLESS-uuid), поэтому карточки бэкендов открывают диалог сразу на шаге «Полный отзыв» с двойным подтверждением, без опции «Только новая ссылка». Основные VLESS-карточки профилей сохраняют выбор между двумя режимами.
Яркая красная danger-кнопка выбивалась из палитры подтверждений; теперь стиль совпадает с мягкой кнопкой удаления на dashboard.
В файле остались две копии _happ_validate_routing_json и _subscription_public_tls_endpoint_verified: первая «копия» валидатора на деле была телом _subscription_write_markers — вызов валидатора затирал бы маркеры подписки; она затенялась поздним настоящим определением, поэтому в рантайме не стреляла. Дубль verifier'а — мёртвый код. Удалены оба; живые определения (jq-валидатор schema-v3 и verifier) не тронуты.
…жет проверить http-01 Root cause (VPS 150.241.65.101, NODE HOST LIMITED, Финляндия, 2026-10-08): certbot http-01 для IP-серта стабильно получает "Connection reset by peer" от LE validation hosts — порт 80 фильтруется UPSTREAM хостера (tcpdump: SYN LE-хостов не доходят/RST mid-handshake; check-host.net: 15 узлов все reset; наш стек исправен — ufw открыт, nginx 200 тем, чьи SYN доходят, hairpin и RU-источники работают). Раньше quickstart падал с ok:false «certbot failed», сервер оставался полусобранным, GUI-деплой был невозможен. Fallback SUB_TLS_MODE=http_tls: подписка поднимается по HTTP (handler 8080 наружу, 404 без токена, токен — bearer), self-signed ECDSA серт для будущего Hysteria, ACME-challenge location на :80 сохраняется, renew-таймер НЕ ставится (в http_tls нет серта). JSON несёт degraded:true + tls_mode + certbot_reason. Повторный quickstart ПОСЛЕ разблокировки :80 у хостера выпускает LE-серт и возвращает ip_tls (идемпотентность сохранена). ip_tls-путь не изменён. Гигиена попутно: маркеры пишутся с переменной режима вместо хардкода. Тест: validation/test-quickstart-tls-fallback.sh (структура fallback-ветки, HTTP-only vhost без ssl/proxy, guard renew-таймера, degraded-метаданные).
…остика Quickstart (841ff9a) теперь возвращает degraded:true при hoster-блокировке http-01 вместо dead-end. GUI принимает fallback: - deployer: ключи тянутся curl'ом на server'е (loopback 127.0.0.1:8080 — firewall не нужен), сервер сохраняется с setupStatus=partial + degraded; - inspector: subscription_mode=http_tls → состояние «fallback» (не public и не localOnly), URL сохраняется как metadata, probe из сети не выполняется; - servers store: degraded персистится, import-upsert обновляет setupStatus; - subscription:fetch: для degraded-серверов загрузка ключей идёт по SSH; - Dashboard: partial-бейдж с подсказкой-причиной (degradedHint, ru/en/zh). Публичный HTTP URL не выдаётся за рабочий HTTPS: токен-URL по-прежнему bearer-credential, но доставляется с server'а по SSH-каналу.
…ture/troubleshooting/testing) + CLAUDE.md Задокументирован graceful-degradation путь (841ff9a + 9e6ec14): почему LE не может проверить http-01 (hoster-фильтр :80), что делает fallback (HTTP-подписка, self-signed серт, degraded-метаданные, renew-таймер не ставится), как GUI показывает сервер («Настроен частично», ключи по SSH) и как вернуть HTTPS (разблокировать :80 / доменный TLS + повторный идемпотентный деплой). Новый тест test-quickstart-tls-fallback.sh в таблицах; счётчик validation скриптов 31 → 34 (фактический подсчёт по каталогу).
…-api DE) Живой кейс 150.241.65.101: ipinfo.io относит диапазон NODE HOST LIMITED к Финляндии (Helsinki), ipwho.is/ip-api — к Германии (Frankfurt am Main). Xrayebator берёт ipwho.is → ip-api, поэтому сервер и ключи подписывались 🇩🇪. В ru/en/zh configuration.md добавлен пункт про расхождение geo-разметки и последствие для http_tls-fallback: клиент без прекашированных geo-баз не может скачать их через недоступную публичную подписку (HAPP «no data»); путь лечения — ручная правка .server_country (`код|страна|город`) + импорт ключей по SSH.
Fallback-JSON (841ff9a) строил subscription_url через _subscription_base_url, который в http_tls пишет порт 8443 и https-схему — но в этом режиме на 8443 никто не слушает, и URL вводит в заблуждение (оператор думает, что подписка публична). Реальный работающий канал — SSH (curl 127.0.0.1:8080 на сервере). Теперь fallback-JSON отдаёт subscription_url пустым; deployer не пробует публичный fetch (не может — http недоступен из сети пользователя) и берёт ключи только по SSH; inspector для http_tls тоже не сохраняет мёртвый URL. Безопасность не меняется: публичных каналов и раньше не открывалось.
…е протоколы» Легаси-подпись серверной карточки: «в разработке» убрать, «запасной» заменить на «дополнительные»; статус разработки перенесён в отдельную строку-подсказку внизу секции бэкендов. Доки ru/en/zh синхронизированы.
… URL нет Остались фразы от промежуточной версии фолбэка («порт 8080 наружу», «URL — bearer-ссылка, не публикуйте в чатах») — после 3608f87 публичного URL подписки в http_tls нет вовсе: ключи GUI тянет по SSH с loopback handler'а, уязвимой HTTP-ссылки не появляется. Синхронизировано configuration.md и troubleshooting.md в ru/en/zh.
…-fallback, GUI-волна
…единый вид заголовков)
Кнопка «Обновить Xrayebator» стала меню из трёх вариантов: закреплённая ветка (.current_branch, прежнее поведение), main (стабильный релиз), dev (бета — свежий менеджер до вливания в main, main не засоряется до финального тестирования). Цепочка: server:update (branch?) -> ServerManager.update(branch) -> xrayebator update <branch> (ветка валидируется isAllowedUpdateBranch, .current_branch переписывается на dev — возврат = обновление на main). Причина: релиз 0.6.5 в бете; раньше сервер можно было перевести на dev только вручную по SSH (sudo xrayebator update dev).
Пункты меню «Обновить Xrayebator» названы по-человечески, а не техническими именами веток: «Авто — как закреплено на сервере», «main — последняя стабильная версия», «dev — все фишки сразу (может быть нестабильной)». i18n ru/en/zh; доки desktop-gui.md ×3 синхронизированы. Фича обновления с явной веткой (f76005e) сохранена; техноминование (dev · бета) убрано.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.