docs(scratch): план упрощения proxy-client
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
205e995f26
commit
fb23b031bc
3 files changed
+210
No files matched your search
@@ -0,0 +1,88 @@
|
||||
# Упрощение 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-тесты, запускалка.
|
||||
Reference in new issue
Block a user