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

-67
View File
@@ -23,70 +23,3 @@ update_hproxy() {
echo "✅ hproxy.local -> $(getent hosts hproxy.local 2>/dev/null | awk '{print $1}')"
}
# Единый источник правды для прокси-эндпоинта (не экспортируется; идемпотентно
# при повторном source). NO_PROXY: ::1 и [::1] нужны, т.к. localhost в dual-stack
# Linux резолвится в IPv6, и без них локальные MCP/loopback-соединения
# (chroma-mcp, claude-mem worker и т.п.) уходят в SOCKS5 через hproxy.local.
: "${_PROXY_HOST:=hproxy.local}"
: "${_PROXY_PORT:=12334}"
: "${_PROXY_NO_PROXY:=hproxy.local,localhost,127.0.0.1,::1,[::1],.concept-software.ru}"
# Внутренний: экспортирует proxy-env (+ lower-case дубли для Python-стека).
# Единственное место, где формируются значения переменных.
_proxy_export() {
export HTTP_PROXY="http://${_PROXY_HOST}:${_PROXY_PORT}"
export HTTPS_PROXY="http://${_PROXY_HOST}:${_PROXY_PORT}"
export ALL_PROXY="socks5://${_PROXY_HOST}:${_PROXY_PORT}"
export NO_PROXY="$_PROXY_NO_PROXY"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export all_proxy="$ALL_PROXY"
export no_proxy="$_PROXY_NO_PROXY"
}
# Внутренний: fail-fast проверка доступности прокси (только reachability —
# не доказательство, что трафик реально проксируется). Таймаут покрывает и
# медленный DNS-резолв; при зависании — отказ запуска (безопасный отказ).
_proxy_reachable() {
timeout "${PROXY_PREFLIGHT_TIMEOUT:-2}" \
bash -c "exec 3<>/dev/tcp/${_PROXY_HOST}/${_PROXY_PORT}" 2>/dev/null
}
# Внутренний: запуск команды с proxy-env. Pre-flight, затем subshell+exec —
# env виден только дочернему процессу, не протекает в родительский shell,
# код возврата пробрасывается.
_proxy_run() {
local cmd="$1"; shift
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "❌ Команда не найдена в PATH: $cmd" >&2
return 127
fi
if ! _proxy_reachable; then
echo "❌ Прокси ${_PROXY_HOST}:${_PROXY_PORT} недоступен — запуск '$cmd' отменён." >&2
return 1
fi
# exec и так резолвит через PATH в обход функций/алиасов.
( _proxy_export; exec "$cmd" "$@" )
}
pclaude() { _proxy_run claude "$@"; }
pcodex() { _proxy_run codex "$@"; }
# Удобные функции-переключатели для терминала.
proxy_on() {
_proxy_export
echo "✅ Proxy enabled. Checking route..."
# Подставляем результат выполнения curl прямо в строку
echo "🌍 Current IP: $(curl -s --max-time 3 https://ifconfig.me)"
}
proxy_off() {
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY
unset http_proxy https_proxy all_proxy no_proxy
echo "❌ Proxy disabled. Checking route..."
echo "🏠 Current IP: $(curl -s --max-time 3 https://ifconfig.me)"
}
# Заодно можно добавить алиас, чтобы быстро чекать IP в любой момент без переключения
alias myip='echo "IP: $(curl -s --max-time 3 https://ifconfig.me)"'