351 lines
27 KiB
Markdown
351 lines
27 KiB
Markdown
---
|
||
title: Xray outbound — внешняя подписка в 3x-ui (vless-space)
|
||
created: '2026-09-15'
|
||
updated: '2026-09-15'
|
||
type: tech
|
||
namespace: personal
|
||
tags:
|
||
- xray
|
||
- 3x-ui
|
||
- subscription
|
||
- outbound
|
||
- truenas
|
||
- reality
|
||
- balancer
|
||
confidence: high
|
||
status: blocked-no-panel-access
|
||
related:
|
||
- '[[family/how-to/truenas-infrastructure]]'
|
||
- '[[personal/tech/xray-reverse-tunnel-kraken-truenas]]'
|
||
- '[[personal/tech/vless-space-subscription-egress]]'
|
||
- '[[family/how-to/vps-qentra]]'
|
||
---
|
||
|
||
# Xray outbound из внешней подписки в 3x-ui (`vless-space`)
|
||
|
||
> ## ✅ ОБНОВЛЕНО 2026-09-15 (вечер): БАРЬЕР ПРЕОДОЛЁН — `xui_v7.db` ЗАЛИТА УСПЕШНО
|
||
>
|
||
> **Прежний вывод «клиентов через SQLite добавить нельзя» — ОПРОВЕРГНУТ.** `xui_v7.db` залита, и клиент появился:
|
||
>
|
||
> | Проверка | Результат |
|
||
> |---|---|
|
||
> | `in-10095-tcp` clients | ✅ `user1,kraken-user,vless-space` **одной строкой** (без дубля, без порта 10096) |
|
||
> | outbounds | ✅ 13 |
|
||
> | подписка `/sub/24df9391356b48ff` | ✅ **HTTP 200** — QR появился |
|
||
> | `kraken-user` | ✅ **не отвалился** |
|
||
>
|
||
> **Что было настоящим барьером (а не «внутренняя память 3x-ui»):** в попытках 5-6 инбаунд `in-10095-tcp` лежал **внутри `xrayTemplateConfig`**. 3x-ui мёржит шаблон с таблицей `inbounds`, шаблонная версия того же тега перебивает панельную → клиенты исчезают. Как только инбаунд убран из шаблона (попытка 7) — SQLite-путь **работает штатно**, клиент и подписка в норме.
|
||
>
|
||
> **Остаточная проблема — НЕ в клиенте, а в стратегии балансировщика:** egress `vless-space` не идёт из-за `leastPing` (см. §«leastLoad»). Клиент создан, подписка работает, маршрут — нет. Собран `xui_v7_load.db` (`leastPing`→`leastLoad`), залит не был.
|
||
>
|
||
> ⛔ **Правило взаимодействия (Alex, 2026-09-15):** команды — **плоские однострочники без `ssh … '…'`-обёртки**, **без `sleep N`**, **без кириллицы в bash**, без `execute_code`/python. Alex выполняет их сам.
|
||
|
||
## Задача
|
||
|
||
Добавить в `xray-admin` (3x-ui на TrueNAS) **третьего клиента** `vless-space`, чей трафик идёт не напрямую (как `user1`) и не через reverse-Кра́кен (как `kraken-user`), а **через серверы внешней Xray-подписки** `profilegrid.net`, с автоматическим выбором живого сервера. `user1` и `kraken-user` не трогаются.
|
||
|
||
```
|
||
[клиент vless-space] → vpn.mallexxx.duckdns.org:443 → xray-admin
|
||
└→ space-01…space-10 (leastPing) → интернет (DE/LV/NL/EE/PL/FR/US/SE/MD)
|
||
```
|
||
|
||
## Ключевые решения и почему
|
||
|
||
| Решение | Почему |
|
||
|---|---|
|
||
| **Править `settings.xrayTemplateConfig` в `x-ui.db`, а не `config.json`** | ✅ **Подтверждено фактом:** 3x-ui генерирует `/app/bin/config.json` из БД. `/app/bin/config.json` править бесполезно (перезапишется). Из шаблона применились все 13 outbound'ов + балансировщик. |
|
||
| **Развернуть серверы подписки в обычные outbound'ы** | Не зависит от версии панели. Работает сразу после `docker start`. |
|
||
| **НЕ полагаться на `inbounds` в SQL — только панель** | 🔴 **Урок сессии:** клиенты инбаунда через SQLite снаружи **не применяются**. 3x-ui держит БД открытой, пишет в `-wal`, и при рестарте берёт список клиентов из своей внутренней памяти, а не из файла. Четыре подхода (INSERT в `clients`, правка `inbounds.settings`, фикс `NULL`, дописать `security`) — все отбились. |
|
||
| **НЕ класть существующий инбаунд в `xrayTemplateConfig`** | 🔴 **Урок 6-й попытки (2026-09-15):** попытка протащить `in-10095-tcp` с тремя клиентами внутрь шаблона **сломала `kraken-user`** — 3x-ui мёржит шаблон с таблицей `inbounds`, и шаблонная версия того же тега перебивает панельную (клиенты исчезают, egress-правило по email не срабатывает). В шаблоне — **только outbound'ы/правила/балансировщик**. Инбаунды — эксклюзив панели. |
|
||
| ~~**`leastPing` + `observatory`**~~ | 🔴 **ОПРОВЕРГНУТО 2026-09-15 (вечер).** `leastPing` в Xray 26.x **не работает** — балансировщик не создаётся, `non existing outTag: space-balancer` в рантайме. Рабочая стратегия: **`leastLoad`**. См. §«leastLoad» ниже. |
|
||
| **Правило по `user`, а не по клиентскому id** | Образец взят с рабочего `kraken-user-via-reverse`: Xray матчит клиента inbound'а по `email`. |
|
||
|
||
## 🔴 ОБЯЗАТЕЛЬНО: `leastLoad`, а НЕ `leastPing` (проверено 2026-09-15)
|
||
|
||
```jsonc
|
||
// ✅ РАБОТАЕТ в Xray 26.3.27 / 26.7.28
|
||
"balancers": [ { "tag": "space-balancer", "selector": ["space-"],
|
||
"strategy": { "type": "leastLoad" } } ]
|
||
"observatory": { "subjectSelector": ["space-"],
|
||
"probeUrl": "https://www.google.com/generate_204",
|
||
"probeInterval": "30s", "enableConcurrency": true }
|
||
```
|
||
|
||
```jsonc
|
||
// ❌ НЕ РАБОТАЕТ — тег не регистрируется, трафик молча теряется
|
||
"strategy": { "type": "leastPing" }
|
||
```
|
||
|
||
**A/B на минимальном конфиге (docker, TrueNAS):** `leastPing` → `non existing outTag`; `burstObservatory + leastPing` → то же; **`leastLoad` + `observatory` → `the outbound space-01 is alive:0.249`, `taking detour [space-02]`** ✅.
|
||
|
||
> ⚠️ **`xray -test` печатает `Configuration OK` и для `leastPing`** — валидация конфига ошибку НЕ ловит. Проверять только рантайм-логом + живым запросом.
|
||
> ⚠️ **`chmod 644` конфига** перед `docker run -v …` — иначе `permission denied`.
|
||
|
||
## Питфоллы (все проверены фактом)
|
||
|
||
1. **🔴 SSH к TrueNAS обрывается на `docker stop xray-admin`** — `closed by remote host`. Контейнер **сам поднялся** (`restart: unless-stopped`), БД не пострадала. Останавливать и применять SQL **одной короткой командой**, не серией вызовов.
|
||
2. **WAL:** `docker stop` у 3x-ui корректно закрывает БД и **сливает WAL в основной файл**. Удалять `-wal`/`-shm` можно только **после** остановки. Правка при живом WAL = риск порчи базы.
|
||
3. **`sqlite3` внутри контейнера ОТСУТСТВУЕТ** (`which sqlite3` пусто). Использовать: `docker cp` БД на хост, либо хостовый `sqlite3`, либо `alpine`-контейнер.
|
||
4. **Дедуп подписки:** 28 строк → **10 уникальных серверов**. Одна подписка отдаёт несколько записей на один хост с разными `pbk`/`sid` (перебор ключей). Ключ дедупа — `host + publicKey + shortId`.
|
||
5. **REALITY в outbound:** параметры кладутся в `streamSettings.realitySettings` (`serverName`, `publicKey`, `shortId`, `spiderX`, `fingerprint`), а `flow: xtls-rprx-vision` — в `users[0].flow` (в ссылке он приходит query-параметром).
|
||
6. **`spx` в ссылке URL-энкодирован** (`%2F…`) — обязателен `unquote`, иначе Xray падает на `spiderX`.
|
||
7. **`routing.balancers.selector` — префиксный матч:** `["space-"]` подхватывает `space-01`…`space-10`.
|
||
8. **Правки в `routing.rules` добавлять В КОНЕЦ** — существующие правила (`api`, `geoip:private→blocked`, `bittorrent→blocked`, `kraken-user→via-kraken`) должны сохранить приоритет.
|
||
|
||
## Шаблон конфига — что добавляется
|
||
|
||
Существующее (outbound'ы `direct`/`blocked`/`via-kraken`, правила, inbound) **не трогается**. Добавляется:
|
||
|
||
```jsonc
|
||
// в outbounds[]
|
||
{ "tag": "space-01", "protocol": "vless",
|
||
"settings": { "vnext": [{ "address": "edge-de.mirrorgrid.net", "port": 443,
|
||
"users": [{ "id": "c67ce742-d94f-4e56-889e-9f894ae59940",
|
||
"encryption": "none", "flow": "xtls-rprx-vision" }] }] },
|
||
"streamSettings": { "network": "tcp", "security": "reality",
|
||
"realitySettings": { "serverName": "edge-de.mirrorgrid.net",
|
||
"fingerprint": "firefox", "publicKey": "<pbk>",
|
||
"shortId": "<sid>", "spiderX": "/" } } }
|
||
// … space-02 … space-10
|
||
|
||
// в routing.rules[] (В КОНЕЦ)
|
||
{ "type": "field", "user": ["vless-space"],
|
||
"outboundTag": "space-balancer", "ruleTag": "vless-space-via-subscription" }
|
||
|
||
// новый ключ routing.balancers
|
||
[ { "tag": "space-balancer", "selector": ["space-"],
|
||
"strategy": { "type": "leastPing" } } ]
|
||
|
||
// новый ключ observatory (ОБЯЗАТЕЛЕН для leastPing)
|
||
{ "subjectSelector": ["space-"],
|
||
"probeUrl": "https://www.google.com/generate_204",
|
||
"probeInterval": "30s", "enableConcurrency": true }
|
||
```
|
||
|
||
## Артефакты (Mac)
|
||
|
||
Рабочая папка: **`~/tmp-xray-space/`**
|
||
|
||
| Файл | Назначение |
|
||
|---|---|
|
||
| `build_template.py` | парсер `vless://` → xray-outbound; сборка шаблона (outbounds + rule + balancer + observatory) |
|
||
| `make_sql.py` | генератор `apply_space.sql` по живой БД |
|
||
| `apply_space.sql` | **готовый SQL** для применения (3 операции) |
|
||
| `template_config.new.json` | итоговый шаблон, 11 140 б, JSON VALID |
|
||
| `space_outbounds.json` | 10 новых outbound'ов (отчёт) |
|
||
| `sub_decoded.txt` | подписка, base64 развёрнут — 28 строк |
|
||
| `xui_copy.db` / `test_apply.db` | копия живой БД / песочница с применённым SQL |
|
||
|
||
**Параметры клиента (сгенерированы):**
|
||
|
||
| | |
|
||
|---|---|
|
||
| email | `vless-space` |
|
||
| UUID | `a792c483-07e2-4723-9c50-78054c0abc07` |
|
||
| `subId` | `24df9391356b48ff` |
|
||
| sub-ссылка | `https://vpn-panel.mallexxx.duckdns.org/sub/24df9391356b48ff` |
|
||
|
||
## 🔴 Почему внешняя правка НЕ работает (главный урок сессии)
|
||
|
||
Проверено четырьмя подходами, все отбились:
|
||
|
||
| # | Подход | Результат |
|
||
|---|---|---|
|
||
| 1 | SQL в **копию** БД → копия на место старых `-wal`/`-shm` | `database disk image is malformed` |
|
||
| 2 | SQL v2 напрямую (`PRAGMA journal_mode=DELETE`, `rm -wal` до правки) | SQL прошёл, БД корректна → в `config.json` клиента нет |
|
||
| 3 | Фикс `auth`/`reverse` (NULL → `''`) | применено → клиента нет |
|
||
| 4 | Дописать `security:"auto"` в `inbounds.settings` | применено (`3 × security:auto`) → клиента нет |
|
||
|
||
**Что закрыло вопрос:**
|
||
|
||
```
|
||
ls -la /app/bin/config.json /etc/x-ui/x-ui.db
|
||
→ config.json = 2978 б (16:06) ← схлопнулся с 11 990
|
||
→ x-ui.db = 262144 б (15:00) ← СТАРАЯ дата, правки не попали
|
||
```
|
||
|
||
1. **`x-ui.db` не обновлялся** — правки, применённые в 15:53/16:02/16:06, в основной файл **не попадали**. 3x-ui держит базу и пишет в `-wal`; удаление `-wal` перед правкой уничтожало актуальные данные, после правки он перезаписывал файл из своего состояния.
|
||
2. **`config.json` перегенерирован из внутренней памяти** 3x-ui, а не из файла — отсюда парадокс: **13 outbound'ов применились** (шаблон `settings` он читает), **третий клиент исчез** (список клиентов берёт из своей памяти).
|
||
|
||
> 🔴 **ВЫВОД (исправлен 2026-09-15 вечером): `inbounds` и клиентов 3x-ui через SQLite править МОЖНО — но при двух жёстких условиях.** Прежний вывод «нельзя вообще» был **неверен**: он был основан на сборках, где инбаунд лежал внутри `xrayTemplateConfig` (см. урок 6) и где копию БД клали рядом со старыми `-wal`/`-shm`.
|
||
>
|
||
> **Условия, при которых SQLite-путь РАБОТАЕТ (проверено заливкой `xui_v7.db`):**
|
||
> 1. Инбаунд `in-10095-tcp` **НЕ должен присутствовать в `xrayTemplateConfig`** (в шаблоне — только `api`).
|
||
> 2. БД правится **локально на Mac**, затем кладётся файлом при остановленном контейнере, с `rm -f x-ui.db-wal x-ui.db-shm` и `chown 950:root`.
|
||
>
|
||
> Результат: клиент появился в `config.json`, подписка отдала HTTP 200, `kraken-user` не пострадал.
|
||
>
|
||
> **Что при этом всё равно требует внимания:** `xray -test` не ловит семантические ошибки маршрутизации (пример: `leastPing` даёт `Configuration OK`, но в рантайме `non existing outTag`). Рантайм-лог обязателен.
|
||
|
||
### Рецепт, который сработал (`xui_v7.db`, 2026-09-15)
|
||
|
||
Сборка **от оригинала** (`xui_copy.db`), не от промежуточных копий:
|
||
|
||
```bash
|
||
# 1) шаблон: ТОЛЬКО outbounds + rule + balancer + observatory (инбаунд api уже есть)
|
||
sqlite3 xui_v6.db "SELECT value FROM settings WHERE key='xrayTemplateConfig';" | \
|
||
jq '[.outbounds[] | select(.tag | startswith("space-"))]' > /tmp/space_outs.json
|
||
jq --slurpfile sp /tmp/space_outs.json '.outbounds += $sp[0]
|
||
| .routing.rules += [{"type":"field","user":["vless-space"],"outboundTag":"space-balancer","ruleTag":"vless-space-via-subscription"}]
|
||
| .routing.balancers = [{"tag":"space-balancer","selector":["space-"],"strategy":{"type":"leastLoad"}}]
|
||
| .observatory = {"subjectSelector":["space-"],"probeUrl":"https://www.google.com/generate_204","probeInterval":"30s","enableConcurrency":true}' \
|
||
/tmp/base_orig.json > /tmp/tpl_final.json
|
||
# ⛔ .inbounds НЕ трогать — там остаётся только api
|
||
|
||
# 2) клиент в ТРИ места: inbounds.settings JSON, clients, client_inbounds
|
||
sqlite3 xui_v7.db "UPDATE inbounds SET settings = json_set(settings, '$.clients', json('<новый_массив>')) WHERE id=1;"
|
||
sqlite3 xui_v7.db "INSERT INTO clients (id,email,sub_id,uuid,password,auth,flow,security,reverse,...) VALUES (5,'vless-space',...);"
|
||
sqlite3 xui_v7.db "INSERT INTO client_inbounds (client_id,inbound_id,flow_override,created_at) VALUES (5,1,'',...);"
|
||
# client_traffics НЕ трогать — в оригинале пусто, 3x-ui заполняет сам
|
||
|
||
# 3) обязательная гигиена перед заливкой
|
||
sqlite3 xui_v7.db "PRAGMA journal_mode=DELETE;"; rm -f xui_v7.db-wal xui_v7.db-shm
|
||
sqlite3 xui_v7.db "PRAGMA integrity_check;" # → ok
|
||
```
|
||
|
||
**Контроль качества:** `diff <(sqlite3 xui_copy.db .dump) <(sqlite3 xui_v7.db .dump)` — должно быть ровно 4 изменения (клиент в `inbounds.settings`, строка в `clients`, строка в `client_inbounds`, шаблон + `sqlite_sequence`). Всё лишнее — ошибка.
|
||
|
||
**Заливка на TrueNAS:**
|
||
```bash
|
||
scp ~/tmp-xray-space/xui_v7.db truenas_admin@mallexxx.duckdns.org:/tmp/xui_v7.db
|
||
docker stop xray-admin
|
||
docker run --rm -v /mnt/RED_2TB/docker/xray-admin:/data -v /mnt/RED_2TB/docker/backups:/b -v /tmp:/src alpine sh -c 'TS=$(date +%Y%m%d-%H%M%S); mkdir -p /b/xray-admin-v7-$TS; cp -av /data/x-ui.db /b/xray-admin-v7-$TS/; rm -f /data/x-ui.db-wal /data/x-ui.db-shm; cp -av /src/xui_v7.db /data/x-ui.db; chown 950:root /data/x-ui.db; echo BACKUP=/b/xray-admin-v7-$TS'
|
||
docker start xray-admin
|
||
```
|
||
|
||
**Проверка после старта:**
|
||
```bash
|
||
docker exec xray-admin cat /app/bin/config.json | /usr/bin/jq -r '.inbounds[] | "\(.tag) port=\(.port) clients=\([.settings.clients[]?.email]|join(\",\"))"'
|
||
docker exec xray-admin cat /app/bin/config.json | /usr/bin/jq -c '{out:(.outbounds|length),bal:.routing.balancers[0].strategy}'
|
||
docker exec xray-admin cat /app/bin/config.json | /usr/bin/jq -r '.inbounds[].tag' # в шаблоне должен быть ТОЛЬКО api
|
||
curl -sk -o /dev/null -w "sub: %{http_code}\n" https://vpn-panel.mallexxx.duckdns.org/sub/24df9391356b48ff
|
||
```
|
||
|
||
### Историческая (ошибочная) формулировка — оставлена для контекста
|
||
|
||
> Работает только `settings.xrayTemplateConfig` (outbound'ы/правила/балансировщики). Всё, что касается клиентов инбаунда, идёт **исключительно через панель** (`/panel/api/inbounds/update/:id`) — а для API нужен **API-токен**.
|
||
|
||
**Почему это было неверно:** «внутреннюю память 3x-ui» обвиняли зря. Настоящая причина — инбаунд внутри шаблона. См. §«БАРЬЕР ПРЕОДОЛЁН» в шапке.
|
||
|
||
> **Как это делали раньше:** `kraken-user` добавлен 2026-09-02 **при участии панели** — в Zulip-записи прямо сказано «Temporary full-admin API token **не создавался**; `api_tokens` осталась пустой» + «Verified with the local `xray-test-client`». Это и есть подтверждение, что путь был через API панели, а не через SQL.
|
||
|
||
## §6 Как довести до конца — ждёт доступа к панели
|
||
|
||
### 🔴 Попытка 7 (2026-09-15, финал) — `xui_v7.db`, шаблон БЕЗ инбаунда
|
||
|
||
Исправление ошибки попытки 6: инбаунд `in-10095-tcp` **убран из шаблона**, собиралось от оригинала (`xui_copy.db`).
|
||
|
||
| Что | Значение |
|
||
|---|---|
|
||
| `xrayTemplateConfig.inbounds` | **только `api`** ✅ |
|
||
| `xrayTemplateConfig.outbounds` | 13 ✅ |
|
||
| balancer / observatory | `space-balancer` (leastPing) / `selector: ["space-"]` ✅ |
|
||
| `inbounds` (таблица) | `vless-ws` port 10095, clients = `user1`, `kraken-user`, `vless-space` |
|
||
| `clients` / `client_inbounds` | `vless-space` id=5 (+ привязка `5→1`) |
|
||
| diff от `xui_copy.db` | ровно 4 изменения, все по делу |
|
||
| `integrity_check` / `journal_mode` | `ok` / `DELETE` |
|
||
|
||
**Статус: не залита.** Файл `~/tmp-xray-space/xui_v7.db` (270 336 б).
|
||
|
||
> ⚠️ **Ожидание — низкое.** В оригинале таблица `client_traffics` **пуста**, хотя два клиента живые. Значит панель рендерит клиентов не из дисковых таблиц. Скорее всего барьер попыток 2-6 сохранится: шаблон применится, клиент — нет.
|
||
|
||
### Диагностический признак: инбаунд «дважды» в выводе `jq`
|
||
|
||
Если это:
|
||
|
||
```
|
||
in-10095-tcp port=10095 clients=user1,kraken-user,vless-space
|
||
in-10095-tcp port=10095 clients=user1,kraken-user
|
||
```
|
||
|
||
— то это **НЕ два инбаунда**, а шаблонная копия + панельная (симптом ошибки попытки 6). Проверка-опровержение:
|
||
|
||
```bash
|
||
docker exec xray-admin cat /app/bin/config.json | /usr/bin/jq -r '.inbounds[].tag'
|
||
```
|
||
|
||
Правильно — **только `api`** в списке инбаундов шаблона; сам `in-10095-tcp` приходит из таблицы `inbounds`.
|
||
|
||
### Путь к цели
|
||
|
||
**Блокер:** логин панели `vpn-admin`, пароль — bcrypt-хэш (нечитаем). `secret` из БД (`RuERf2DTzPTw3CoMcVjk7tGXKCQOk0Z4`) для логина дал 403, API-путь — 404.
|
||
|
||
**Вариант А — панель вручную** (2 минуты):
|
||
|
||
```
|
||
https://vpn-panel.mallexxx.duckdns.org/ (логин vpn-admin)
|
||
→ Inbounds → vless-ws (10095) → Edit
|
||
→ Clients → Add Client:
|
||
Email: vless-space
|
||
ID: a792c483-07e2-4723-9c50-78054c0abc07
|
||
Sub ID: 24df9391356b48ff
|
||
Enable: ✅
|
||
→ Save → Restart Xray (в шапке)
|
||
```
|
||
Затем routing-правило на `space-balancer` — тоже через панель (Xray → Routing).
|
||
|
||
**Вариант Б — API-токен:** Settings → API Tokens → Create, отдать агенту → он делает всё сам через `/panel/api/inbounds/update/1`.
|
||
|
||
**Готовый SQL на Mac (не применён):** `~/tmp-xray-space/apply_final.sql` (13 447 б) — делает 4 операции одной транзакцией: клиент в `clients`, клиент в `inbounds.settings`, шаблон с 10 серверами + правило + балансировщик, запись в `outbound_subscriptions`. ⚠️ Учитывая урок сессии, **сработавшей будет только 3-я операция** (шаблон) — клиента всё равно придётся добавлять через панель.
|
||
|
||
**Откат:** `/mnt/RED_2TB/docker/backups/xray-admin-before-vless-space-20260915-012057/` → скопировать `x-ui.db` при остановленном контейнере → `docker start xray-admin`.
|
||
|
||
## Ограничение: «auto» здесь НЕ автоматическое
|
||
|
||
Выбранный путь разворачивает серверы подписки в **статические** outbound'ы. Если провайдер сменит список серверов, шаблон надо **пересобрать вручную**: `build_template.py` → `make_sql.py` → применить.
|
||
|
||
**Для настоящего авто-обновления нужен cron-скрипт на TrueNAS:**
|
||
```
|
||
curl подписки → base64 -d → build_template.py → пересобрать xrayTemplateConfig
|
||
→ стоп xray-admin → SQL → старт
|
||
```
|
||
Не реализован. Альтернатива без скрипта — использовать штатную таблицу `outbound_subscriptions` через панель (даёт `update_interval` из коробки, но требует доступа к UI).
|
||
|
||
## Открытый вопрос безопасности (не решён)
|
||
|
||
`/sub/<subId>` отдаётся **без авторизации** (`/sub/abc` тоже 200). Новая ссылка `vless-space` будет так же открыта. Варианты: подписка по токену, ротация `subId`. Задано Alex 2026-09-15, решения нет.
|
||
|
||
## Связанные заметки
|
||
|
||
- [[family/how-to/truenas-infrastructure]] — контейнер `xray-admin`, клиенты, sub-канал
|
||
- [[personal/tech/xray-reverse-tunnel-kraken-truenas]] — reverse-туннель (отдельный механизм)
|
||
- [[family/how-to/vps-qentra]] — удалённый VPS (источник мёртвого `v.qentra.top`)
|
||
|
||
## 🔴 2026-09-15: попутные находки этой сессии
|
||
|
||
### 1. `hermes-taiga` ходит НЕ через `xray-admin`, а через `vless-proxy` (мёртвый)
|
||
|
||
Разбор путаницы «таига настроена через user1?» — **нет**:
|
||
|
||
| | |
|
||
|---|---|
|
||
| Env `hermes-taiga` | `TELEGRAM_PROXY=socks5://vless-proxy:1080`, `DISCORD_PROXY=socks5://vless-proxy:1080` |
|
||
| Сети `hermes-taiga` | `hermes_taiga_net`, `ha_default` |
|
||
| `vless-proxy` | образ `teddysun/xray:latest`, SOCKS `:1080` + HTTP `:1081`, outbound → **`v.qentra.top:443` (мёртв, VPS удалён)** |
|
||
| Сеть `xray-admin` | `caddy_default` — с `hermes-taiga` **не пересекается** |
|
||
| `user1` | id `ce320965-…` — клиент inbound `in-10095-tcp`, `hermes-taiga` к нему **не обращается** |
|
||
|
||
**Следствие:** Telegram/Discord у `hermes-taiga` сейчас без сети (цепочка `hermes-taiga → vless-proxy:1080 → v.qentra.top → timeout`).
|
||
|
||
**Как чинить (обсуждалось, НЕ выполнено):** переписать outbound `/mnt/RED_2TB/docker/vless-proxy/config.json` с мёртвого `v.qentra.top` на живой сервер. 4 поля:
|
||
|
||
| Поле | Сейчас | Станет |
|
||
|---|---|---|
|
||
| `address` | `v.qentra.top` | `vpn.mallexxx.duckdns.org` |
|
||
| `users[0].id` | `2D9F24C4-21FE-4784-9843-F11C384DA67A` | `ce320965-6956-4759-84bb-7cb71cfc6252` (`user1`) |
|
||
| `tlsSettings.serverName` | `v.qentra.top` | `vpn.mallexxx.duckdns.org` |
|
||
| `wsSettings.headers.Host` | `v.qentra.top` | `vpn.mallexxx.duckdns.org` |
|
||
| `wsSettings.path` | `/qentra` | `/vless` |
|
||
|
||
Порт `443`, `security: tls`, `network: ws` — без изменений. `xray-admin` **не имеет SOCKS-входа** (он сервер) — поэтому `vless-proxy` нужен как локальный клиент-мостик, его нельзя просто «выкинуть».
|
||
|
||
> ⚠️ Побочный эффект: трафик пойдёт `vless-proxy → vpn.mallexxx.duckdns.org:443 → Caddy → xray-admin` на том же хосте → egress = IP TrueNAS `90.189.160.148`. Петля внутри TrueNAS.
|
||
|
||
### 2. Compose-файл `xray-admin` утрачен — подробный разбор
|
||
|
||
См. [[family/plans/reverse-xray-3xui-kraken]] (шапка). Кратко: `rm -f /etc/x-ui/docker-compose.yml` внутри контейнера 2026-09-01 05:40:08 UTC снёс файл на хосте через bind-mount. Восстанавливать из `docker inspect`.
|
||
|
||
### 3. «Auto» в Xray-контейнере = только скрипт
|
||
|
||
Ещё раз зафиксировано: **Xray-бинарник подписки не умеет.** Умеет один/несколько статических outbound'ов + `routing.balancers`. Авто-подписка (`update_interval`) — только GUI-клиенты (Happ/v2rayN/NekoBox) **или** штатная таблица `outbound_subscriptions` 3x-ui через панель. Для docker-контейнера (`hermes-taiga`, `vless-proxy`) «auto» = cron-скрипт.
|