Files
dotfiles/.scratch/headless-xray-proxy/issues/02-managed-xray-happy-path.md
T
ddadmin e69a4bb7df feat(xray-proxy): добавлен управляемый прокси для CLI
Зачем:
- отделить переносимый прокси-интерфейс от общих Bash-функций
- запускать агентские CLI через явный внешний или управляемый прокси

Что:
- добавлен stow-пакет xray-proxy с CLI, Bash-модулем и примерами
- реализованы строгий разбор VLESS и управляемый запуск Xray
- добавлены проверки процесса, порта, сигналов и отсутствия утечек
- сохранены спецификация и очередь следующих тикетов

Проверка:
- python3 tests/test_xray_proxy.py — 22/22
- python3 tests/test_xray_proxy_managed.py — 16/16
- bash tests/test_proxy_launchers.sh — 9/9
- bash tests/test_install.sh
- bash -n, Python 3.8 grammar, git diff --check
2026-07-20 00:00:59 +03:00

73 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 02 — Управляемый Xray: полный штатный путь
**What to build:** Пользователь с уже установленным поддерживаемым Xray кладёт
одну VLESS-ссылку в закрытый файл и получает полный штатный сценарий локального
прокси: проверку профиля, запуск на переднем плане, диагностику, запуск команд
через прокси и штатную остановку.
**Blocked by:** 01 — Внешний прокси и переносимый Bash-интерфейс.
**Status:** done
- [x] `start` разрешён только при явном типе `xray`, требует loopback-адрес и
согласованный локальный порт, никогда не скачивает бинарник и выбирает первый
`xray` из `PATH`. Один разрешённый путь используется для `version`,
`run -test` и основного процесса и показывается перед запуском.
- [x] Успешный `xray version` разбирается только по первой строке в форме
`Xray VERSION` с концом строки либо ASCII-пробелом после полного токена
версии. Принимаются только `25.12.8` и `26.3.27`; ведущий мусор, похожий
префикс вроде `26.3.270`, пустой, неверный или завершившийся ошибкой вывод
запрещает преобразование и запуск. Запрошенная или указанная в профиле версия
не подменяет фактическую версию выбранного бинарника.
- [x] Профиль берётся из предусмотренного файла по умолчанию либо из явно
переданного `-f`, содержит ровно одну VLESS-ссылку, а конечный файл после
разрешения симлинка недоступен группе и остальным пользователям.
- [x] Строгий преобразователь поддерживает TCP/RAW с REALITY и XHTTP с TLS,
сохраняет все предусмотренные спецификацией поля, отклоняет повторы,
любой неизвестный query-параметр, отсутствующие обязательные поля и
неподдерживаемые сочетания до запуска Xray.
- [x] Для Xray 26.3.27 корректно обрабатываются `pcs`/`vcn`, а устаревшие
`allowInsecure`/`insecure` не переносятся и дают предупреждение; для явно
выбранного Xray 25.12.8 сохраняется совместимое insecure-поведение, а новые
поля отклоняются без автоматического отката версии.
- [x] `allowInsecure` и `insecure` принимают только точные значения `true` или
`false`; при одновременном присутствии значения должны совпадать. Для
25.12.8 только согласованное истинное значение включает `allowInsecure` с
предупреждением, а для 26.3.27 поле никогда не попадает в JSON и истинное
значение предупреждает об обычной проверке сертификата.
- [x] Созданный клиентский JSON слушает только loopback, предоставляет HTTP и
SOCKS на одном порту, отключает журнал доступа и проходит `xray run -test`
до запуска основного процесса.
- [x] `start` остаётся на переднем плане как супервизор одного дочернего Xray;
после запуска процесс жив и порт принимает соединения, а сбой отдельной
проверки внешнего IP остаётся предупреждением.
- [x] Штатный `start` создаёт закрытое состояние с PID супервизора и дочернего
Xray, разрешённым путём к бинарнику, портом и безопасным отпечатком профиля.
`status`, `env`, `run` и `stop` требуют это состояние, живой супервизор,
ожидаемый дочерний процесс и настроенный порт; один чужой listener или PID
никогда не считается управляемым Xray и не затрагивается.
- [x] `status`, `env`, `run` и `stop` обеспечивают штатный путь управляемого
Xray; `run` никогда не запускает его скрыто, а `stop` может завершить
управляемый процесс после переключения машинного типа на `external`.
Успешный `stop` посылает сигнал супервизору, ограниченно ждёт завершения
супервизора и Xray, очищает штатное состояние и возвращает исходный
foreground-вызов `start` в терминал.
- [x] Диагностика внешнего IP действительно делает запрос через настроенный
локальный HTTP-прокси. Её сбой явно показан как предупреждение и не отменяет
уже успешные проверки процесса и порта.
- [x] Безопасная сводка показывает только полезные несекретные свойства
профиля; XHTTP `path` показывается только как скрытое значение с длиной, а
UUID, ключи, short ID и другие секреты — без фрагментов исходного значения.
Полная VLESS-ссылка и уникальные секреты отсутствуют в stdout, stderr и argv
дочерних процессов при успехе, любом отказе разбора и сбое `run -test`.
- [x] Модульные и интеграционные тесты покрывают обе семьи ссылок, варианты
ALPN, типичную ссылку Hiddify XHTTP/TLS, обе поддержанные версии Xray и
понятные отказы на неподдерживаемом вводе.
- [x] Чёрный ящик для каждой поддержанной версии доказывает полный порядок:
профиль по умолчанию и `-f`, `version`, успешный `run -test` до основного
запуска, живое управляемое состояние и порт, `status`, `env`, дочернюю
команду через `run`, проксированную IP-диагностику, `stop` и ограниченное
завершение исходного `start`. Через один настроенный локальный порт реально
завершаются отдельный HTTP-proxy-запрос и отдельный SOCKS-proxy-запрос.
Подмена порта или состояния чужим процессом даёт безопасный отказ.