From 86ffda93d438b9f76cd8bb5de9f1b7f5727dd626 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 15 Sep 2026 15:04:42 +0600 Subject: [PATCH] [2026-09-15] eagle: family/how-to/truenas-infrastructure.md family/plans/reverse-xray-3xui-kraken.md personal/tech/vless-space-subscription-egress.md --- family/how-to/truenas-infrastructure.md | 26 +++-- family/plans/reverse-xray-3xui-kraken.md | 50 ++++++++++ .../tech/vless-space-subscription-egress.md | 94 +++++++++++++++++-- 3 files changed, 158 insertions(+), 12 deletions(-) diff --git a/family/how-to/truenas-infrastructure.md b/family/how-to/truenas-infrastructure.md index 48624f2a..1e1f183e 100644 --- a/family/how-to/truenas-infrastructure.md +++ b/family/how-to/truenas-infrastructure.md @@ -13,7 +13,7 @@ > - **⚠️ «Камера на TrueNAS» — ИСПРАВЛЕНО (2026-09-14, вечер-10) + ✅ РЕШЕНО ОКОНЧАТЕЛЬНО (вечер-13):** прежняя запись «камера = USB-вебка на t610, upstream `cam.*:8090` к камере отношения не имеет» — **❌ НЕВЕРНА**. Поиск в `Caddyfile.bak` доказал: **`cam.mallexxx.duckdns.org → 192.168.2.197:8090` — ЭТО И БЫЛА камера** на TrueNAS: отдельный HTTP-MJPEG-сервис (`ustreamer`/`mjpg-streamer`, порт 8090 — канон для «USB-вебка → MJPEG»). **Контейнер УТРАЧЕН** при пересоздании пула (локальный образ не пережил `.ix-apps`; из живого Caddyfile строка удалена — `cam.*` больше нет). **✅ ФИНАЛ (вечер-13):** вебка `046d:0825` физически в **t610**, работает через **аддон `a889bffc_go2rtc-hardware`** → RTSP H.264 `rtsp://192.168.2.176:8554/usb_camera_h264` → **Generic Camera** `camera.192_168_2_176` (зона `kotelnaia`, `unique_id`, **WebRTC работает**, поворот `#rotate=90`). Схема `camera: platform: ffmpeg` в Core — **❌ ОТВЕРГНУТА** (`Resource busy` + нет `unique_id`). Подробно — [[family/how-to/home-automation]] §5-кватер-И-3/И-6. > - **Не перенесено с TrueNAS:** ~~погашение TrueNAS-стека (Этап 4 п.6 — заблокировано: Caddy на TrueNAS держит точку входа)~~ → **✅ ЗАКРЫТО 2026-09-14 (ночь): стек автоматизации ПОГАШЕН, Caddy остался на TrueNAS (так и задумано).** См. §5-кватер-Л в [[family/how-to/home-automation]]. -> Обновлено: 2026-09-15 (ночь-3: **`vless-space` — попытка 1 применения на живую БД ПРОВАЛИЛАСЬ (`database disk image is malformed`), причина найдена и исправлена.** Причина: SQL применялся к **копии** `x-ui.db`, созданной без её `-wal`/`-shm`, и копия клалась рядом со **старыми** WAL/SHM → SQLite применяла чужой журнал. 🔴 **ПИТФОЛЛ:** для WAL-базы нельзя копировать только `.db`; либо работать напрямую при остановленном процессе, либо удалять `-wal`/`-shm` до открытия. Исправленная процедура — в `~/tmp-xray-space/apply_space_v2.sql` (с `PRAGMA journal_mode=DELETE` в начале и `WAL` в конце, запись НАПРЯМУЮ в `/data/x-ui.db`). **✅ Также в этой сессии: compose-файл `xray-admin` ВОССТАНОВЛЕН** из `docker inspect` (утрачен 2026-09-01, см. [[family/plans/reverse-xray-3xui-kraken]]). Полный разбор задачи — [[personal/tech/vless-space-subscription-egress]]. Ранее 2026-09-15 (ночь-2: артефакты `vless-space` собраны и проверены в песочнице; путь через БД подтверждён рабочим, шаг «нужны креды панели» **снят как неверный**). Ранее 2026-09-15 (вечер: черновой план `vless-space`, подписка проверена). Ранее: 2026-09-15 (subscription-канал 3x-ui: ссылки `/sub/` работают, base64 vless-список). Ранее: 2026-09-02 (vpn.mallexxx:443 = РАБОЧИЙ Xray-сервер, проверено end-to-end; vless-proxy outbound мёртв) +> Обновлено: 2026-09-15 (ночь-4: **`vless-space` — ПОПЫТКА 2: SQL применён, БД полностью корректна, но Xray клиента не видит.** Корень найден: `auth`/`reverse` = `NULL` вместо `''` (SQLite ставит `NULL` в колонки, не указанные в `INSERT`; Xray молча выкидывает такого клиента из `config.json`). Шаблон при этом применился — **13 outbound + балансировщик `space-balancer` (leastPing) работают**, гипотеза «`leastPing`/`observatory` не поддерживаются» **опровергнута**. Исправление (4 команды) готово, ждёт выполнения. 🔴 **НОВЫЕ ПИТФОЛЛЫ:** (1) ручной `INSERT` в `clients` — заполнять все текстовые колонки `''`; (2) команды для Alex давать **без `ssh truenas_admin@… '…'`-обёртки** — вложенные кавычки ломают `sh -c` (`unrecognized token`), Alex выполняет сам на хосте. **✅ Compose-файл `xray-admin` ВОССТАНОВЛЕН** из `docker inspect`. Полный разбор — [[personal/tech/vless-space-subscription-egress]]. Ранее 2026-09-15 (ночь-3: попытка 1 провалилась с `database disk image is malformed` — SQL применялся к копии `.db` без `-wal`/`-shm`, копия клалась рядом со старыми WAL/SHM → чужой журнал. 🔴 **ПИТФОЛЛ:** для WAL-базы нельзя копировать только `.db`; либо работать напрямую при остановленном процессе, либо удалять `-wal`/`-shm` до открытия. Исправлено в `~/tmp-xray-space/apply_space_v2.sql`. Также в этой сессии: compose-файл `xray-admin` **восстановлен** из `docker inspect` (утрачен 2026-09-01, см. [[family/plans/reverse-xray-3xui-kraken]]). Ранее 2026-09-15 (ночь-2: артефакты `vless-space` собраны и проверены в песочнице; путь через БД подтверждён рабочим, шаг «нужны креды панели» **снят как неверный**). Ранее 2026-09-15 (вечер: черновой план `vless-space`, подписка проверена; subscription-канал 3x-ui: ссылки `/sub/` работают, base64 vless-список). Ранее: 2026-09-02 (vpn.mallexxx:443 = РАБОЧИЙ Xray-сервер, проверено end-to-end; vless-proxy outbound мёртв) > ## ⚠️ ПРИОРИТЕТ 2026-09-01: VPS qentra.top УДАЛЁН → vless-proxy и сетевые туннели сломаны > - **VPS `91.207.28.205` больше НЕ существует** (вся его Xray/OpenVPN/WG-инфраструктура утрачена). Подробно: [[family/how-to/vps-qentra]]. @@ -438,12 +438,24 @@ arr, caddy, cups, filebrowser, gitea, hermes, immich, inpx-web, inpxer, library, | Образ | `ghcr.io/mhsanaei/3x-ui:latest` (3.7.0, Xray 26.7.28) | | Volume | `/mnt/RED_2TB/docker/xray-admin:/etc/x-ui` (там `x-ui.db`) | | Сеть | `caddy_default` (внешняя) | -| Панель | `https://vpn-panel.mallexxx.duckdns.org/` (Caddy → xray-admin:2053) | -| Inbound | `vless-ws` port `10095`, tag `in-10095-tcp`, path `/vless`, host `vpn.mallexxx.duckdns.org`; clients: `user1` (direct TrueNAS), `kraken-user` (reverse via Kraken), **`vless-space`** (egress через внешнюю подписку `profilegrid.net` — ⏳ SQL собран и проверен, **в БД не применён**) | +| Панель | `https://vpn-panel.mallexxx.duckdns.org/` (Caddy → `xray-admin:2053`) | +| Inbound | `vless-ws` port `10095`, tag `in-10095-tcp`, path `/vless`, host `vpn.mallexxx.duckdns.org`; clients: `user1` (direct TrueNAS), `kraken-user` (reverse via Kraken), `vless-space` (подписка profilegrid — см. ниже) | | Sub-сервер | `[::]:443` (path /sub), панель `[::]:2053` | -| Env | `TZ=Asia/Novosibirsk`, `PUID=950`, `PGID=950` | +| Env | `TZ=Asia/Novosibirsk`, `PUID=950`, `PGID=950`, `XUI_IN_DOCKER=true`, `XUI_MAIN_FOLDER=/app`, `XUI_ENABLE_FAIL2BAN=true`, `XUI_DB_TYPE=`, `XUI_DB_DSN=` | | Ports (host) | `54321:54321` (не используется панелью — внутри панель на 2053, можно убрать) | -| **Точка правки Xray-конфига** | таблица `settings` → ключ **`xrayTemplateConfig`** в `/etc/x-ui/x-ui.db`. **⚠️ `/app/bin/config.json` — генерируемый, не править (перезапишется).** `sqlite3` внутри контейнера отсутствует — работать хостовым бинарём или `alpine`-контейнером | +| **Compose** | `/mnt/RED_2TB/docker/xray-admin/docker-compose.yml` — **✅ ВОССТАНОВЛЕН 2026-09-15** из `docker inspect` (был утрачен 2026-09-01, см. [[family/plans/reverse-xray-3xui-kraken]]). `docker compose config` валиден, `docker compose ps` распознаёт контейнер. | + +> 🔴 **ПИТФОЛЛ `xray-admin` (bind-mount `/etc-x-ui`):** правка/удаление файлов внутри контейнера в пути `/etc/x-ui/` **бьёт прямо по хосту** — это тот же самый каталог. Именно так 2026-09-01 был уничтожен `docker-compose.yml` (`docker exec xray-admin rm -f /etc/x-ui/docker-compose.yml`). Никогда не делать `rm`/`mv` в `/etc/x-ui` изнутри контейнера. Файлы складывать на хост через `docker run --rm -v /tmp:/src -v /mnt/RED_2TB/docker/xray-admin:/dst alpine cp …`. + +> 🔴 **ПИТФОЛЛ правки SQLite `x-ui.db` (WAL):** база работает в WAL-режиме. Нельзя копировать только `.db` и класть рядом со старыми `-wal`/`-shm` → `database disk image is malformed`. Правильно: `docker stop xray-admin` → `rm -f x-ui.db-wal x-ui.db-shm` → SQL напрямую в `/data/x-ui.db` → `chown 950:root` → `docker start`. Лучше всего — вообще править через панель. + +> 🔴 **ПИТФОЛЛ ручного `INSERT` в таблицу `clients`:** SQLite ставит `NULL` в колонки, не указанные в `INSERT`. 3x-ui/Xray при генерации `/app/bin/config.json` **молча выкидывает** клиента с `auth=NULL`/`reverse=NULL` — панель его показывает, в конфиге его нет, в логах ни слова. Заполнять все текстовые колонки (`auth`, `reverse`, `flow`, `password`, `group_name`) пустой строкой `''`. + +> ⚠️ **Панель на `/login` отдаёт 403** — это не поломка и не отсутствие доступа, просто другой путь у API. Логина/пароля панели у агента нет и подбирать не нужно: всё нужное читается через `docker exec`/SQLite. + +> 📌 **Как генерируется `config.json`:** 3x-ui собирает `/app/bin/config.json` из БД. **Outbound'ы и routing берутся из `xrayTemplateConfig`** (таблица `settings`, ключ `xrayTemplateConfig` — правится целиком), **а список клиентов — из `inbounds.settings` + таблицы `clients`**. Правка БД требует `docker restart xray-admin` (или «Restart Xray» в панели) — иначе Xray работает на старом файле. +> +> **Точка правки Xray-конфига:** таблица `settings` → ключ **`xrayTemplateConfig`** в `/etc/x-ui/x-ui.db`. **⚠️ `/app/bin/config.json` — генерируемый, не править (перезапишется).** `sqlite3` внутри контейнера отсутствует — работать хостовым бинарём или `alpine`-контейнером. **Статус (2026-09-02):** контейнер **Up**, панель HTTP 200. Reverse portal развёрнут отдельным контейнером `xray-reverse-portal`; per-user egress работает end-to-end. @@ -471,12 +483,14 @@ arr, caddy, cups, filebrowser, gitea, hermes, immich, inpx-web, inpxer, library, |---|---|---|---| | `user1` | `68c5cy5n5ui138yh` | `https://vpn-panel.mallexxx.duckdns.org/sub/68c5cy5n5ui138yh` | TrueNAS `90.189.160.148` | | `kraken-user` | `f43074a029dc656e` | `https://vpn-panel.mallexxx.duckdns.org/sub/f43074a029dc656e` | Kraken `92.62.70.41` | +| `vless-space` | `24df9391356b48ff` | `https://vpn-panel.mallexxx.duckdns.org/sub/24df9391356b48ff` | подписка `profilegrid.net` (10 серверов, `space-balancer` leastPing) — ⏳ клиент в БД есть, в `config.json` пока нет | - Sub-сервер отдаёт **base64-список** `vless://…` (проверено: HTTP 200, `text/plain`). Пример тела: `vless://ce320965-…@vpn.mallexxx.duckdns.org:443?encryption=none&host=vpn.mallexxx.duckdns.org&path=%2Fvless&security=tls&type=ws#vless-ws-user1`. - **`/sub/` отдаётся БЕЗ авторизации** — любой, кто знает `subId`, получает рабочий ключ. Открытый вопрос безопасности. +- **Авто-обновление подписки — функция GUI-клиента** (Happ / v2rayN / NekoBox / sing-box: «Add subscription» + auto-update interval). Xray в docker (и `vless-proxy`, и HA-аддон) подписки **не умеет** — там только статический `config.json`; «auto» реализуется внешним cron-скриптом, который тянет `/sub/` → генерит `config.json` → рестартит контейнер. - Панель: `/login` с `admin/admin` → **403** (не подбирать; креды не записаны). -**`vless-space` — подготовлен, НЕ применён (2026-09-15):** третий клиент, чей egress идёт через внешнюю Xray-подписку `profilegrid.net` (10 серверов, `leastPing`). `user1` и `kraken-user` не трогаются. Артефакты собраны и проверены в песочнице, применение в живую БД не выполнено. Полный разбор — [[personal/tech/xray-outbound-subscription-3xui]]. +**`vless-space` — SQL применён, клиент не в конфиге (2026-09-15):** третий клиент, чей egress идёт через внешнюю Xray-подписку `profilegrid.net` (10 серверов, `leastPing`). `user1` и `kraken-user` **не тронуты** — подтверждено фактом. Шаблон применился (13 outbound + `space-balancer`), клиент есть во всех таблицах БД, но в `config.json` не попадает из-за `auth`/`reverse` = `NULL`. Исправление — 4 команды. Полный разбор — [[personal/tech/vless-space-subscription-egress]]. > ⚠️ База `x-ui.db` была **уже настроена** под эту Caddy-интеграцию (inbound vless-ws:10095, subDomain vpn-panel), поэтому панель заработала «из коробки». Бэкап базы/Caddyfile до изменений: `/mnt/RED_2TB/docker/backups/reverse-xray-3xui-20260901-113625/`. diff --git a/family/plans/reverse-xray-3xui-kraken.md b/family/plans/reverse-xray-3xui-kraken.md index 0abb31e4..518f3c3e 100644 --- a/family/plans/reverse-xray-3xui-kraken.md +++ b/family/plans/reverse-xray-3xui-kraken.md @@ -41,6 +41,56 @@ docker exec xray-admin rm -f /etc/x-ui/docker-compose.yml **Восстановление:** только из `docker inspect` (см. ниже). Параметры: образ `ghcr.io/mhsanaei/3x-ui:latest`, `container_name: xray-admin`, `hostname: xray-admin`, `restart: unless-stopped`, `TZ=Asia/Novosibirsk`, `PUID=950`, `PGID=950`, volume `/mnt/RED_2TB/docker/xray-admin:/etc/x-ui`, `ports: 54321:54321`, сеть `caddy_default` (external). Эквивалент: `docker run` с теми же флагами. +### ✅ ВОССТАНОВЛЕНО 2026-09-15 (факт) + +Compose-файл воссоздан и лежит на месте: `/mnt/RED_2TB/docker/xray-admin/docker-compose.yml` (536 б, владелец `950:root`). + +**Содержимое (полное):** + +```yaml +services: + xray-admin: + image: ghcr.io/mhsanaei/3x-ui:latest + container_name: xray-admin + hostname: xray-admin + restart: unless-stopped + environment: + - TZ=Asia/Novosibirsk + - PUID=950 + - PGID=950 + - XUI_IN_DOCKER=true + - XUI_MAIN_FOLDER=/app + - XUI_ENABLE_FAIL2BAN=true + - XUI_DB_TYPE= + - XUI_DB_DSN= + volumes: + - /mnt/RED_2TB/docker/xray-admin:/etc/x-ui + ports: + - "54321:54321" + networks: + - caddy_default + +networks: + caddy_default: + external: true +``` + +**Проверка после восстановления:** +- `docker compose config` → валиден, без ошибок +- `docker compose ps` → контейнер распознан как service `xray-admin` +- Все 6 env-переменных сверены с живым контейнером через `docker inspect` (`XUI_IN_DOCKER`, `XUI_MAIN_FOLDER`, `XUI_ENABLE_FAIL2BAN`, `XUI_DB_TYPE`, `XUI_DB_DSN` + `TZ`/`PUID`/`PGID`) + +**Как заливать (питфолл):** файл кладётся на хост **через `docker run -v`**, а **не** `scp` в смонтированную папку с последующей правкой изнутри контейнера — иначе повторяется исходный инцидент. Использованный приём: + +```bash +scp docker-compose.yml truenas_admin@mallexxx.duckdns.org:/tmp/ +ssh truenas_admin@mallexxx.duckdns.org ' +docker run --rm -v /tmp:/src -v /mnt/RED_2TB/docker/xray-admin:/dst alpine \ + sh -c "cp /src/docker-compose.yml /dst/docker-compose.yml && chown 950:root /dst/docker-compose.yml"' +``` + +**Локальная копия на Mac:** `~/tmp-xray-space/docker-compose.yml` + ## Архитектура ```text diff --git a/personal/tech/vless-space-subscription-egress.md b/personal/tech/vless-space-subscription-egress.md index f9e26ea3..9f636c2a 100644 --- a/personal/tech/vless-space-subscription-egress.md +++ b/personal/tech/vless-space-subscription-egress.md @@ -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`, получит ключ. Кандидат на включение подписки-по-токену в панели (не сделано). ## Что НЕ сделано / следующие шаги -- [ ] Применить `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`). Не начато. ## Связанные заметки