Files
dotfiles/proxy-client
ddadmin 9c2e134fc1 fix(install): предотвращено сворачивание каталога .local
- Зачем:
  - свежая установка могла превратить ~/.local в ссылку на пакет и записать Xray в репозиторий.
- Что:
  - перед Stow теперь гарантируются настоящие ~/.local/bin и ~/.config/proxy-client без раскрытия посторонних ссылок.
  - добавлены регрессионные проверки свежего HOME и посторонней ссылки ~/.local.
  - README перестроены вокруг установки, выбора режима и ежедневного использования.
- Проверка:
  - bash tests/test_install.sh.
  - bash tests/test_proxy_launchers.sh.
  - bash -n install.sh tests/test_install.sh.
  - git diff --cached --check.
2026-07-21 11:15:27 -04:00
..

proxy-client

proxy-client — переносимый Linux/Bash-интерфейс для запуска команд через внешний прокси или через управляемый пользовательский Xray. Он добавляет команды proxy_on, proxy_off, pclaude и pcodex, но не подменяет обычные claude и codex.

CLI требует Python 3.8+ и использует только стандартную библиотеку. Он не запускает Xray и не переключает режим прокси без явной команды пользователя.

Установка

В составе dotfiles

Полная установка подключает пакет и автоматически загружает Bash-функции в новых интерактивных сессиях:

cd ~/dotfiles
./install.sh

Установщик заранее создаёт ~/.local/bin и ~/.config/proxy-client, чтобы Stow размещал ссылки внутри них, а не превращал сами каталоги в ссылки на репозиторий.

После установки откройте новый Bash или выполните:

source ~/.bash_custom

Только пакет proxy-client

cd ~/dotfiles
mkdir -p ~/.local/bin ~/.config/proxy-client
stow proxy-client
source ~/.config/proxy-client/shell.bash

Если Bash-пакет dotfiles не установлен, добавьте подключение модуля в ~/.bashrc:

printf '%s\n' 'source ~/.config/proxy-client/shell.bash' >> ~/.bashrc

Как выбирается прокси

Режим определяется только машинным файлом ~/.config/proxy-client/config:

Машинный конфиг Используется Что запускать
Файла нет Hiddify на hproxy.local:12334 Ничего
type = external Указанный внешний прокси Ничего
type = xray Управляемый локальный Xray proxy-client start

Доступность процесса не меняет выбранный режим. Если в конфиге указан Xray, но он не запущен, status, env, run, proxy_on, pclaude и pcodex завершатся с ошибкой. Автоматического перехода на Hiddify или другой прокси нет.

Текущий выбор и доступность проверяет команда:

proxy-client status

Настройка режима

Hiddify в Windows, команды в WSL

Это режим по умолчанию. Если Hiddify доступен из WSL как hproxy.local:12334, создавать config не нужно:

getent hosts hproxy.local
proxy-client status
pclaude --version

В WSL NAT mode IP Windows-шлюза меняется при перезапуске. Интерактивный ./install.sh предлагает добавить обновление hproxy.local в /etc/wsl.conf. То же можно настроить вручную:

[boot]
command = "/path/to/dotfiles/scripts/setup-hproxy.sh"

После изменения выполните wsl --shutdown из Windows. Обновить адрес без перезапуска WSL можно так:

sudo ~/dotfiles/scripts/setup-hproxy.sh
# или после загрузки Bash-функций:
update_hproxy

В NAT mode Hiddify должен слушать адрес, доступный через Windows-шлюз, а не только 127.0.0.1.

В WSL mirrored mode (networkingMode=mirrored) Windows-сервисы доступны из WSL через 127.0.0.1. Чтобы сохранить адрес по умолчанию, добавьте алиас в Windows hosts:

# C:\Windows\System32\drivers\etc\hosts
127.0.0.1  hproxy.local

Альтернатива — создать config.external с address = 127.0.0.1. В обоих случаях проверьте результат через getent hosts hproxy.local или proxy-client status.

Другой внешний прокси

Скопируйте пример и измените адрес, порт и локальные исключения:

cp ~/.config/proxy-client/examples/config.external \
  ~/.config/proxy-client/config
[proxy]
type = external
name = Office proxy
address = proxy.example.internal
port = 12334
no_proxy_extra = .example.internal,git.example.internal

Для внешнего прокси на той же Linux-машине можно указать 127.0.0.1 напрямую.

Локальный Xray

Создайте машинный конфиг:

cp ~/.config/proxy-client/examples/config.xray \
  ~/.config/proxy-client/config

Закрытый профиль должен содержать ровно одну VLESS-ссылку:

cp ~/.config/proxy-client/examples/default.url \
  ~/.config/proxy-client/default.url
$EDITOR ~/.config/proxy-client/default.url
chmod 600 ~/.config/proxy-client/default.url

Установите проверенную версию Xray без root:

proxy-client install

Запустите Xray в отдельной панели tmux:

proxy-client start

Другой закрытый профиль можно выбрать без замены default.url:

proxy-client start -f ~/.config/proxy-client/work.url

Для переключения профиля сначала выполните proxy-client stop. Все файлы с настоящими VLESS-ссылками должны иметь права 600 и не должны попадать в Git.

Ежедневное использование

Задача Команда Область действия
Запустить Claude через прокси pclaude [ARG...] Только дочерний процесс
Запустить Codex через прокси pcodex [ARG...] Только дочерний процесс
Запустить другую команду proxy-client run -- COMMAND ARG... Только дочерний процесс
Включить прокси proxy_on Текущая Bash-сессия
Выключить прокси proxy_off Текущая Bash-сессия
Проверить прокси proxy-client status Без изменения окружения
Получить proxy-переменные proxy-client env Машинный вывод в stdout
Показать внешний IP myip С учётом текущего окружения

