feat(xray-proxy): добавлен управляемый прокси для CLI

Зачем:
- отделить переносимый прокси-интерфейс от общих Bash-функций
- запускать агентские CLI через явный внешний или управляемый прокси

Что:
- добавлен stow-пакет xray-proxy с CLI, Bash-модулем и примерами
- реализованы строгий разбор VLESS и управляемый запуск Xray
- добавлены проверки процесса, порта, сигналов и отсутствия утечек
- сохранены спецификация и очередь следующих тикетов

Проверка:
- python3 tests/test_xray_proxy.py — 22/22
- python3 tests/test_xray_proxy_managed.py — 16/16
- bash tests/test_proxy_launchers.sh — 9/9
- bash tests/test_install.sh
- bash -n, Python 3.8 grammar, git diff --check
This commit is contained in:
ddadmin committed 2026-07-20 00:00:59 +03:00
1 parent fdf744e578
commit e69a4bb7df
20 files changed
+3224 -170

No files matched your search

+147
View File
@@ -0,0 +1,147 @@
# xray-proxy
Переносимый Linux/Bash-интерфейс для безопасного запуска команд через явно
настроенный внешний прокси или через управляемый пользовательский Xray.
CLI требует Python 3.8+ и использует только стандартную библиотеку. Он ничего не
устанавливает и не запускает без явной подкоманды. `start` использует первый
`xray` из `PATH`; скачивания и установки при запуске нет.
## Подключение
В составе dotfiles:
```bash
cd ~/dotfiles
stow xray-proxy
source ~/.config/xray-proxy/shell.bash
```
Полный `./install.sh` выполняет тот же `stow` вместе с остальными пакетами, а
`.bash_custom` подключает модуль автоматически.
Без остальных dotfiles можно создать две ссылки:
```bash
mkdir -p ~/.local/bin ~/.config/xray-proxy
ln -s /path/to/xray-proxy/.local/bin/xray-proxy ~/.local/bin/xray-proxy
ln -s /path/to/xray-proxy/.config/xray-proxy/shell.bash \
~/.config/xray-proxy/shell.bash
printf '%s\n' 'source ~/.config/xray-proxy/shell.bash' >> ~/.bashrc
```
Вместо ссылок файлы можно скопировать в те же пути. Исполняемому файлу нужен
режим `chmod 755`. Каталог `~/.local/bin` должен входить в `PATH`.
## Машинный конфиг
Скопируйте пример и отредактируйте его:
```bash
mkdir -p ~/.config/proxy
cp ~/.config/xray-proxy/examples/config ~/.config/proxy/config
```
Формат строгий: одна секция `[proxy]`, пять обязательных ключей без повторов и
неизвестных полей.
```ini
[proxy]
type = external
name = Hiddify
address = hproxy.local
port = 12334
no_proxy_extra = .example.internal,git.example.internal
```
`address` — IPv4, IPv6 без квадратных скобок или ASCII DNS-имя без схемы и
порта. `no_proxy_extra` — список через запятую; значение может быть пустым.
Поддержка CIDR в `NO_PROXY` различается между программами, поэтому надёжнее
указывать точные IP и домены.
Если файла нет, используется прежний внешний Hiddify на
`hproxy.local:12334`, включая `.concept-software.ru` в `NO_PROXY`. Это не
переключает тип прокси автоматически.
Для управляемого Xray задайте явный тип, loopback IP и нужный локальный порт:
```ini
[proxy]
type = xray
name = Local Xray
address = 127.0.0.1
port = 12334
no_proxy_extra = .example.internal,git.example.internal
```
Секретный профиль хранится отдельно. Скопируйте синтетический пример, замените
его одной настоящей VLESS-ссылкой и закройте права конечного файла:
```bash
cp ~/.config/xray-proxy/examples/default.url ~/.config/xray-proxy/default.url
chmod 600 ~/.config/xray-proxy/default.url
```
Файл должен содержать ровно одну непустую строку. Можно передать другой файл
через `xray-proxy start -f /path/to/profile.url`. Если это симлинк, проверяются
права конечного файла.
## Команды
```bash
xray-proxy status
xray-proxy start [-f PROFILE]
xray-proxy stop
xray-proxy env
xray-proxy run -- COMMAND ARG...
proxy_on
proxy_off
pclaude [ARG...]
pcodex [ARG...]
myip
```
Для `external` команды `status`, `env` и `run` проверяют настроенный адрес и
порт. Для `xray` они дополнительно требуют закрытое состояние именно того
супервизора и дочернего Xray, который запустил CLI. Один открытый порт или чужой
PID не принимается. `run` никогда не запускает Xray скрыто.
`start` поддерживает Xray `25.12.8` и `26.3.27`, сначала выполняет
`xray version` и `xray run -test`, затем остаётся на переднем плане. Используйте
отдельную панель tmux. После готовности один loopback-порт принимает HTTP и
SOCKS. `stop` ограниченно ждёт завершения супервизора и Xray, очищает служебные
файлы и возвращает исходный `start` в терминал. Команда `stop` работает и после
явного переключения машинного типа на `external`.
`run` передаёт восемь proxy-переменных только дочернему процессу и сохраняет
аргументы и код возврата. `proxy_on` атомарно применяет те же восемь переменных
к текущей Bash-сессии; `proxy_off` удаляет их.
Таймаут проверки задаётся положительным числом секунд:
```bash
export PROXY_PREFLIGHT_TIMEOUT=2
```
Значение по умолчанию — 2 секунды. `env` при успехе печатает только восемь строк
`KEY=value`; для обычной диагностики используйте `status` или `myip`.
## Поддерживаемые профили
Поддерживаются только 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 25.12.8 предназначен
только для явной старой совместимости: согласованное `true` переносится как
`allowInsecure=true` с предупреждением об отключённой проверке сертификата;
`pcs` и `vcn` для этой версии запрещены. Автоматического перехода между
версиями или типами прокси нет.
Сводка скрывает UUID и ключи. Содержимое XHTTP `path` не показывается — только
его длина. Сгенерированный JSON и состояние лежат в закрытом каталоге
`$XDG_STATE_HOME/xray-proxy` либо `~/.local/state/xray-proxy` и удаляются после
штатной остановки. Сбой диагностики внешнего IP через локальный HTTP-прокси
показывается как предупреждение и не останавливает уже готовый Xray.