[2026-09-15] eagle: family/how-to/truenas-infrastructure.md family/plans/reverse-xray-3xui-kraken.md personal/tech/vless-space-subscription-egress.md

This commit is contained in:
Alexey Martemyanov
2026-09-15 15:04:42 +06:00
parent 8364013988
commit 86ffda93d4
3 changed files with 158 additions and 12 deletions
@@ -6,7 +6,7 @@ type: tech
namespace: personal
tags: [xray, 3x-ui, x-ui, subscription, outbound, profilegrid, truenas, space]
confidence: high
status: in-progress
status: blocked-on-null-fields
related:
- "[[family/plans/reverse-xray-3xui-kraken]]"
- "[[personal/tech/xray-reverse-tunnel-kraken-truenas]]"
@@ -15,7 +15,7 @@ related:
# `vless-space` — клиент 3x-ui, egress через внешнюю подписку
> Задача поставлена Alex 2026-09-15. **Статус: НЕ применено** — SQL готов и проверен в песочнице, применение на живой БД провалилось (см. «Провал попытки 1») и требует повтора по исправленной процедуре.
> Задача поставлена Alex 2026-09-15. **Статус: ЧАСТИЧНО ПРИМЕНЕНО — БД корректна, Xray клиента не видит.** Шаблон (13 outbound + балансировщик) применён и работает; клиент `vless-space` есть во всех трёх местах БД, но в сгенерированный `config.json` не попадает. Корень найден: `auth`/`reverse` = `NULL` (см. «Корень найден»). Исправление — 4 команды, ждут выполнения.
## Что хотели
@@ -240,20 +240,102 @@ docker start xray-admin'
`user1` и `kraken-user` **не изменяются ни в одной версии SQL** — откат нужен только если сломалась БД.
## ✅ ПОПЫТКА 2 (2026-09-15, ночь-4) — SQL применён, БД корректна, но клиент не в конфиге
**Выполнено (Alex сам, вручную на TrueNAS, строки без `ssh`-обёртки — так ему удобнее):**
Ошибка экранирования в моей инструкции: `\"` внутри `ssh '... sh -c \"...\"'` ломается на `sh`. Результат: диагностические `echo "integrity_..."` упали с `unrecognized token: ""PRAGMA"`, но **сам SQL прошёл** (`sql_exit=0`, вывод `delete` + `wal` = сработали оба `PRAGMA journal_mode`).
**Факт-состояние БД после применения (все три места корректны):**
| Где | `vless-space` |
|---|---|
| таблица `clients` | ✅ `id=5`, `sub_id=24df9391356b48ff`, `enable=1`, `security=auto` |
| `inbounds.settings` JSON (id=1) | ✅ `enable=true`, `id=a792c483-…` |
| `PRAGMA integrity_check` | ✅ `ok` |
| таблица `client_traffics` | ❌ **пустая** (но и у `user1`/`kraken-user` тоже пустая — не критерий) |
**Сгенерированный `/app/bin/config.json` после рестарта:**
```json
{"inbounds":[{"tag":"api","port":62789,"clients":[]},
{"tag":"in-10095-tcp","port":10095,"clients":["user1","kraken-user"]}],
"outcount":13,
"bal":[{"tag":"space-balancer","selector":["space-"],"strategy":{"type":"leastPing"}}]}
```
**шаблон применился** (13 outbound, балансировщик на месте), **клиент — нет**.
**Таймстампы опровергли гипотезу «не перечитал БД»:** `config.json` = 15:56, `x-ui.db` = 15:53, т.е. 3x-ui сгенерировал конфиг ПОСЛЕ правки и всё равно клиента выкинул.
### 🔑 КОРЕНЬ НАЙДЕН — `NULL` вместо `''` в полях `auth`/`reverse`
Построчное сравнение `clients` показало единственное расхождение:
```
user1 auth="" reverse="" ← живые, созданы 3x-ui
kraken-user auth="" reverse=""
vless-space auth=NULL reverse=NULL ← мой INSERT, эти колонки не заполнены
```
Xray при генерации конфига спотыкается на `NULL` и **молча выкидывает** клиента из списка. SQLite ставит `NULL` вместо `''` для колонок, не указанных в `INSERT ... VALUES`.
> 🔴 **ПИТФОЛЛ (повторяемый):** при ручном `INSERT` в таблицу `clients` (3x-ui) **заполнять ВСЕ текстовые колонки** — `auth`, `reverse`, `flow`, `password`, `group_name` — пустой строкой `''`, а не оставлять их вне списка. `NULL` ≠ `''` и ломает генерацию конфига без единой ошибки в логах.
### Исправление (4 команды, ждут выполнения)
```bash
docker stop xray-admin
```
```bash
docker run --rm -v /mnt/RED_2TB/docker/xray-admin:/data alpine sh -c 'apk add --no-cache sqlite >/dev/null 2>&1; cd /data; rm -f x-ui.db-wal x-ui.db-shm; sqlite3 x-ui.db "UPDATE clients SET auth=\"\", reverse=\"\", flow=\"\" WHERE email=\"vless-space\";"; sqlite3 -header x-ui.db "select email, quote(auth), quote(reverse), quote(flow) from clients;"; chown 950:root x-ui.db'
```
```bash
docker start xray-admin
```
```bash
sleep 8; docker exec xray-admin cat /app/bin/config.json | /usr/bin/jq -r '.inbounds[].settings.clients[]?.email'
```
**Ожидаемо:** `user1`, `kraken-user`, `vless-space`.
> ⚠️ **Правило взаимодействия (Alex, 2026-09-15):** команды выдаются **строками без `ssh truenas_admin@… '…'`-обёртки** — Alex выполняет их сам, сидя на хосте. Вложенные кавычки внутри `ssh '... sh -c \"...\"'` ломают передачу (`unrecognized token`), поэтому диагностику и правки писать **плоскими однострочниками**, без экранирования внутри `sh -c`.
### Откат
```bash
docker stop xray-admin
```
```bash
docker run --rm -v /mnt/RED_2TB/docker/xray-admin:/d -v /mnt/RED_2TB/docker/backups:/b alpine sh -c 'cp -av /b/xray-admin-before-vless-space-20260915-012057/x-ui.db /d/x-ui.db; rm -f /d/x-ui.db-wal /d/x-ui.db-shm; chown 950:root /d/x-ui.db'
```
```bash
docker start xray-admin
```
Возвращает состояние «только `user1` + `kraken-user`, 3 outbound».
## Открытые риски (не проверено)
1. **`leastPing` + `observatory`** — могут не поддерживаться 3x-ui 3.7.0 (Xray 26.7.28). Если контейнер не поднимется → `docker logs xray-admin`, откат по A.
2. Если ругается на `subjectSelector` — попробовать старый ключ `selector`.
1. **`leastPing` + `observatory`** — ⚠️ **СНЯТО (2026-09-15): 3x-ui 3.7.0 / Xray 26.7.28 принимает оба ключа.** Проверено фактом: после применения шаблона контейнер поднялся, `config.json` содержит `balancers` с `leastPing`, Xray-процесс запущен (`bin/xray-linux-amd64 -c bin/config.json`), в логах ошибок нет — только безобидные `WARNING common/protocol/http: received "X-Forwarded-For" … "sockopt.trustedXForwardedFor" is not configured` (это Caddy шлёт XFF, на работу не влияет).
2. **`auth`/`reverse` = NULL при ручном INSERT** — см. «Корень найден», это и есть реальный блокер.
3. **Ссылка подписки `vpn-panel…/sub/<subId>` открыта БЕЗ авторизации** — любой, кто знает `subId`, получит ключ. Кандидат на включение подписки-по-токену в панели (не сделано).
## Что НЕ сделано / следующие шаги
- [ ] Применить `apply_space_v2.sql` по исправленной процедуре
- [x] ~~Применить `apply_space_v2.sql` по исправленной процедуре~~**применён 2026-09-15, БД корректна** (шаблон + 3 клиента)
- [ ] **Исправить `auth`/`reverse`/`flow` с `NULL` на `''`** у `vless-space` (4 команды в «Исправление») — **текущий блокер**
- [ ] Проверить, что `config.json` содержит `vless-space` после фикса
- [ ] Проверить end-to-end: тестовый клиент с UUID `vless-space``curl` → egress IP ≠ `90.189.160.148`
- [ ] Проверить, что `user1` и `kraken-user` продолжают работать
- [ ] Решить вопрос с авторизацией на sub-ссылках
- [ ] Обновить [[family/how-to/truenas-infrastructure]] (новый клиент + балансировщик)
- [ ] Отдельная задача: `hermes-taiga` ходит через `vless-proxy`, чей outbound указывает на **мёртвый** `v.qentra.top` (VPS удалён). Нужно переключить на `vpn.mallexxx.duckdns.org` (клиент `user1`) или на `vless-space`/Kraken.
- [ ] Отдельная задача: `hermes-taiga` ходит через `vless-proxy`, чей outbound указывает на **мёртвый** `v.qentra.top` (VPS удалён). Нужно переключить на `vpn.mallexxx.duckdns.org` (клиент `user1`) или на `vless-space`/Kraken. **Alex спрашивал, можно ли переключить — ответ: да**, правка 5 полей в `/mnt/RED_2TB/docker/vless-proxy/config.json` (`address``vpn.mallexxx.duckdns.org`, `users[0].id``ce320965-6956-4759-84bb-7cb71cfc6252`, `tlsSettings.serverName``vpn.mallexxx.duckdns.org`, `wsSettings.headers.Host``vpn.mallexxx.duckdns.org`, `wsSettings.path``/vless`). Не начато.
## Связанные заметки