[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:
@@ -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`). Не начато.
|
||||
|
||||
## Связанные заметки
|
||||
|
||||
|
||||
Reference in New Issue
Block a user