Добавлены независимые пользовательские профили, их выбор в Bash-командах и явная установка службы systemd. Инструкции размещены в README пакета. Проверка: 67 тестов на Python 3.8 и 3.14, shell-наборы и интеграция Bash с CLI. Загрузка ОС и восстановление настоящей службы требуют отдельной проверки.
proxy-client
proxy-client — переносимый Linux/Bash-интерфейс для запуска команд через
внешний прокси или через управляемый Xray. Он добавляет команды
proxy_on, proxy_off, pclaude и pcodex, но не подменяет обычные claude
и codex.
CLI требует Python 3.8+ и использует только стандартную библиотеку. Он не запускает Xray и не переключает режим прокси без явной команды пользователя.
Установка
Только пакет proxy-client
Скопируйте каталог в постоянное место и запустите пакетный установщик. Текущий рабочий каталог не важен:
~/src/proxy-client/install.sh
Установщик создаёт три ссылки на исходный каталог: CLI, Bash-модуль и каталог шаблонов. Поэтому исходный каталог после установки нельзя перемещать. Если какой-то из путей уже занят чужим файлом или ссылкой, установщик ничего не меняет и перечисляет все такие пути. Повторный запуск безопасен.
По умолчанию установщик дописывает в ~/.bashrc блок между строками
# >>> proxy-client >>> и # <<< proxy-client <<<: он добавляет
~/.local/bin в PATH и подключает Bash-модуль. Если блок уже есть, файл не
меняется. После установки откройте новый Bash или примените блок в текущей
сессии:
source ~/.bashrc
Чтобы оставить ~/.bashrc без изменений, запустите:
~/src/proxy-client/install.sh --no-shell-setup
В этом случае подготовьте только текущую сессию вручную:
export PATH="$HOME/.local/bin:$PATH"
source ~/.config/proxy-client/shell.bash
Для следующих сессий добавьте эти строки в подходящий Bash-конфиг сами.
Установщик не создаёт машинный config и закрытый default.url, не
устанавливает Xray и не проверяет сеть. После подключения команд выберите режим
по разделу «Настройка режима». Без машинного конфига
действует режим Hiddify по умолчанию.
В составе dotfiles
Корневой установщик dotfiles подключает тот же пакет через Stow и загружает Bash-функции в новых интерактивных сессиях:
cd ~/dotfiles
./install.sh
Он заранее создаёт ~/.local/bin и ~/.config/proxy-client, чтобы Stow
размещал ссылки внутри них, а не превращал сами каталоги в ссылки на
репозиторий. После установки откройте новый Bash или выполните:
export PATH="$HOME/.local/bin:$PATH"
source ~/.bash_custom
Если ~/.local/bin отсутствует в PATH и в новых сессиях, добавьте ту же строку
export в свой Bash-конфиг: корневой установщик dotfiles его не изменяет.
Как выбирается прокси
Без выбора профиля режим определяется файлом
~/.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-шлюза меняется при перезапуске WSL, поэтому hproxy.local нужно
обновлять. В отдельно скопированном пакете системных помощников нет. Узнайте
адрес шлюза:
ip route show default | awk 'NR == 1 {print $3}'
Затем откройте /etc/hosts через sudoedit и оставьте одну отдельную строку с
полученным адресом:
sudoedit /etc/hosts
<адрес-шлюза> hproxy.local
Не удаляйте другие имена на той же строке: при необходимости перенесите их на отдельную строку. Повторяйте обновление после перезапуска WSL.
С полным dotfiles запустите корневой ~/dotfiles/install.sh интерактивно: он
предложит автоматическое обновление при старте WSL. Обновить адрес сразу можно
так:
sudo ~/dotfiles/scripts/setup-hproxy.sh
# после настройки автозапуска и загрузки общих Bash-функций:
update_hproxy
В NAT mode Hiddify должен слушать адрес, доступный через Windows-шлюз, а не
только 127.0.0.1.
WSL mirrored mode
В mirrored mode
(networkingMode=mirrored) Windows-сервисы доступны из WSL через 127.0.0.1.
Чтобы сохранить адрес по умолчанию, добавьте алиас в Windows hosts:
# C:\Windows\System32\drivers\etc\hosts
127.0.0.1 hproxy.local
Альтернатива — настройте внешний режим по следующему разделу и укажите
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
Другой файл VLESS-ссылки можно выбрать без замены default.url:
proxy-client start -f ~/.config/proxy-client/work.url
Для смены ссылки работающего экземпляра сначала выполните proxy-client stop.
Все файлы с настоящими VLESS-ссылками должны иметь права 600 и не должны
попадать в Git.
Именованные профили
Профиль объединяет настройки локального входа, исключения и, для Xray,
VLESS-ссылку. Без указания имени используется default: прежние config и
default.url остаются на своих местах. Дополнительные профили живут в
~/.config/proxy-client/profiles/<имя>/. При заданном XDG_CONFIG_HOME
вместо ~/.config используется этот каталог.
Например, создайте профиль work:
mkdir -p ~/.config/proxy-client/profiles/work
cp ~/.config/proxy-client/examples/config.xray ~/.config/proxy-client/profiles/work/config
$EDITOR ~/.config/proxy-client/profiles/work/config
В config задайте свободный порт, например 12335, если основной прокси
занимает 12334. Поместите VLESS-ссылку в profiles/work/default.url и
ограничьте доступ:
chmod 600 ~/.config/proxy-client/profiles/work/default.url
proxy-client --profile work start
Команда остаётся в терминале. В другом терминале можно проверить или остановить именно этот профиль:
proxy-client --profile work status
proxy-client --profile work stop
Параметр --profile ставится перед подкомандой. Неизвестный профиль даёт
ошибку; перехода на default нет. Разные профили могут работать одновременно
на разных портах. Остановка одного не затрагивает остальные.
start -f FILE переопределяет только файл ссылки выбранного профиля на этот
запуск. Его порт и исключения по-прежнему берутся из config.
Ежедневное использование
| Задача | Команда | Область действия |
|---|---|---|
| Запустить 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 наследуют
прокси-переменные, как и любой другой дочерний процесс.
Для именованного профиля:
proxy_on --profile work
pclaude --proxy-profile work
pcodex --proxy-profile work --search
proxy-client --profile work run -- COMMAND ARG...
У pclaude и pcodex параметр --proxy-profile должен быть первым.
Обычный --profile передаётся запускаемой программе.
proxy_on --profile work меняет окружение терминала, но не профиль по
умолчанию: обычный codex наследует это окружение, а pcodex без параметра
выберет default. proxy_off только очищает переменные — работающие прокси,
включая системную службу, остаются запущенными. myip использует текущее
окружение.
Жизненный цикл Xray
proxy-client install [--replace]
proxy-client start [-f PROFILE]
proxy-client status
proxy-client stop
start сначала проверяет версию и конфигурацию Xray, затем остаётся на переднем
плане. Скрытого запуска из run нет; системная служба устанавливается отдельно.
Один loopback-порт принимает HTTP CONNECT и SOCKS5.
Остановить Xray можно двумя способами: Ctrl+C в окне start или
proxy-client stop из любого терминала. Оба гасят Xray и удаляют служебные
файлы. Если процесс start был убит (например, закрыли окно tmux), Xray может
остаться работать: status и env тогда сообщат об ошибке, а stop добьёт его
и уберёт файлы. stop работает и после изменения машинного типа на external.
Второй start того же профиля, пока первый работает, завершится ошибкой.
Системная служба
Этот режим нужен, когда приложения должны получать прокси после загрузки
Linux, до входа пользователя. Требуются systemd, systemd-sysusers и права
администратора для установки. Служба одна; именованные профили остаются
пользовательскими.
Сначала подготовьте и проверьте профиль Xray обычным ручным запуском. Перед запуском службы остановите ручной экземпляр, если он занимает тот же порт. Установите службу, указав каталог настроек и уже установленный Xray:
sudo "$HOME/.local/bin/proxy-client" service install \
--config-dir "$HOME/.config/proxy-client" \
--xray "$HOME/.local/bin/xray" --enable --start
В качестве --config-dir можно указать каталог именованного профиля.
Пути должны быть абсолютными. --enable включает запуск при загрузке,
--start запускает сейчас. Без этих параметров команда только устанавливает
файлы и регистрирует службу.
Установщик копирует настройки в /etc/proxy-client/, а CLI и Xray — в
/usr/local/lib/proxy-client/. Служба больше не зависит от домашнего каталога.
Изменения исходного пользовательского профиля на неё не влияют. Системные
настройки имеют владельца root, группу proxy-client и права 640;
каталог — 750. Процесс работает под отдельным пользователем proxy-client.
Временные файлы находятся в закрытом /run/proxy-client/.
Управление и журнал:
sudo systemctl status proxy-client
sudo systemctl stop proxy-client
sudo systemctl start proxy-client
sudo systemctl restart proxy-client
sudo journalctl -u proxy-client -b
sudo journalctl -u proxy-client -f
Для изменения настроек отредактируйте /etc/proxy-client/config или
/etc/proxy-client/default.url с правами администратора, затем перезапустите
службу. Сохраняйте владельца, группу и права файлов.
После аварии systemd повторяет запуск с паузой в пять секунд. Явная команда
stop оставляет службу остановленной, но не отменяет запуск при следующей
загрузке. Чтобы отключить автозапуск и остановить её сразу:
sudo systemctl disable --now proxy-client
Чтобы включить обратно:
sudo systemctl enable --now proxy-client
При обновлении повторите установку из актуальной копии пакета. Существующие системные настройки сохраняются; исходный домашний профиль уже не нужен:
sudo "$HOME/.local/bin/proxy-client" service install \
--config-dir /etc/proxy-client --xray "$HOME/.local/bin/xray"
sudo systemctl restart proxy-client
Работающий процесс сам не перезапускается. Чужие или вручную изменённые
исполняемые файлы и unit-файл установщик не заменяет; изменения параметров
systemd делайте через sudo systemctl edit proxy-client. Файлы заменяются
по одному атомарно, общего отката всей установки при сбое нет.
Вывод CLI поступает в journald. Сырой вывод Xray в системном режиме подавлен,
чтобы сообщения с фрагментами конфигурации не раскрывали секреты; детальные
сетевые журналы Xray поэтому недоступны. Установщик сообщает настройку хранения
journald, но не меняет её. Сохранение журнала после перезагрузки зависит от
настроек машины; проверить предыдущие загрузки можно через
sudo journalctl --list-boots.
Открытый локальный порт не гарантирует доступность удалённого сервера. На ноутбуке сеть может появиться позже службы. Приложениям без повторения запросов понадобится отдельная настройка ожидания готовности.
Для proxy_on, pclaude, pcodex и run системная служба — внешний прокси:
укажите в нужном пользовательском профиле type = external, адрес
127.0.0.1 и порт службы. Дополнительный профиль типа xray запускайте вручную
на другом порту. Пользовательский stop системной службой не управляет.
Для проверки размещения файлов без установки на машину есть
service install --config-dir DIR --xray FILE --root /absolute/staging.
Этот режим не вызывает systemd, не создаёт системную учётную запись и не
назначает ей владельцев; он несовместим с --enable и --start.
Прокси в настройках Codex и Claude Code
Codex и Claude Code умеют брать proxy-переменные из собственных настроек.
Значения оттуда перекрывают окружение, унаследованное от запускающего
приложения, поэтому маршрут не зависит от того, откуда агент запущен:
терминал, IDE или фоновый демон Codex. С такими настройками pcodex и
pclaude не обязательны.
Установщики эти настройки не трогают. Шаблоны лежат в
~/.config/proxy-client/examples/: прокси 127.0.0.1:12334 и короткий
список исключений. Скопируйте нужный и поправьте под свою машину.
Codex читает ~/.codex/.env:
cp ~/.config/proxy-client/examples/codex.env ~/.codex/.env
codex app-server daemon restart
Запросы к API отправляет общий демон Codex, а он читает .env только при
старте. Перезапуск демона прерывает открытые сессии Codex.
Claude Code берёт переменные из блока env в ~/.claude/settings.json.
Перенесите туда блок из examples/claude-settings.json; остальные ключи
файла не трогайте. Настройки подхватятся при следующем запуске Claude Code.
Claude Desktop этот блок не использует: само приложение ходит в сеть через
Chromium.
Чтобы агент на машине работал без прокси, даже если его запустило
приложение с прокси в окружении, очистите адреса (HTTP_PROXY,
HTTPS_PROXY, ALL_PROXY в обоих регистрах) и задайте NO_PROXY=* и
no_proxy=*.
Диагностика
Начните с проверки выбранного режима:
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
Справочник
Ручное подключение без установщика
Если пакетный установщик запустить нельзя, выберите постоянный абсолютный путь к исходному каталогу и создайте те же ссылки вручную. Команды предполагают, что назначения ещё не заняты:
mkdir -p ~/.local/bin ~/.config/proxy-client
ln -s /absolute/path/to/proxy-client/.local/bin/proxy-client \
~/.local/bin/proxy-client
ln -s /absolute/path/to/proxy-client/.config/proxy-client/shell.bash \
~/.config/proxy-client/shell.bash
ln -s /absolute/path/to/proxy-client/.config/proxy-client/examples \
~/.config/proxy-client/examples
chmod 755 /absolute/path/to/proxy-client/.local/bin/proxy-client
Подготовьте текущую Bash-сессию:
export PATH="$HOME/.local/bin:$PATH"
source ~/.config/proxy-client/shell.bash
Для следующих сессий добавьте эти две строки в свой Bash-конфиг. Исходный каталог после этого нельзя перемещать: созданные ссылки зависят от его пути.
Машинный конфиг
Формат строгий: одна секция [proxy] и пять обязательных ключей без повторов и
неизвестных полей:
type—externalилиxray;name— имя для диагностики;address— IPv4, IPv6 без квадратных скобок или ASCII DNS-имя без схемы и порта;port— TCP-порт локального входа;no_proxy_extra— IP и домены через запятую, значение может быть пустым. Список замещает встроенныйDEFAULT_NO_PROXY_EXTRAцеликом, а не дополняет его: домены, нужные постоянно, придётся перечислить здесь заново.
Поддержка CIDR в NO_PROXY различается между программами, поэтому надёжнее
указывать точные IP и домены. Без машинного файла внешний режим дополнительно
включает .concept-software.ru, dementev.space и .dementev.space в
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 run -test.
Параметры ссылок передаются по спецификации Xray:
| В ссылке | В конфигурации Xray |
|---|---|
ech |
TLS echConfigList |
pqv, spx |
REALITY mldsa65Verify, spiderX |
fm |
streamSettings.finalmask, JSON-объект |
x_padding_bytes, xPaddingBytes |
XHTTP extra.xPaddingBytes |
scMaxEachPostBytes, scMinPostsIntervalMs, uplinkChunkSize |
Одноимённые поля XHTTP внутри extra |
Для XHTTP пустой или отсутствующий host допустим; при отсутствии path
используется /. Имена sessionPlacement и sessionKey в extra, включая
отдельное соединение скачивания, преобразуются в sessionIDPlacement и
sessionIDKey. Если старое и новое имя задают разные значения, профиль
отклоняется. Новые sessionIDTable и sessionIDLength передаются ядру.
Параметры XHTTP с именами как в JSON имеют приоритет над extra, а
extra.xPaddingBytes — над x_padding_bytes.
При отсутствии encryption используется none, sni — адрес сервера,
TLS fp — chrome. Для REALITY fp и pbk обязательны, а flow и sid
могут быть пустыми или отсутствовать; type=raw принимается как type=tcp.
Пустые ech, pqv, spx, pcs, vcn допустимы. SHA-256 в pcs может
содержать двоеточия и пробелы по краям. Метка support-x25519mlkem768=true в REALITY
принимается для совместимости со ссылками 3x-ui и не создаёт поле в JSON Xray.
Кроме encryption=none, принимается VLESS-шифрование
encryption=mlkem768x25519plus.… из новых ссылок Hiddify; остальную часть
значения проверяет сам Xray. Только с таким шифрованием XHTTP допускает
flow=xtls-rprx-vision. Косая черта перед параметрами (…:443/?type=…)
допустима, другой путь в ссылке — нет.
Xray 26.10.10 использует pcs и vcn. Устаревшие allowInsecure и insecure
принимаются с любым значением, но не переносятся: при значении 1 или true
выводится предупреждение, а сертификат проверяется обычным способом.
Последняя версия Xray, где allowInsecure ещё применяется, —
25.12.8; опция
удалена в 26.2.6.
proxy-client эти версии не поддерживает и не устанавливает.
Проверяемая установка Xray
proxy-client install устанавливает Xray 26.10.10 в ~/.local/bin/xray. Для
x86_64/amd64 используется Xray-linux-64.zip, для aarch64/arm64 —
Xray-linux-arm64-v8a.zip; остальные архитектуры отклоняются.
Выпуск 26.10.10 помечен как предварительный. Обновление уже установленного клиента:
proxy-client install --replace
CLI скачивает официальный архив и файл .dgst, сверяет SHA-256 и фактическую
версию бинарника, а затем атомарно заменяет назначение. При любой ошибке старый
файл остаётся на месте. Если нужная версия уже установлена, сеть не нужна и
ничего не меняется. Другой файл или симлинк не заменяется без --replace
(симлинк заменяется сам, файл по ссылке не трогается); каталог не заменяется
никогда. Если после установки PATH находит другой xray, install сообщает об
ошибке и подсказывает команду.
Устанавливать можно и при работающем Xray: он продолжит работу со старым файлом,
а install напомнит перезапустить start.
start использует первый xray из PATH и принимает только версию 26.10.10.
Файлы и безопасность
| Путь | Назначение |
|---|---|
~/.config/proxy-client/config |
Несекретный машинный выбор режима |
~/.config/proxy-client/default.url |
Закрытая VLESS-ссылка, права 600 |
~/.config/proxy-client/examples/ |
Синтетические примеры без секретов, шаблоны для Codex и Claude Code |
$XDG_STATE_HOME/proxy-client/ или ~/.local/state/proxy-client/ |
Состояние и сгенерированный JSON |
Сводка скрывает UUID и ключи, а для XHTTP показывает только длину path.
Если файл профиля доступен другим пользователям, start не запустится и
покажет готовую команду chmod 600 для конечного файла (у симлинка — для файла,
на который он указывает). Служебный каталог закрыт для других пользователей
(700, файлы в нём — 600) и очищается после остановки Xray. Сбой
определения внешнего IP показывается как предупреждение и не останавливает уже
готовый процесс.
Изменение кода
Перед правкой proxy-client прочитайте спецификацию: там сказано, от чего клиент защищается, от чего нет и почему, и где живут тесты.
Все тесты пакета (из корня dotfiles):
tests/test_proxy_client_full.sh