run, pclaude и pcodex передают дочернему процессу восемь вариантов HTTP_PROXY, HTTPS_PROXY, ALL_PROXY и NO_PROXY, включая имена в нижнем регистре. После завершения команды переменные не остаются в оболочке.

proxy_on применяет те же переменные к текущей Bash-сессии только после успешной проверки прокси. proxy_off удаляет их. Обычные claude и codex не обёрнуты и не выполняют предварительную проверку, но после proxy_on наследуют прокси-переменные, как и любой другой дочерний процесс.

Жизненный цикл Xray

proxy-client install [--replace]
proxy-client start [-f PROFILE]
proxy-client status
proxy-client stop

start сначала проверяет версию и конфигурацию Xray, затем остаётся на переднем плане. Systemd, фоновый автозапуск и скрытый запуск из run не используются. Один loopback-порт принимает HTTP CONNECT и SOCKS5.

stop завершает управляемые процессы и удаляет созданные служебные файлы. Он работает и после изменения машинного типа на external.

Диагностика

Начните с проверки выбранного режима:

proxy-client status

Для внешнего Hiddify в WSL проверьте имя и порт:

getent hosts hproxy.local
curl --proxy http://hproxy.local:12334 https://example.com
curl --proxy socks5h://hproxy.local:12334 https://example.com

Для запущенного Xray можно дополнительно проверить созданный JSON:

xray run -test -c \
  "${XDG_STATE_HOME:-$HOME/.local/state}/proxy-client/client.json"

Если выбран type = xray, но процесс не запущен, запустите его отдельно — proxy_on и run этого не делают. Профиль XHTTP с ALPN h3 требует доступного UDP-маршрута до сервера; автоматического перехода на H2 нет.

Таймаут предварительной проверки по умолчанию равен двум секундам. Его можно изменить положительным числом:

export PROXY_PREFLIGHT_TIMEOUT=5

Справочник

Ручное подключение без Stow

Можно создать ссылки на CLI, Bash-модуль и примеры либо скопировать те же файлы:

mkdir -p ~/.local/bin ~/.config/proxy-client
ln -s /path/to/proxy-client/.local/bin/proxy-client ~/.local/bin/proxy-client
ln -s /path/to/proxy-client/.config/proxy-client/shell.bash \
  ~/.config/proxy-client/shell.bash
ln -s /path/to/proxy-client/.config/proxy-client/examples \
  ~/.config/proxy-client/examples

Исполняемому файлу нужен режим 755, а ~/.local/bin должен входить в PATH.

Машинный конфиг

Формат строгий: одна секция [proxy] и пять обязательных ключей без повторов и неизвестных полей:

  • type — external или xray;
  • name — имя для диагностики;
  • address — IPv4, IPv6 без квадратных скобок или ASCII DNS-имя без схемы и порта;
  • port — TCP-порт локального входа;
  • no_proxy_extra — дополнительные IP и домены через запятую, значение может быть пустым.

Поддержка CIDR в NO_PROXY различается между программами, поэтому надёжнее указывать точные IP и домены. Без машинного файла внешний режим дополнительно включает .concept-software.ru в NO_PROXY. Для type = xray адрес обязан быть адресом обратной петли, например 127.0.0.1 или ::1.

Поддерживаемые профили

Поддерживаются VLESS TCP/RAW с REALITY и VLESS XHTTP с TLS. Неизвестные, повторные и несовместимые query-параметры отклоняются. XHTTP поддерживает ALPN http/1.1, h2 и h3; extra должен быть JSON-объектом без повторных ключей.

Xray 26.3.27 использует pcs и vcn, а устаревшие allowInsecure и insecure не переносит. Истинное legacy-значение даёт предупреждение, но обычная проверка сертификата остаётся включённой.

Последняя версия Xray, где allowInsecure ещё применяется, — 25.12.8; опция удалена в 26.2.6. proxy-client эти версии не поддерживает и не устанавливает.

Проверяемая установка Xray

proxy-client install устанавливает Xray 26.3.27 в ~/.local/bin/xray. Для x86_64/amd64 используется Xray-linux-64.zip, для aarch64/arm64 — Xray-linux-arm64-v8a.zip; остальные архитектуры отклоняются.

CLI скачивает официальный архив и файл .dgst, проверяет SHA-256, ограничения размера и фактическую версию бинарника, а затем атомарно заменяет назначение. Корректная уже установленная версия даёт no-op без сети. Другой файл или симлинк не заменяется без --replace; каталог не заменяется никогда.

start использует первый xray из PATH и принимает только версию 26.3.27. Если PATH выбирает другой бинарник, команда сообщает об ошибке. Во время живого или неподтверждённого управляемого процесса установка запрещена.

Файлы и безопасность

Путь Назначение
~/.config/proxy-client/config Несекретный машинный выбор режима
~/.config/proxy-client/default.url Закрытая VLESS-ссылка, права 600
~/.config/proxy-client/examples/ Синтетические примеры без секретов
$XDG_STATE_HOME/proxy-client/ или ~/.local/state/proxy-client/ Состояние и сгенерированный JSON

Сводка скрывает UUID и ключи, а для XHTTP показывает только длину path. Служебный каталог закрыт для других пользователей и очищается после штатной остановки Xray. Сбой определения внешнего IP показывается как предупреждение и не останавливает уже готовый процесс.