Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
7.7 KiB
Упрощение 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 и
pathXHTTP в stdout/stderr. client.jsonиstate.json— права 600 в каталоге 700 (в них секреты).- Один управляемый Xray за раз: блокировка
flockна времяstart. - Остановка: Ctrl+C или
stopгасят Xray и удаляют служебные файлы; если супервизор убит (SIGKILL),stopдобивает оставшийся Xray и чистит файлы. - Python 3.8+ (у друзей старые дистрибутивы), только стандартная библиотека.
Что упрощаем
- Проверка «тот ли процесс». Вместо boot_id + starttime +
/proc/PID/exe- разрешения argv супервизора относительно его cwd: Xray — PID жив и
/proc/PID/exeсовпадает сxray_path; супервизор — PID жив (и, если дёшево, его cmdline упоминаетproxy-client). Непохожий процесс считаем мёртвым: сигнал не шлём, файлы считаем устаревшими и чистим. Состояние «не удалось подтвердить, удалите файлы вручную» исчезает. Двойная проверка под блокировкой при чистке устаревших файлов не нужна. state.json читаем без строгой схемы: битый файл — понятная ошибка с путём.
- разрешения argv супервизора относительно его cwd: Xray — PID жив и
- Скачивание Xray. Убрать три уровня ограничений размера, сверку
Content-Length, строгую грамматику
.dgst. Достаточно: скачать, найти в.dgstстрокуSHA2-256=, сравнить без учёта регистра. УбратьO_EXCL/0600 для кандидата внутри закрытого временного каталога и требование «каталог установки внутри $HOME». installи работающий Xray. Замена бинарника под работающим процессом на Linux безопасна: не блокироватьinstall, а напомнить перезапуститьstart. Блокировку start на время install не брать.- Разбор ссылки.
extra— обычныйjson.loads+ проверка, что это объект (без своих проверок повторных ключей и NaN:xray run -testпроверит).allowInsecure/insecure— принимаются с любым значением и игнорируются; при истинном значении (1,true) — предупреждение. - Установщик пакета
proxy-client/install.sh. Один способ — прямые симлинки (без Stow). Не перезаписывать чужие файлы и сообщить обо всех конфликтах сразу. Разрешить~/.localи~/.config, которые сами являются ссылками. Блок в~/.bashrc— дописать, если нет маркера; без разбора «повреждённых» блоков, поиска.bash_customи точного текстаexport PATH. - Подсказки об ошибках с файлами называют файл полным путём и дают готовую команду. Пример: «файл профиля /home/u/.config/proxy-client/default.url доступен другим пользователям; выполните: chmod 600 /home/u/...». Если профиль — симлинк, называть конечный файл (права ставятся на него).
Где живут тесты (согласовано с владельцем)
- Команда
proxy-client: argv → код выхода, вывод, созданные файлы, запущенные и остановленные процессы. - Разбор ссылки:
parse_vless+build_xray_config(ссылка → JSON Xray) — быстрые табличные тесты без запуска процессов. - Установка Xray:
command_installс подставляемым скачивателем. - Функции Bash: через поддельный исполняемый файл в
PROXY_CLIENT_BIN. - Установщик пакета: через временный HOME.
Больше нигде. Запрещено: подмена внутренних функций через __globals__ /
mock.patch.dict, проверки порядка внутренних вызовов, тесты тестовых
подделок, по нескольку полных циклов start/stop ради одного утверждения.
Задачи
issues/01-cli.md— CLI и Python-тесты.issues/02-installer-shell.md— установщик пакета, shell-тесты, запускалка.