Files
dotfiles/proxy-client/README.md
T
ddadmin f679515a8f feat(proxy-client): добавлен самостоятельный установщик
- Зачем:
  - пакет должен устанавливаться отдельно от dotfiles без ручной раскладки и опасных замен.
- Что:
  - добавлен безопасный установщик со Stow и прямыми симлинками.
  - добавлены идемпотентная настройка Bash и защита машинных файлов.
  - обновлены инструкция и полный набор интеграционных проверок.
- Проверка:
  - env XDG_STATE_HOME=<временный каталог> bash tests/test_proxy_client_full.sh.
2026-07-21 22:22:04 +03:00

337 lines
16 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
`proxy-client` — переносимый Linux/Bash-интерфейс для запуска команд через
внешний прокси или через управляемый пользовательский Xray. Он добавляет команды
`proxy_on`, `proxy_off`, `pclaude` и `pcodex`, но не подменяет обычные `claude`
и `codex`.
CLI требует Python 3.8+ и использует только стандартную библиотеку. Он не
запускает Xray и не переключает режим прокси без явной команды пользователя.
## Установка
### В составе dotfiles
Полная установка подключает пакет и автоматически загружает Bash-функции в
новых интерактивных сессиях:
```bash
cd ~/dotfiles
./install.sh
```
Установщик заранее создаёт `~/.local/bin` и `~/.config/proxy-client`, чтобы Stow
размещал ссылки внутри них, а не превращал сами каталоги в ссылки на
репозиторий.
После установки откройте новый Bash или выполните:
```bash
source ~/.bash_custom
```
### Только пакет `proxy-client`
Каталог можно скопировать отдельно от остальных dotfiles и запустить его
собственный установщик из любого рабочего каталога:
```bash
~/src/proxy-client/install.sh
```
При наличии Stow установщик использует его, иначе создаёт те же три симлинка
напрямую: CLI, Bash-модуль и каталог шаблонов. Исходный каталог после установки
нельзя перемещать: домашние ссылки зависят от его постоянного пути.
По умолчанию установщик добавляет в `~/.bashrc` помеченный блок для
`~/.local/bin` и Bash-модуля. Чтобы оставить настройки оболочки без изменений:
```bash
~/src/proxy-client/install.sh --no-shell-setup
```
Установщик не создаёт машинный `config` и закрытый `default.url`, не
устанавливает Xray и не проверяет сеть. После установки примените изменения
через `source ~/.bashrc`; с `--no-shell-setup` подключите модуль напрямую:
`source ~/.config/proxy-client/shell.bash`. Затем выберите режим по разделу
[«Настройка режима»](#настройка-режима). Без машинного конфига продолжает
действовать режим Hiddify по умолчанию.
## Как выбирается прокси
Режим определяется только машинным файлом
`~/.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 или другой прокси нет.
Текущий выбор и доступность проверяет команда:
```bash
proxy-client status
```
## Настройка режима
### Hiddify в Windows, команды в WSL
Это режим по умолчанию. Если Hiddify доступен из WSL как
`hproxy.local:12334`, создавать `config` не нужно:
```bash
getent hosts hproxy.local
proxy-client status
pclaude --version
```
В WSL NAT mode IP Windows-шлюза меняется при перезапуске. Интерактивный
`./install.sh` предлагает добавить обновление `hproxy.local` в `/etc/wsl.conf`.
То же можно настроить вручную:
```ini
[boot]
command = "/path/to/dotfiles/scripts/setup-hproxy.sh"
```
После изменения выполните `wsl --shutdown` из Windows. Обновить адрес без
перезапуска WSL можно так:
```bash
sudo ~/dotfiles/scripts/setup-hproxy.sh
# или после загрузки Bash-функций:
update_hproxy
```
В NAT mode Hiddify должен слушать адрес, доступный через Windows-шлюз, а не
только `127.0.0.1`.
В [WSL mirrored mode](https://learn.microsoft.com/windows/wsl/networking#mirrored-mode-networking)
(`networkingMode=mirrored`) Windows-сервисы доступны из WSL через `127.0.0.1`.
Чтобы сохранить адрес по умолчанию, добавьте алиас в Windows hosts:
```text
# 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`.
### Другой внешний прокси
Скопируйте пример и измените адрес, порт и локальные исключения:
```bash
cp ~/.config/proxy-client/examples/config.external \
~/.config/proxy-client/config
```
```ini
[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
Создайте машинный конфиг:
```bash
cp ~/.config/proxy-client/examples/config.xray \
~/.config/proxy-client/config
```
Закрытый профиль должен содержать ровно одну VLESS-ссылку:
```bash
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:
```bash
proxy-client install
```
Запустите Xray в отдельной панели tmux:
```bash
proxy-client start
```
Другой закрытый профиль можно выбрать без замены `default.url`:
```bash
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
```bash
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`.
## Диагностика
Начните с проверки выбранного режима:
```bash
proxy-client status
```
Для внешнего Hiddify в WSL проверьте имя и порт:
```bash
getent hosts hproxy.local
curl --proxy http://hproxy.local:12334 https://example.com
curl --proxy socks5h://hproxy.local:12334 https://example.com
```
Для запущенного Xray можно дополнительно проверить созданный JSON:
```bash
xray run -test -c \
"${XDG_STATE_HOME:-$HOME/.local/state}/proxy-client/client.json"
```
Если выбран `type = xray`, но процесс не запущен, запустите его отдельно —
`proxy_on` и `run` этого не делают. Профиль XHTTP с ALPN `h3` требует доступного
UDP-маршрута до сервера; автоматического перехода на H2 нет.
Таймаут предварительной проверки по умолчанию равен двум секундам. Его можно
изменить положительным числом:
```bash
export PROXY_PREFLIGHT_TIMEOUT=5
```
## Справочник
### Ручное подключение без установщика
Если пакетный установщик запустить нельзя, создайте те же ссылки вручную:
```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](https://github.com/XTLS/Xray-core/releases/tag/v25.12.8); опция
удалена в [26.2.6](https://github.com/XTLS/Xray-core/releases/tag/v26.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 показывается как предупреждение и
не останавливает уже готовый процесс.