Files
dotfiles/.scratch/proxy-client-simplify/spec.md
T
2026-09-28 09:21:39 -04:00

89 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.
# Упрощение 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-тесты, запускалка.