From 05464f090a30233340853d2c30a8d9323f760bfa Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 15 Sep 2026 16:13:51 +0600 Subject: [PATCH] [2026-09-15] eagle: family/how-to/truenas-infrastructure.md personal/tech/vless-space-subscription-egress.md personal/tech/xray-outbound-subscription-3xui.md personal/tech/xray-reverse-tunnel-kraken-truenas.md --- family/how-to/truenas-infrastructure.md | 4 +- .../tech/vless-space-subscription-egress.md | 56 +++++++++- .../tech/xray-outbound-subscription-3xui.md | 102 ++++++++++++++++-- .../xray-reverse-tunnel-kraken-truenas.md | 37 +++++++ 4 files changed, 187 insertions(+), 12 deletions(-) diff --git a/family/how-to/truenas-infrastructure.md b/family/how-to/truenas-infrastructure.md index 0466a15d..eb820c10 100644 --- a/family/how-to/truenas-infrastructure.md +++ b/family/how-to/truenas-infrastructure.md @@ -13,7 +13,9 @@ > - **⚠️ «Камера на 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 (**ФИНАЛ попытки 7: `vless-space` НЕ СОЗДАН, БД ОТКАЧЕНА Alex'ом, система в исходном состоянии** — проверено: контейнер Up, панель/`vpn.mallexxx`/обе подписки HTTP 200, клиенты `user1`+`kraken-user`, outbound'ов 3). **Главный вывод: 3x-ui НЕЛЬЗЯ править снаружи работающего контейнера.** Семь подходов (SQL в копию БД, прямой SQL, `auth`/`reverse`, `security`, `password`, инбаунд-в-шаблоне, шаблон-без-инбаунда) — все отбились, при том что БД каждый раз была полностью корректна (`integrity ok`, типы совпадают, шаблон валиден, живой Xray давал `Configuration OK`). Работает только `settings.xrayTemplateConfig` (outbound'ы/правила/балансировщики — **13 outbound + `space-balancer` leastPing применились**), **клиенты инбаунда — только через панель/API-токен**. 🔴 **ХАРД-ВЫВОД: не тратить попытки на правку клиентов 3x-ui через SQLite — сразу просить доступ к панели.** 🔴 **НОВЫЕ ПИТФОЛЛЫ:** (1) **правку SQLite делать ЛОКАЛЬНО на Mac** (`scp` базы → `sqlite3`/`jq`/`integrity_check` → валидация живым `xray -test` → заливка готового файла) — установка Alex, гонка кавычек по SSH дважды ломала команды; (2) команды для Alex давать **без `ssh truenas_admin@… '…'`-обёртки** и **без `sleep N`** (Alex, 2026-09-15: «ты заебал свой sleep 8 пихать»); (3) 3x-ui держит БД открытой — при внешней правке `x-ui.db` показывает старую дату; (4) 🔴 **инбаунд ВНУТРИ `xrayTemplateConfig` ломает своих клиентов** — 3x-ui мёржит шаблон с таблицей `inbounds`, шаблонная версия того же тега перебивает панельную (так отвалился `kraken-user`); в шаблоне — только outbound'ы/правила/балансировщик. **✅ Compose-файл `xray-admin` ВОССТАНОВЛЕН** из `docker inspect` (это единственное, что пережило откат). Полный разбор — [[personal/tech/vless-space-subscription-egress]]. Ранее 2026-09-15 (ночь-4: попытка 2 — SQL применён, БД корректна, но Xray клиента не видит; ложный «корень» `auth`/`reverse`=`NULL` — **опровергнут**; ранее ночь-3: попытка 1 провалилась с `database disk image is malformed` — SQL применялся к копии `.db` без `-wal`/`-shm`. 🔴 **ПИТФОЛЛ:** для WAL-базы нельзя копировать только `.db`. Ранее ночь-2: артефакты собраны и проверены в песочнице. Ранее 2026-09-15 (вечер: черновой план `vless-space`, подписка проверена; subscription-канал 3x-ui: ссылки `/sub/` работают, base64 vless-список). Ранее: 2026-09-02 (vpn.mallexxx:443 = РАБОЧИЙ Xray... [truncated] — провенено: контейнер Up, панель/`vpn.mallexxx`/обе подписки HTTP 200, клиенты `user1`+`kraken-user`, outbound'ов 3). **Главный вывод: 3x-ui НЕЛЬЗЯ править снаружи работающего контейнера.** Пять подходов (SQL в копию БД, прямой SQL, `auth`/`reverse`, `security`, `password`) — все отбились, при том что БД каждый раз была полностью корректна (`integrity ok`, типы совпадают, шаблон валиден, живой Xray давал `Configuration OK`). Работает только `settings.xrayTemplateConfig` (outbound'ы/правила/балансировщики — **13 outbound + `space-balancer` leastPing применились**), **клиенты инбаунда — только через панель/API-токен**. 🔴 **ХАРД-ВЫВОД: не тратить попытки на правку клиентов 3x-ui через SQLite — сразу просить доступ к панели.** 🔴 **НОВЫЕ ПИТФОЛЛЫ:** (1) **правку SQLite делать ЛОКАЛЬНО на Mac** (`scp` базы → `sqlite3`/`jq`/`integrity_check` → валидация живым `xray -test` → заливка готового файла) — установка Alex, гонка кавычек по SSH дважды ломала команды; (2) команды для Alex давать **без `ssh truenas_admin@… '…'`-обёртки**; (3) 3x-ui держит БД открытой — при внешней правке `x-ui.db` показывает старую дату. **✅ Compose-файл `xray-admin` ВОССТАНОВЛЕН** из `docker inspect` (это единственное, что пережило откат). Полный разбор — [[personal/tech/vless-space-subscription-egress]]. Ранее 2026-09-15 (ночь-4: попытка 2 — SQL применён, БД корректна, но Xray клиента не видит; ложный «корень» `auth`/`reverse`=`NULL` — **опровергнут**; ранее ночь-3: попытка 1 провалилась с `database disk image is malformed` — SQL применялся к копии `.db` без `-wal`/`-shm`. 🔴 **ПИТФОЛЛ:** для WAL-базы нельзя копировать только `.db`. Ранее ночь-2: артефакты собраны и проверены в песочнице. Ранее 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-15 (**ВЕЧЕР — `vless-space` СОЗДАН И ЗАЛИТ, `xui_v7.db` применена успешно.** Проверено фактом: `in-10095-tcp` clients = `user1,kraken-user,vless-space` одной строкой (без дубля, **без порта 10096**), outbounds 13, подписка `/sub/24df9391356b48ff` **HTTP 200** — QR появился впервые за 7 попыток, `kraken-user` и `user1` **не пострадали**. 🔴 **ЭТО ОПРОВЕРГАЕТ прежний хард-вывод «3x-ui нельзя править снаружи».** Настоящий барьер был один — **инбаунд внутри `xrayTemplateConfig`**; как только в шаблоне остаётся **только `api`**, SQLite-путь работает штатно. ⚠️ **Остаточная проблема (не в клиенте):** egress `vless-space` **не идёт** — `app/dispatcher: non existing outTag: space-balancer`, туннель рвётся `websocket: close 1000`. 🔴🔴 **КОРЕНЬ НАЙДЕН И ДОКАЗАН A/B: `leastPing` НЕ РАБОТАЕТ в Xray 26.x** — балансировщик не регистрируется; рабочая стратегия — **`leastLoad`** (с `observatory`): лог даёт `app/observatory: the outbound space-01 is alive:0.249334909` + `taking detour [space-02]`. Собран `xui_v7_load.db` (md5 `855ff3ac2d2319b17b20fe5c788ddc59`, `leastPing`→`leastLoad`, integrity `ok`) — **залит не был**, это следующий шаг. ⚠️ **`xray -test` печатает `Configuration OK` и для битого `leastPing`** — семантику маршрутизации ловит только рантайм-лог. **Команды для Alex:** плоские однострочники, **без `ssh … '…'`-обёртки**, **без `sleep N`**, **без кириллицы в bash**. **✅ Compose-файл `xray-admin` ВОССТАНОВЛЕН** из `docker inspect`. Полный разбор — [[personal/tech/vless-space-subscription-egress]] / [[personal/tech/xray-outbound-subscription-3xui]]. +> +> Обновлено (ранее): 2026-09-15 (**ФИНАЛ попытки 7: `vless-space` НЕ СОЗДАН, БД ОТКАЧЕНА Alex'ом, система в исходном состоянии** — проверено: контейнер Up, панель/`vpn.mallexxx`/обе подписки HTTP 200, клиенты `user1`+`kraken-user`, outbound'ов 3). **Главный вывод: 3x-ui НЕЛЬЗЯ править снаружи работающего контейнера.** Семь подходов (SQL в копию БД, прямой SQL, `auth`/`reverse`, `security`, `password`, инбаунд-в-шаблоне, шаблон-без-инбаунда) — все отбились, при том что БД каждый раз была полностью корректна (`integrity ok`, типы совпадают, шаблон валиден, живой Xray давал `Configuration OK`). Работает только `settings.xrayTemplateConfig` (outbound'ы/правила/балансировщики — **13 outbound + `space-balancer` leastPing применились**), **клиенты инбаунда — только через панель/API-токен**. 🔴 **ХАРД-ВЫВОД: не тратить попытки на правку клиентов 3x-ui через SQLite — сразу просить доступ к панели.** 🔴 **НОВЫЕ ПИТФОЛЛЫ:** (1) **правку SQLite делать ЛОКАЛЬНО на Mac** (`scp` базы → `sqlite3`/`jq`/`integrity_check` → валидация живым `xray -test` → заливка готового файла) — установка Alex, гонка кавычек по SSH дважды ломала команды; (2) команды для Alex давать **без `ssh truenas_admin@… '…'`-обёртки** и **без `sleep N`** (Alex, 2026-09-15: «ты заебал свой sleep 8 пихать»); (3) 3x-ui держит БД открытой — при внешней правке `x-ui.db` показывает старую дату; (4) 🔴 **инбаунд ВНУТРИ `xrayTemplateConfig` ломает своих клиентов** — 3x-ui мёржит шаблон с таблицей `inbounds`, шаблонная версия того же тега перебивает панельную (так отвалился `kraken-user`); в шаблоне — только outbound'ы/правила/балансировщик. **✅ Compose-файл `xray-admin` ВОССТАНОВЛЕН** из `docker inspect` (это единственное, что пережило откат). Полный разбор — [[personal/tech/vless-space-subscription-egress]]. Ранее 2026-09-15 (ночь-4: попытка 2 — SQL применён, БД корректна, но Xray клиента не видит; ложный «корень» `auth`/`reverse`=`NULL` — **опровергнут**; ранее ночь-3: попытка 1 провалилась с `database disk image is malformed` — SQL применялся к копии `.db` без `-wal`/`-shm`. 🔴 **ПИТФОЛЛ:** для WAL-базы нельзя копировать только `.db`. Ранее ночь-2: артефакты собраны и проверены в песочнице. Ранее 2026-09-15 (вечер: черновой план `vless-space`, подписка проверена; subscription-канал 3x-ui: ссылки `/sub/` работают, base64 vless-список). Ранее: 2026-09-02 (vpn.mallexxx:443 = РАБОЧИЙ Xray... [truncated] — провенено: контейнер Up, панель/`vpn.mallexxx`/обе подписки HTTP 200, клиенты `user1`+`kraken-user`, outbound'ов 3). **Главный вывод: 3x-ui НЕЛЬЗЯ править снаружи работающего контейнера.** Пять подходов (SQL в копию БД, прямой SQL, `auth`/`reverse`, `security`, `password`) — все отбились, при том что БД каждый раз была полностью корректна (`integrity ok`, типы совпадают, шаблон валиден, живой Xray давал `Configuration OK`). Работает только `settings.xrayTemplateConfig` (outbound'ы/правила/балансировщики — **13 outbound + `space-balancer` leastPing применились**), **клиенты инбаунда — только через панель/API-токен**. 🔴 **ХАРД-ВЫВОД: не тратить попытки на правку клиентов 3x-ui через SQLite — сразу просить доступ к панели.** 🔴 **НОВЫЕ ПИТФОЛЛЫ:** (1) **правку SQLite делать ЛОКАЛЬНО на Mac** (`scp` базы → `sqlite3`/`jq`/`integrity_check` → валидация живым `xray -test` → заливка готового файла) — установка Alex, гонка кавычек по SSH дважды ломала команды; (2) команды для Alex давать **без `ssh truenas_admin@… '…'`-обёртки**; (3) 3x-ui держит БД открытой — при внешней правке `x-ui.db` показывает старую дату. **✅ Compose-файл `xray-admin` ВОССТАНОВЛЕН** из `docker inspect` (это единственное, что пережило откат). Полный разбор — [[personal/tech/vless-space-subscription-egress]]. Ранее 2026-09-15 (ночь-4: попытка 2 — SQL применён, БД корректна, но Xray клиента не видит; ложный «корень» `auth`/`reverse`=`NULL` — **опровергнут**; ранее ночь-3: попытка 1 провалилась с `database disk image is malformed` — SQL применялся к копии `.db` без `-wal`/`-shm`. 🔴 **ПИТФОЛЛ:** для WAL-базы нельзя копировать только `.db`. Ранее ночь-2: артефакты собраны и проверены в песочнице. Ранее 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]]. diff --git a/personal/tech/vless-space-subscription-egress.md b/personal/tech/vless-space-subscription-egress.md index c2b8942a..c4bf6f89 100644 --- a/personal/tech/vless-space-subscription-egress.md +++ b/personal/tech/vless-space-subscription-egress.md @@ -4,9 +4,9 @@ created: 2026-09-15 updated: 2026-09-15 type: tech namespace: personal -tags: [xray, 3x-ui, x-ui, subscription, outbound, profilegrid, truenas, space] +tags: [xray, 3x-ui, x-ui, subscription, outbound, profilegrid, truenas, space, balancer, leastLoad] confidence: high -status: reverted-blocked-7-attempts +status: applied-clients-ok-egress-rootcaused related: - "[[family/plans/reverse-xray-3xui-kraken]]" - "[[personal/tech/xray-reverse-tunnel-kraken-truenas]]" @@ -16,7 +16,25 @@ related: # `vless-space` — клиент 3x-ui, egress через внешнюю подписку -> ## ❌ ФИНАЛ 2026-09-15: ЗАДАЧА НЕ ВЫПОЛНЕНА. БД ОТКАЧЕНА. +> ## ✅ ОБНОВЛЕНО 2026-09-15 (вечер): `xui_v7.db` ЗАЛИТА И РАБОТАЕТ ЧАСТИЧНО +> +> | Проверка после заливки `xui_v7.db` | Результат | +> |---|---| +> | `in-10095-tcp` clients | ✅ `user1,kraken-user,vless-space` — **один инбаунд, без дубля, без порта 10096** | +> | outbounds | ✅ 13 | +> | balancer | ✅ `space-balancer` в конфиге | +> | подписка `/sub/24df9391356b48ff` | ✅ **HTTP 200** (QR теперь есть — впервые за 7 попыток) | +> | `kraken-user` | ✅ **не отвалился** (исправление урока попытки 6 сработало) | +> | `user1` | ✅ на месте | +> | **egress `vless-space`** | ❌ **НЕ работает** — `non existing outTag: space-balancer`, туннель рвётся `websocket: close 1000` | +> +> **🔴 Корень найден и доказан:** стратегия **`leastPing` не работает в Xray 26.x** — балансировщик не создаётся. Лечится заменой на **`leastLoad`**. Подробности — §«ГЛАВНАЯ НАХОДКА СЕССИИ» ниже. +> +> **Собран `xui_v7_load.db`** (md5 `855ff3ac2d2319b17b20fe5c788ddc59`, integrity `ok`) — `xui_v7.db` с `leastPing` → `leastLoad`. **Залит не был** (апрувы истекли). Это следующий шаг. +> +> **Ключевой вывод, который опроверг прежний пессимизм:** правка клиентов 3x-ui через SQLite **СРАБОТАЛА** в попытке 7 — клиент появился в конфиге и подписка отдала 200. Барьер был **только** в том, что инбаунд лежал внутри шаблона (урок 6). При исправленной сборке SQLite-путь рабочий. + +> ## ❌ ПРЕДЫДУЩИЙ ФИНАЛ 2026-09-15: ЗАДАЧА НЕ ВЫПОЛНЕНА. БД ОТКАЧЕНА. > > **Система возвращена в исходное состояние** (Alex восстановил из бэкапа). Проверено: `xray-admin` Up, панель HTTP 200, `vpn.mallexxx` HTTP 200, подписки `user1`/`kraken-user` HTTP 200, клиенты `user1`+`kraken-user`, outbound'ов 3. > @@ -26,9 +44,9 @@ related: > > **Единственный рабочий путь к цели:** панель 3x-ui (Inbounds → Edit → Add Client → Save → Restart Xray) **или** API-токен панели. Пароль панели (`vpn-admin`) — bcrypt, недоступен агенту; API-токен Alex не выдал. > -> **Попытка 7 (финал сессии):** собрана `xui_v7.db` — **исправлена ошибка попытки 6** (инбаунд убран из шаблона). `integrity ok`, diff от оригинала чистый. **Не залита** — Alex выполнение не подтвердил. Подробно: §«ПОПЫТКА 7». +> **Попытка 7 (финал сессии):** собрана `xui_v7.db` — **исправлена ошибка попытки 6** (инбаунд убран из шаблона). `integrity ok`, diff от оригинала чистый. Подробно: §«ПОПЫТКА 7». > -> ⛔ **Правило взаимодействия (Alex, 2026-09-15):** команды — плоскими однострочниками, **без `ssh … '…'`-обёртки**, **без `sleep N`** («ты заебал свой sleep 8 пихать»), **без `execute_code`/python**. Alex выполняет команды сам. +> ⛔ **Правило взаимодействия (Alex, 2026-09-15):** команды — плоскими однострочниками, **без `ssh … '…'`-обёртки**, **без `sleep N`** («ты заебал свой sleep 8 пихать»), **без `execute_code`/python**, **без кириллицы в bash**. Alex выполняет команды сам. ## Что хотели @@ -519,6 +537,34 @@ curl -sk -o /dev/null -w "sub: %{http_code}\n" https://vpn-panel.mallexxx.duckdn - [ ] Обновить [[family/how-to/truenas-infrastructure]] (новый клиент + балансировщик) - [ ] **Отдельная задача, НЕ начата:** `hermes-taiga` ходит через `vless-proxy`, чей outbound указывает на **мёртвый** `v.qentra.top` (VPS удалён). Переключение на живой сервер — правка 5 полей в `/mnt/RED_2TB/docker/vless-proxy/config.json` (таблица в [[personal/tech/xray-outbound-subscription-3xui]] §попутные находки). Alex спрашивал — **ответ: да, можно**. +## 🔴🔴 ГЛАВНАЯ НАХОДКА СЕССИИ (2026-09-15, позже в тот же день): `leastPing` В XRAY 26.x НЕ РАБОТАЕТ — НУЖЕН `leastLoad` + +> **Это объясняет ошибку `non existing outTag: space-balancer`.** Балансировщик в конфиге есть, Xray конфиг принимает (`Configuration OK`), но **тег не регистрируется**, и правило `vless-space-via-subscription` уходит в никуда → клиент подключается, туннель строится, трафик обрывается (`websocket: close 1000`). + +**Проверено на минимальном конфиге в докере на TrueNAS (тройной A/B):** + +| Конфиг | Результат | +|---|---| +| `strategy: leastPing` + `observatory` | ❌ `app/dispatcher: non existing outTag: space-balancer` | +| `burstObservatory` + `pingConfig` + `leastPing` | ❌ то же самое | +| **`strategy: leastLoad` + `observatory`** | ✅ **работает:** `app/observatory: the outbound space-01 is alive:0.249334909`, `app/dispatcher: taking platform initialized detour [space-02]` | + +**Вывод:** в Xray 26.x стратегия `leastPing` **устарела/несовместима** — балансировщик с ней не создаётся вообще. Рабочая стратегия — **`leastLoad`** (нативная для `observatory`). + +**Команда проверки (минимальный конфиг, доказательство):** +```bash +# outbounds: [{"tag":"space-01","protocol":"freedom"},{"tag":"space-02","protocol":"freedom"}] +# routing.balancers: [{"tag":"space-balancer","selector":["space-"],"strategy":{"type":"leastLoad"}}] +# routing.rules: [{"type":"field","inboundTag":["socks-in"],"outboundTag":"space-balancer"}] +# observatory: {"subjectSelector":["space-"],"probeUrl":"https://www.google.com/generate_204","probeInterval":"30s","enableConcurrency":true} +docker run --name probe-load -d --network host -v /tmp/probe_load.json:/etc/xray/config.json:ro ghcr.io/xtls/xray-core:latest -c /etc/xray/config.json +docker logs probe-load 2>&1 | grep -iE 'observatory|detour|non existing' +``` + +> ⚠️ **Питфолл:** `xray -test -c config.json` → `Configuration OK` **НЕ гарантирует**, что балансировщик создастся. Ошибка `non existing outTag` видна **только в рантайм-логе** при первом реальном соединении. Проверять всегда живым запросом, не только `-test`. + +> ⚠️ **Питфолл docker volume:** файл конфига, залитый через `scp` в `/tmp`, при монтировании в контейнер даёт `permission denied` — нужен `chmod 644` перед `docker run`. + ## Артефакты на Mac — итоговые (`~/tmp-xray-space/`) | Файл | Назначение | diff --git a/personal/tech/xray-outbound-subscription-3xui.md b/personal/tech/xray-outbound-subscription-3xui.md index eb3d6ec4..c61ff5fa 100644 --- a/personal/tech/xray-outbound-subscription-3xui.md +++ b/personal/tech/xray-outbound-subscription-3xui.md @@ -23,11 +23,22 @@ related: # Xray outbound из внешней подписки в 3x-ui (`vless-space`) -> ## ❌ Статус 2026-09-15 (финал): НЕ ПРИМЕНЕНО, БД ОТКАЧЕНА -> Артефакты собраны и проверены в песочнице. Применение отбилось **семь раз** — **3x-ui не даёт править себя снаружи**. БД откачена Alex'ом из бэкапа, система в исходном состоянии. Задача ждёт доступа к панели. -> Разбор контейнера и клиентов — в [[family/how-to/truenas-infrastructure]] (разделы `xray-admin`). Полная история попыток — [[personal/tech/vless-space-subscription-egress]]. +> ## ✅ ОБНОВЛЕНО 2026-09-15 (вечер): БАРЬЕР ПРЕОДОЛЁН — `xui_v7.db` ЗАЛИТА УСПЕШНО > -> ⛔ **Правило взаимодействия (Alex, 2026-09-15):** команды для Alex — **плоские однострочники без `ssh … '…'`-обёртки**, **без `sleep N`**, без `execute_code`/python. Alex выполняет их сам. +> **Прежний вывод «клиентов через 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 выполняет их сам. ## Задача @@ -46,9 +57,30 @@ related: | **Развернуть серверы подписки в обычные 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`** | Alex: «авто брать» — все 10 серверов в пул, живой выбирается сам. `observatory` **обязателен**, иначе балансировщик не знает задержек. ✅ Оба ключа приняты Xray 26.7.28. | +| ~~**`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 **одной короткой командой**, не серией вызовов. @@ -135,7 +167,65 @@ ls -la /app/bin/config.json /etc/x-ui/x-ui.db 1. **`x-ui.db` не обновлялся** — правки, применённые в 15:53/16:02/16:06, в основной файл **не попадали**. 3x-ui держит базу и пишет в `-wal`; удаление `-wal` перед правкой уничтожало актуальные данные, после правки он перезаписывал файл из своего состояния. 2. **`config.json` перегенерирован из внутренней памяти** 3x-ui, а не из файла — отсюда парадокс: **13 outbound'ов применились** (шаблон `settings` он читает), **третий клиент исчез** (список клиентов берёт из своей памяти). -> 🔴 **ВЫВОД: `inbounds` и клиентов 3x-ui через SQLite снаружи править НЕЛЬЗЯ.** Работает только `settings.xrayTemplateConfig` (outbound'ы/правила/балансировщики). Всё, что касается клиентов инбаунда, идёт **исключительно через панель** (`/panel/api/inbounds/update/:id`) — а для API нужен **API-токен**. +> 🔴 **ВЫВОД (исправлен 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. diff --git a/personal/tech/xray-reverse-tunnel-kraken-truenas.md b/personal/tech/xray-reverse-tunnel-kraken-truenas.md index 3c6892d7..5b81de98 100644 --- a/personal/tech/xray-reverse-tunnel-kraken-truenas.md +++ b/personal/tech/xray-reverse-tunnel-kraken-truenas.md @@ -264,6 +264,43 @@ docker run --rm --network caddy_default curlimages/curl:latest curl -sv --socks5 3. reverse-туннель TrueNAS↔Kraken (portal `xray-reverse-portal` + bridge на Kraken) — это про проксирование egress ЛОКАЛЬНЫХ клиентов сети TrueNAS через Kraken. НЕ связан с vpn.mallexxx. +## 🔴 2026-09-15 (вечер): KRAKEN НЕДОСТУПЕН — `kraken-user` отвалился НЕ из-за правок БД + +> **Симптом:** Alex сообщил «не работает больше `vless-ws-kraken-user`, даже из бэкапа». Логичное подозрение — мои правки БД 3x-ui. **Подозрение опровергнуто фактами.** + +**Диагностика (по порядку, все — факт):** + +| Проверка | Результат | +|---|---| +| `docker ps` на TrueNAS | `xray-reverse-portal` **Up 13 days**, `xray-admin` Up, `caddy` Up. `xray-reverse-bridge` **отсутствует** (он на Kraken) | +| порт `12345` (SOCKS) | LISTEN ✅ | +| порт `12346` (interconn) | LISTEN ✅ | +| выход через SOCKS :12345 → `api.ipify.org` | ❌ **пусто** (ни IP, ни ошибки) | +| `netstat` соединений на 12345 | много **`CLOSE_WAIT`** от `172.16.1.5` — сессии оборваны, новых нет | +| соединений от бриджа на `12346` | ❌ **НОЛЬ** (бридж не звонит) | +| логи портала | `app/dispatcher: non existing outTag: reverse-out` + `from tcp:172.16.1.5:… [local -> reverse-out]` | +| TrueNAS напрямую | `90.189.160.148` ✅ (интернет на NAS есть) | +| `ssh kraken@10.99.1.2` | ❌ **Operation timed out** | +| `ssh ssh-kraken.qentra.top` (cloudflared) | ❌ **Connection timed out during banner exchange** | +| DNS `host kraken` | ❌ **NXDOMAIN** | + +> **🔴 ВЫВОД: хост Kraken недоступен по ОБОИМ задокументированным путям** (WG-адрес `10.99.1.2` и cloudflared-туннель `ssh-kraken.qentra.top`). `kraken-user` не работает, потому что **машина Kraken выключена/недоступна**, а не из-за правок в `x-ui.db`. Совпадение по времени. + +**ВАЖНО про `non existing outTag: reverse-out`:** это **НЕ дефект конфига портала**. В reverse-схеме Xray тег `reverse-out` объявляется **не в `outbounds[]`**, а в `clients[].reverse.tag` инбаунда `interconn` — и создаётся **только когда бридж подключён**. Ошибка = бридж не подключён. Конфиг портала (`/mnt/RED_2TB/docker/reverse-portal/config.json`, 1287 б, бинд-маунт `:ro`) **корректен**, проверено 2026-09-15. + +> ⚠️ **Сделано по ходу диагностики (требует внимания):** выполнен `docker restart xray-reverse-portal` — портал перезапущен, но `CLOSE_WAIT` ушли, а новых соединений от Kraken **не появилось** (ожидаемо: машины нет). Портал после рестарта — Up, оба порта LISTEN. **Рестарт портала сам по себе проблему не решает** — она на стороне Kraken. + +**Что проверять, когда Kraken вернётся:** +```bash +# 1) канал поднялся? +docker exec xray-reverse-portal sh -c 'netstat -an' | grep 12346 +# 2) output жив? +curl -s --max-time 20 --socks5-hostname 127.0.0.1:12345 https://api.ipify.org +# ожидаем: 92.62.70.41 +``` + +**Питфолл диагностики:** `curl --socks5-hostname 127.0.0.1:12345` на TrueNAS **не** проверяет туннель, если портал сам не может выйти — надо сравнивать с `curl` напрямую (`90.189.160.148`), иначе не отличить «портал сломан» от «Kraken недоступен». + ## ❌ ИСТОРИЯ ДИАГНОСТИКИ 2026-09-02: downgrade сам по себе не помог > ⚠️ ВАЖНО: вопреки секции «ИСТИННЫЙ КОРЕНЬ #6242» выше (которая была гипотезой, ещё не проверенной полностью), **полный downgrade обеих сторон до Xray 26.4.25 payload НЕ починил**. Это зафиксировано здесь как фактический итог.