Files
dotfiles/.scratch/headless-xray-proxy/issues/01-external-proxy-and-portable-shell.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

6.2 KiB

01 — Внешний прокси и переносимый Bash-интерфейс

What to build: Самостоятельный пользовательский пакет прокси, через который можно безопасно запускать команды с уже работающим внешним прокси, например Hiddify. Привычные Bash-команды переходят на единый CLI-контракт, но прежний сценарий без машинного конфига продолжает работать.

Blocked by: None — can start immediately.

Status: done

  • CLI работает на Python 3.8+ без сторонних библиотек, ничего не устанавливает и не запускает без явной подкоманды и выдаёт понятную ошибку на более старом Python.

  • Машинный INI явно различает типы external и xray, проверяет имя, адрес, порт и добавку к NO_PROXY; отсутствие файла сохраняет внешний прокси hproxy.local:12334 без неявного переключения на другой тип.

  • Канонический машинный INI содержит единственную секцию [proxy] и ровно по одному ключу type, name, address, port, no_proxy_extra:

    [proxy]
    type = external
    name = Hiddify
    address = hproxy.local
    port = 12334
    no_proxy_extra = .example.internal,git.example.internal
    

    Все ключи обязательны при наличии файла; no_proxy_extra может быть пустым. Неизвестные секции и ключи, повторы, пропуски, многострочные или содержащие NUL значения, пустые имя или адрес и порт вне диапазона 1–65535 отклоняются. Добавки к NO_PROXY задаются через запятую, окружающие пробелы удаляются, пустые элементы отклоняются.

  • address принимает IPv4, IPv6 без квадратных скобок либо ASCII DNS-имя из корректных непустых меток; схема URL, встроенный порт, скобки, zone ID, пробелы, /, @ и другие URL-разделители отклоняются. При формировании proxy-URL CLI сам заключает IPv6-литерал в квадратные скобки.

  • Для типа external команды status, env и run -- COMMAND ARG... проверяют только настроенный адрес и порт; недоступный прокси запрещает запуск дочерней команды с понятным сообщением.

  • До реализации управляемого процесса конфиг с type=xray обрабатывается безопасным отказом: status, env, run и start не считают один открытый порт доказательством управляемого Xray и не запускают дочернюю команду.

  • env при успехе печатает только восемь разрешённых proxy-переменных в двух регистрах, а при ошибке не печатает частичный результат; базовый NO_PROXY включает loopback и узел прокси, затем дополняется машинной настройкой.

  • Документированный PROXY_PREFLIGHT_TIMEOUT сохраняется как положительное число секунд с прежним значением по умолчанию 2 для проверок доступности из status, env и run; ошибочное значение даёт понятный отказ.

  • run без искажений сохраняет аргументы и код возврата команды, передаёт proxy-переменные только дочернему процессу и возвращает отдельную понятную ошибку, если команда отсутствует в PATH.

  • Переносимый Bash-модуль становится единственным владельцем proxy_on, proxy_off, pclaude, pcodex, myip и внутренних proxy-помощников; WSL-функция обновления hproxy.local остаётся независимой.

  • Обычный запуск dotfiles подключает общий Bash-файл и переносимый proxy-модуль независимо: после установки доступны все пять proxy-команд и update_hproxy; подключение одного переносимого модуля без остальных dotfiles также предоставляет все пять proxy-команд.

  • Bash-модуль принимает вывод env атомарно, проверяет белый список и наличие каждого из восьми ключей ровно один раз, не использует eval и при любом неверном выводе оставляет прежние восемь переменных без изменений; proxy_on и proxy_off больше не делают автоматический запрос внешнего IP.

  • Автоматические тесты подтверждают прежний внешний Hiddify-сценарий, fail-fast, оба регистра переменных, настраиваемый NO_PROXY, отсутствие протечки окружения, обычное и самостоятельное подключение Bash-модуля, безопасный отказ для type=xray и атомарный разбор полного вывода env.