Files
dotfiles/.scratch/proxy-client-simplify/spec.md
T

8.1 KiB
Raw Blame History

Упрощение proxy-client

Status: ready-for-agent

Зачем

proxy-client — личный клиент для владельца и нескольких друзей, а не промышленное ПО. Большая часть кода и тестов — защита от сценариев, которые на личной машине не случаются (повторное использование PID, подложный state.json, zip-бомба в проверенном по SHA-256 официальном архиве, гонка status с параллельным start). Эта защита стоит сотни строк кода и тестов и около минуты прогона. Цель — оставить существенную сложность и убрать случайную.

Принцип: простой код, который честно делает своё дело и понятно сообщает об ошибке. Не защищаемся от самого пользователя и от его собственных файлов.

Что сохраняем (обязательное поведение)

  • Команды и их договор: install [--replace], status, env, run -- CMD, start [-f FILE], stop; коды выхода (2 без подкоманды, 127 — команда не найдена, 128+N — дочерний процесс убит сигналом N); восемь proxy-переменных.
  • Отказ без запасного пути: выбран Xray, но он не запущен — ошибка, а не переход на Hiddify.
  • Машинный INI: строгий формат как сейчас (он маленький и понятный).
  • Разбор VLESS: поддерживаемые TCP/REALITY и XHTTP/TLS, VLESS-шифрование mlkem768x25519plus, неизвестные query-параметры отклоняются.
  • Точная версия Xray 26.3.27 для install и start (сознательное решение).
  • Установка Xray: официальный архив, проверка SHA-256 по .dgst, атомарная замена через временный каталог рядом с назначением; --replace не пишет через симлинк; неудачная установка не портит старый бинарник.
  • start только на loopback-адресе; занятый порт — понятная ошибка.
  • Не выводим UUID, ключи REALITY и path XHTTP в stdout/stderr.
  • client.json и state.json — права 600 в каталоге 700 (в них секреты).
  • Один управляемый Xray за раз: блокировка flock на время start.
  • Остановка: Ctrl+C или stop гасят Xray и удаляют служебные файлы; если супервизор убит (SIGKILL), stop добивает оставшийся Xray и чистит файлы.
  • Python 3.8+ (у друзей старые дистрибутивы), только стандартная библиотека.

Что упрощаем

  1. Проверка «тот ли процесс». Вместо boot_id + starttime + /proc/PID/exe
    • разрешения argv супервизора относительно его cwd: Xray — PID жив и /proc/PID/exe совпадает с xray_path; супервизор — PID жив (и, если дёшево, его cmdline упоминает proxy-client). Непохожий процесс считаем мёртвым: сигнал не шлём, файлы считаем устаревшими и чистим. Состояние «не удалось подтвердить, удалите файлы вручную» исчезает. Двойная проверка под блокировкой при чистке устаревших файлов не нужна. state.json читаем без строгой схемы: битый файл — понятная ошибка с путём.
  2. Скачивание Xray. Убрать три уровня ограничений размера, сверку Content-Length, строгую грамматику .dgst. Достаточно: скачать, найти в .dgst строку SHA2-256=, сравнить без учёта регистра. Убрать O_EXCL/0600 для кандидата внутри закрытого временного каталога и требование «каталог установки внутри $HOME».
  3. install и работающий Xray. Замена бинарника под работающим процессом на Linux безопасна: не блокировать install, а напомнить перезапустить start. Блокировку start на время install не брать.
  4. Разбор ссылки. extra — обычный json.loads + проверка, что это объект (без своих проверок повторных ключей и NaN: xray run -test проверит). allowInsecure/insecure — принимаются с любым значением и игнорируются; при истинном значении (1, true) — предупреждение.
  5. Установщик пакета proxy-client/install.sh. Один способ — прямые симлинки (без Stow). Не перезаписывать чужие файлы и сообщить обо всех конфликтах сразу. Разрешить ~/.local и ~/.config, которые сами являются ссылками. Блок в ~/.bashrc — дописать, если нет маркера; без разбора «повреждённых» блоков, поиска .bash_custom и точного текста export PATH.
  6. Подсказки об ошибках с файлами называют файл полным путём и дают готовую команду. Пример: «файл профиля /home/u/.config/proxy-client/default.url доступен другим пользователям; выполните: chmod 600 /home/u/...». Если профиль — симлинк, называть конечный файл (права ставятся на него).

Где живут тесты (согласовано с владельцем)

  1. Команда proxy-client: argv → код выхода, вывод, созданные файлы, запущенные и остановленные процессы.
  2. Разбор ссылки: parse_vless + build_xray_config (ссылка → JSON Xray) — быстрые табличные тесты без запуска процессов.
  3. Установка Xray: command_install с подставляемым скачивателем.
  4. Функции Bash: через поддельный исполняемый файл в PROXY_CLIENT_BIN.
  5. Установщик пакета: через временный HOME.

Больше нигде. Запрещено: подмена внутренних функций через __globals__ / mock.patch.dict, проверки порядка внутренних вызовов, тесты тестовых подделок, по нескольку полных циклов start/stop ради одного утверждения.

Задачи

  • issues/01-cli.md — CLI и Python-тесты.
  • issues/02-installer-shell.md — установщик пакета, shell-тесты, запускалка.
  • После 01 и 02 (делает оркестратор): привести разделы docs/specs/2026-07-15-proxy-client-design.md про установку, жизненный цикл, доставку, риски и проверку в соответствие с кодом; добавить в proxy-client/README.md ссылку на спецификацию для тех, кто меняет код.