282 lines
29 KiB
Markdown
282 lines
29 KiB
Markdown
# Reverse Xray (3x-ui) — TrueNAS ↔ Kraken
|
||
|
||
> Создано: 2026-09-01. Цель: проксировать трафик локальных клиентов (сеть TrueNAS 192.168.2.x) через TrueNAS → Kraken → интернет. **Kraken = точка выхода (exit node).** TrueNAS = bridge/контроллер.
|
||
|
||
## Архитектура
|
||
|
||
```text
|
||
ЛОКАЛЬНЫЕ КЛИЕНТЫ (192.168.2.x)
|
||
│ подключаются к прокси TrueNAS:1080/1081 (SOCKS/HTTP) ИЛИ на поддомен
|
||
▼
|
||
TRUENAS = 3x-ui (Xray-сервер, bridge/контроллер) — белый IP, mallexxx.duckdns.org
|
||
│ принимает клиентский трафик; reverse-канал к Kraken
|
||
▼ ▲
|
||
KRAKEN = Xray-клиент (outbound reverse) + exit node — держит исходящий канал к TrueNAS
|
||
▼
|
||
интернет
|
||
```
|
||
|
||
- **TrueNAS** (3x-ui): принимает от локальных клиентов + держит reverse-вход, куда подключается Kraken.
|
||
- **Kraken**: сам **инициирует** канал к TrueNAS (за NAT, не может принимать), получает по нему трафик клиентов, отпускает в интернет.
|
||
- Кра́кен за NAT ⇒ направление канала **от Kraken к TrueNAS** (Xray reverse).
|
||
|
||
## Ключевые факты (прояснены)
|
||
|
||
1. **На 443 у TrueNAS — Caddy** (reverso-proxy, валидные LE-серты), НЕ Xray REALITY. Хостовый маппинг: `0.0.0.0:8443→443` (контейнер), `2019` (admin), `8088→80`.
|
||
2. **Xray на TrueNAS** раньше был задуман как 3x-ui:
|
||
- База `/mnt/RED_2TB/docker/xray-admin/x-ui.db` (3x-ui), inbound `vless-ws` port `10095`, tag `in-10095-tcp`, path `/vless`, host `vpn.mallexxx.duckdns.org`, protocol vless.
|
||
- Композ-файла в `xray-admin/` нет; контейнер НЕ запущен.
|
||
3. **Caddyfile** уже проксирует (мёртвые ссылки на `xray-admin`):
|
||
- `vpn.mallexxx.duckdns.org` → `@ws path /vless` → `xray-admin:10095`
|
||
- `vpn-panel.mallexxx.duckdns.org` → `xray-admin:443` / `xray-admin:2053` (path /sub/*)
|
||
- Сертификаты для этих поддоменов уже выданы (DNS на TrueNAS IP).
|
||
4. **`vless-proxy`** (teddysun/xray) на TrueNAS — КЛИЕНТ: слушает 1080/1081 (SOCKS/HTTP), outbound на мёртвый `v.qentra.top:443` (VPS удалён). Используется Hermes-Taiga.
|
||
5. **VPS qentra.top (91.207.28.205) УДАЛЁН.** Вся старая VLESS+REALITY инфраструктура на нём недоступна.
|
||
6. Открытые порты TrueNAS наружу: **22, 443** (8443 ведёт внутрь контейнера Caddy:443 → но Caddy обрабатывает HTTPS-домены).
|
||
|
||
## Образ 3x-ui
|
||
|
||
- Официальный: `ghcr.io/mhsanaei/3x-ui:latest`
|
||
- Контейнер должен называться **`xray-admin`** (как в Caddyfile) и быть в сети **`caddy_default`** (чтобы Caddy резолвил имя).
|
||
- Volume: `/mnt/RED_2TB/docker/xray-admin:/etc/x-ui` (там лежит готовая `x-ui.db`).
|
||
- Порт панели: 54321 (web UI, через Caddy поддомен `vpn-panel.mallexxx.duckdns.org`).
|
||
- VLESS inbound 10095 принимается извне через Caddy `vpn.mallexxx.duckdns.org/vless` (WS), НО для reverse к Kraken нужен подход через панель.
|
||
|
||
## Композ-файл
|
||
|
||
Файл: `/mnt/RED_2TB/docker/xray-admin/docker-compose.yml`
|
||
|
||
```yaml
|
||
services:
|
||
xray-admin:
|
||
image: ghcr.io/mhsanaei/3x-ui:latest
|
||
container_name: xray-admin
|
||
restart: unless-stopped
|
||
volumes:
|
||
- /mnt/RED_2TB/docker/xray-admin:/etc/x-ui
|
||
environment:
|
||
- XRAY_VMESS_AEAD_FORCED=false
|
||
networks:
|
||
- caddy_default
|
||
ports:
|
||
- "54321:54321" # 3x-ui панель (web UI)
|
||
|
||
networks:
|
||
caddy_default:
|
||
external: true
|
||
```
|
||
|
||
⚠️ ПОРТЫ 10095 и 2053/443 НЕ пробрасывать на host отдельно — Caddy стоит перед 443 и маршрутизирует /vless → xray-admin:10095 по имени в общей сети. Если нужно наружу снаружи (не через Caddy), проброс отдельный — обсудить.
|
||
|
||
## Сеть: reverse к Kraken
|
||
|
||
`xray-admin` должен быть в сети `caddy_default` — там же Caddy. Проверено: caddy_default содержит caddy, syncthing, webdav, gitea.
|
||
|
||
## Reverse-схема (Xray portal/bridge) — 2026-09-01, спроектировано
|
||
|
||
Целевое: локальные клиенты сети TrueNAS (192.168.2.x) выходят в интернет через Kraken.
|
||
|
||
Роли Xray reverse (по эталону Xray-examples/ReverseProxy):
|
||
- **Kraken = BRIDGE** (reverse bridges) — держит исходящий канал к TrueNAS, публикует "интернет-выход" (freedom).
|
||
- **TrueNAS = PORTAL** (reverse portals) — принимает от локальных клиентов (external-inbound) и пересылает в Kraken по reverse-каналу (interconn).
|
||
|
||
Конкретные порты/транспорт:
|
||
| Компонент | Хост | Контейнер/роль | Транспорт | Вход/выход |
|
||
|---|---|---|---|---|
|
||
| portal | TrueNAS | `xray-reverse-portal` | VLESS-WS | interconn `:12346` → Caddy path `/rvs`; external `:12345` для клиентов сети |
|
||
| bridge | Kraken | `xray-reverse-bridge` | VLESS-WS | interconn → `vpn.mallexxx.duckdns.org` path `/rvs`; свобода → интернет |
|
||
|
||
Транспорт: VLESS + WebSocket (т.к. снаружи TrueNAS только 443 через Caddy; WS подходит для reverse поверх outbound). Отдельный путь Caddy `/rvs` (не `/vless` 3x-ui) → `xray-reverse-portal:12346`, чтобы не смешивать с inbound 3x-ui.
|
||
|
||
Caddy правка: `vpn.mallexxx.duckdns.org` добавить маршрут `@rvs path /rvs` → `reverse_proxy @rvs xray-reverse-portal:12346`.
|
||
|
||
## Статус деплоя (2026-09-01)
|
||
|
||
✅ **3x-ui развёрнут на TrueNAS и работает:**
|
||
- Контейнер `xray-admin` (ghcr.io/mhsanaei/3x-ui:latest, **3.7.0**, Xray 26.7.28) в сети `caddy_default`, volume `/mnt/RED_2TB/docker/xray-admin:/etc/x-ui`.
|
||
- Панель web UI: **`https://vpn-panel.mallexxx.duckdns.org/` → HTTP 200** (Caddy резолвит `xray-admin:2053`).
|
||
- Sub-сервер: `[::]:443` (путь /sub), панель `[::]:2053` — как в Caddyfile.
|
||
- Inbound: `vless-ws` port **10095**, tag `in-10095-tcp`, path `/vless`, host `vpn.mallexxx.duckdns.org` (Caddy path /vless → xray-admin:10095).
|
||
- 3x-ui **поддерживает reverse** (в бинарнике `clientReverseTags`) — настройка через панель.
|
||
- Бэкап: `/mnt/RED_2TB/docker/backups/reverse-xray-3xui-20260901-113625/` (Caddyfile + x-ui.db + docker-inventory).
|
||
|
||
### Фактически развёрнутый compose (deployed на TrueNAS)
|
||
```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
|
||
volumes:
|
||
- /mnt/RED_2TB/docker/xray-admin:/etc/x-ui
|
||
ports:
|
||
- "54321:54321" # 3x-ui web UI (внутри панель реально на 2053)
|
||
networks:
|
||
- caddy_default
|
||
networks:
|
||
caddy_default:
|
||
external: true
|
||
```
|
||
> Черновик выше (секция «Композ-файл») — предварительный; фактический файл на TrueNAS содержит `hostname`, `TZ`, `PUID/PGID`. Панель внутри слушает **2053** (не 54321) — это то, что Caddyfile проксирует через `vpn-panel`. Хостовый 54321-проброс не используется панелью (панель = 2053), можно убрать.
|
||
|
||
**Следующий шаг:** ✅ Выполнено — reverse развёрнут (см. ниже). Основной doc архитектуры: `personal/tech/xray-reverse-tunnel-kraken-truenas.md`.
|
||
|
||
## Reverse деплой — ПОЛНЫЙ СТАТУС (2026-09-01) — РЕШЕН переезд на TCP+REALITY
|
||
|
||
### 🔀 РЕШЕНИЕ: WS → прямой TCP+REALITY (принято в сессии 2026-09-01)
|
||
WS-вариант reverse НЕ пропускал payload (curl через SOCKS → 000; portal логировал `accepted tcp:... [local -> reverse-out]`, но bridge не получал). Официальный Xray-reverse пример = прямой TCP + flow `xtls-rprx-vision`. Alex согласовал проброс порта → переводим reverse канал Kraken↔TrueNAS на **прямой TCP+REALITY** порт 12346.
|
||
|
||
**REALITY-ключи (для interconn :12346):** server PrivateKey `0JTjeirfviDqCr63wSnisvU7DV6SpR9_9V2l_EUHmkk`; server PublicKey (для bridge) `GhsphQLT_0fwOvK45MHeAgG3sBQsFtw7lQfUIbrLMQU`; shortId `1451ef281caf5905`; serverName/SNI `www.cloudflare.com`; flow `xtls-rprx-vision`.
|
||
|
||
**⚠️ Pitfall Xray 26.x:** VLESS без TLS/шифрования к публичному адресу ЗАПРЕЩЁН (`vless without TLS or other encryption is prohibited unless the server address is a private IP`). → bridge TCP-VLESS обязателен с REALITY.
|
||
|
||
Обновлённые конфиги (оба `Configuration OK` при `xray run -test`):
|
||
- **portal** `/mnt/RED_2TB/docker/reverse-portal/config.json`: interconn `:12346` VLESS-TCP reality (dest www.cloudflare.com:443, client a81c3179..., flow xtls-rprx-vision, reverse tag reverse-out); local `:12345` SOCKS; routing local→reverse-out.
|
||
- **bridge** `/home/kraken/xray-reverse/config.json`: outbound `conn` VLESS simplified → mallexxx.duckdns.org:12346, flow, reality (publicKey=server PublicKey, shortId, serverName www.cloudflare.com, fingerprint random), reverse tag reverse-in; direct=freedom; routing reverse-in→direct.
|
||
- **compose portal**: добавлен проброс `- "12346:12346"`.
|
||
|
||
### Доступ к роутеру OpenWrt (TrueNAS сети) — из `truenas-access`
|
||
- OpenWrt = main router сети 192.168.2.0/24, SSH `root@192.168.2.2`, пароль root **`1316261`**. Доступ с TrueNAS через docker+sshpass.
|
||
- ✅ Бэкап firewall OpenWrt: `/mnt/RED_2TB/docker/backups/openwrt-firewall-20260901-130558.txt` (212 строк).
|
||
- Порт-форвардинг: `uci add firewall redirect` ... `src_dport` → `dest_ip=192.168.2.197` `dest_port` `target=DNAT`; `/etc/init.d/firewall reload`.
|
||
|
||
### ✅ ВНЕДРЕНО (2026-09-01, после согласия Alex) — TCP+REALITY переход выполнен
|
||
Все 4 шага перехода на TCP+REALITY **ВЫПОЛНЕНЫ**:
|
||
1. ✅ Пересоздан `xray-reverse-portal` на TrueNAS (compose `12345:12345` + `12346:12346`, config REALITY TCP). Проверено: `ss -tlnp` → `0.0.0.0:12346 LISTEN`.
|
||
2. ✅ OpenWrt DNAT добавлен: redirect `xray-reverse-12346`, `src_dport=12346` → `dest_ip=192.168.2.197:12346`, `target=DNAT`, `/etc/init.d/firewall reload` → `DNAT_ADDED`. Проверено: `mallexxx.duckdns.org:12346` → **OPEN** извне.
|
||
3. ✅ Пересоздан `xray-reverse-bridge` на Kraken (config REALITY TCP). Reverse-канал снова ESTABLISHED: Kraken `172.24.0.2 → 90.189.160.148:12346 ESTABLISHED` + лог `common/mux: received request for udp:reverse:0`.
|
||
4. ❌ **Тест payload НЕ прошёл даже на TCP+REALITY**: `curl --socks5 127.0.0.1:12345 http://api.ipify.org` на TrueNAS → **всё ещё `code=000`** (прямой curl → 200). Portal: `accepted tcp:8.6.112.0:80 [local -> reverse-out]`, но bridge НЕ логирует приход TCP-payload (`no accepted/received` в `reverse-in`).
|
||
|
||
### ❌ Дополнительно пробовано: снятие `flow: xtls-rprx-vision`
|
||
- Убрал `flow: xtls-rprx-vision` с обеих сторон (portal interconn client + bridge conn outbound), пересоздал оба контейнера (оба `Configuration OK`).
|
||
- Результат: **по-прежнему `code=000`**. Reverse-канал устанавливается (`udp:reverse:0`), TCP-payload до bridge не доходит.
|
||
- **Вывод: проблема НЕ в `flow` и НЕ в WS-транспорте — даже на «каноничном» TCP+REALITY payload между portal-reverse-out и bridge-reverse-in не передаётся.** Ранее выдвинутая гипотеза (WS не пропускает reverse-payload) **опровергнута** переходом на TCP.
|
||
|
||
### 🔑 КОРЕНЬ ПРОБЛЕМЫ НАЙДЕН (2026-09-01, интернет-поиск) — issue XTLS/Xray-core #6612
|
||
**Симптомы точно совпадают с #6612:** канал reverse устанавливается (`udp:reverse:0`), но TCP-payload не проходит; portal логирует `accepted tcp:... -> reverse-out`, bridge НЕ получает входящих reverse-in; curl → 000.
|
||
**Причина:** с **Xray v26.5+** у outbound `freedom`/`direct` дефолтная политика безопасности **блокирует VLESS Reverse payload**, пока не задан явный `finalRules`. Reverse-канал при этом живёт — «выглядит подключено», но payload молча дропается.
|
||
**Фикс (bridge, место egress reverse-in→интернет):**
|
||
```json
|
||
{ "protocol": "freedom", "tag": "direct",
|
||
"settings": { "domainStrategy": "AsIs", "finalRules": [ { "action": "allow" } ] } }
|
||
```
|
||
**Ссылки:** #6612 (фикс), #6027 (корень — finalRules у Direct), docs freedom, 3x-ui #4782, #2664 (flow vision на bridge+REALITY), #6242/#6195/#6248 (регресс роутинга reverse v26.5+, кварк = пин v26.4.25).
|
||
**Проверено из поиска:** placeholder-freedom на portal нужен (есть); routing `reverse-in→direct` на bridge нужен (есть); у VLESS outbound поле `encryption` обязательно `"none"` (есть).
|
||
|
||
### ✅ ФИКС ПРИМЕНЁН, но заблокирован (2026-09-01)
|
||
Новый bridge-конфиг с `finalRules:[{action:"allow"}]` в `direct` **залит** на Kraken (`/home/kraken/xray-reverse/config.json`, 1098 байт). **НО Kraken по docker НЕДОСТУПЕН:**
|
||
- `systemctl is-active docker` → **`activating`** (не `active`), накопились зависшие docker-процессы (ps/run/compose).
|
||
- **USB-HDD снова не поднялся:** `lsblk /dev/sda` → **`0B`** (без раздела). Docker data-root `/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker-data` (на HDD) → daemon ждёт диск, застревает.
|
||
- ⚠️ **Расхождение UUID:** data-root сейчас `/srv/dev-disk-by-uuid-49e8f586-...`, ранее в доке фигурировал `6194539b...` (sda1 1.8T). Сейчас `sda`=0B без раздела.
|
||
- **`docker compose down/up` для bridge не выполнен** — контейнер всё ещё со старым конфигом.
|
||
**Шаг продолжения (нужно подтверждение Alex):** починить HDD/docker на Kraken (reboot или физ. переподключение USB), `cd /home/kraken/xray-reverse && docker compose up -d`, тест `curl --socks5 127.0.0.1:12345 http://api.ipify.org` на TrueNAS → ожидаем IP Kraken.
|
||
|
||
**Статус: задание НЕ завершено — остаётся применить bridge-фикс после восстановления docker на Kraken.**
|
||
|
||
### ⚠️ Kraken status — диск/докер были нестабильны
|
||
- Несколько `System is booting up` (pam_nologin) — Kraken перезагружался из-за USB-диска в цикле enumeration (`device descriptor read/64 error -110`, `device not accepting address error -62`, `[sda] Read Capacity(10) failed`, `0 B`).
|
||
- Итог: диск появился, Docker `active`, **30 образов целы, 0 контейнеров** (контейнеры потеряны, data-root на HDD).
|
||
- Docker Root Dir Kraken: `/srv/dev-disk-by-uuid-6194539b-.../docker-data` (UUID **6194539b**, не 49e8f586).
|
||
- Прямой интернет Kraken работает (api.ipify → 92.62.70.41). Контейнеры Kraken (jellyfin/transmission/radarr/hermes-kraken...) НЕ восстановлены — отдельная задача при необходимости.
|
||
|
||
### Историческая справка (WS-версия, суперсидившаяся)
|
||
- Канал до перехода: Kraken→TrueNAS `172.24.0.2 → 90.189.160.148:443 ESTABLISHED`; portal `172.16.1.7:12346 ← Caddy 172.16.1.3 ESTABLISHED`; bridge лог `common/mux: received request for udp:reverse:0`. payload ❌ НЕ проходил (причина перехода на TCP).
|
||
|
||
#### Развёрнутые контейнеры (WS-версия, историческая справка)
|
||
|
||
**TrueNAS — `xray-reverse-portal`** (VLESS/W S, reverse portal): `/mnt/RED_2TB/docker/reverse-portal/`
|
||
- compose в `/mnt/RED_2TB/docker/reverse-portal/docker-compose.yml`, image `teddysun/xray:latest` (Xray 26.7.28)
|
||
- конфиг `config.json` (portal reverse):
|
||
- inbound `interconn`: VLESS на `:12346`, ws path `/rvs`, host `vpn.mallexxx.duckdns.org`, client `a81c3179-312b-4c5e-8a46-6bf3c30c2941`, `"reverse":{"tag":"reverse-out"}`
|
||
- inbound `local`: SOCKS на `:12345` (для клиентов сети TrueNAS), `udp:true`
|
||
- routing: `inboundTag:["local"] → outboundTag:"reverse-out"`
|
||
- outbounds: `freedom` (placeholder)
|
||
- проброс на host: **только `12345:12345`** (SOCKS для сети). Порт 12346 в docker-сети (к нему обращается Caddy по имени `xray-reverse-portal:12346`), наружу НЕ проброшен.
|
||
- сеть `caddy_default`, папку создавал через `docker run --rm -v /:/host alpine sh -c "mkdir -p ...; chown 950:950 ..."` (truenas_admin не имеет прав на `/mnt/RED_2TB/docker/`).
|
||
|
||
**TrueNAS — Caddy**: в блок `vpn.mallexxx.duckdns.org` добавлен маршрут `/rvs`:
|
||
```caddy
|
||
@rvs path /rvs
|
||
reverse_proxy @rvs xray-reverse-portal:12346
|
||
```
|
||
- Caddyfile на хосте: `/mnt/RED_2TB/docker/caddy/Caddyfile` (bind-mount; **нельзя `docker cp`** → `device or resource busy`; править на хосте через alpine `cp /host/tmp/...`).
|
||
- Бэкап перед правкой: `Caddyfile.pre-reverse` в той же папке. Caddy валидация: `docker exec caddy caddy validate --config /tmp/Caddyfile.new` → "Valid configuration". Перезапуск: `docker restart caddy` (безопасно).
|
||
- Проверка маршрута: `curl -sk https://vpn.mallexxx.duckdns.org/rvs` → HTTP 400 (ожидаемо для WS-эндпоинта Xray при не-WS GET).
|
||
|
||
**Kraken — `xray-reverse-bridge`** (VLESS-WS reverse bridge): `/home/kraken/xray-reverse/`
|
||
- compose + `config.json` (bridge reverse):
|
||
- outbounds: `direct` = `freedom` + `"finalRules":[{"action":"allow","network":"tcp,udp","ip":["0.0.0.0/0"]}]`; `conn` = VLESS simplified style (НЕ vnext) → `vpn.mallexxx.duckdns.org:443`, ws `/rvs`, `"reverse":{"tag":"reverse-in"}`, security tls
|
||
- routing: `inboundTag:["reverse-in"] → outboundTag:"direct"`
|
||
- **Питфолл:** VLESS-outbound для reverse ДОЛЖЕН быть в *упрощённом* стиле (`settings.address/port/id/encryption/reverse`) — при использовании `vnext[]/users[]` Xray 26.x ругается: `VLESS users: please use simplified outbound's config style to use "reverse"`.
|
||
- `loglevel debug` включён для диагностики.
|
||
- Порт 443 на Kraken свободен; образ `teddysun/xray:latest` скачан.
|
||
|
||
### Развёрнутый reverse-канал — работает
|
||
- Kraken → TrueNAS: `netstat` на Kraken показывает `172.24.0.2:xxxxx → 90.189.160.148:443 ESTABLISHED`.
|
||
- Portal (TrueNAS): `::ffff:172.16.1.7:12346 ::ffff:172.16.1.3:52616 ESTABLISHED` (172.16.1.3 = Caddy, передающий WS от Kraken).
|
||
- Bridge логи: `common/mux: received request for udp:reverse:0` — reverse-канал установлен (TCP+UDP).
|
||
|
||
### ❌ НЕ работает: payload (end-to-end curl 000)
|
||
- `curl --socks5 127.0.0.1:12345 http://api.ipify.org` на TrueNAS → `code=000` (прямой curl с того же хоста → 200).
|
||
- Portal логи: `accepted tcp:8.47.69.0:80 [local -> reverse-out]` — portal отправил запрос в reverse-out.
|
||
- **Bridge НЕ логирует accepted/received для этого TCP-payload** — данные теряются между portal reverse-out и bridge reverse-in.
|
||
- Kraken имеет прямой интернет (api.ipify → `92.62.70.41`, code=200), поэтому проблема НЕ в egress Kraken.
|
||
|
||
### 💡 Гипотеза по неработающему payload (ВЕРОЯТНАЯ)
|
||
**WebSocket-транспорт НЕ пропускает reverse-payload должным образом.** В официальном Xray reverse-примере используется **прямой TCP** + `flow: xtls-rprx-vision` (REALITY) для канала bridge↔portal. Обратный UDP reverse создаётся (`udp:reverse:0`), но TCP-payload по WS не доходит до bridge.
|
||
**Решение (предполагаемое):** перевести reverse-канал на **прямой TCP**: на TrueNAS VLESS-inbound interconn на отдельном TCP-порту (напр. 12346 наружу) + проброс на роутере `внешний :12346 → 192.168.2.197:12346`; bridge VLESS-outbound → TCP (не WS). Выполнение отложено — Alex согласовал проброс порта («не проблема»), но внедрение не завершено.
|
||
|
||
## Порядок работ (отметки → фактический статус 2026-09-01, финал)
|
||
|
||
1. ✅ Бэкап: `/mnt/RED_2TB/docker/backups/reverse-xray-3xui-20260901-113625/` (Caddyfile + x-ui.db + docker-inventory).
|
||
2. ✅ Создан `/mnt/RED_2TB/docker/xray-admin/docker-compose.yml` (deployed версия — см. «Фактически развёрнутый compose»).
|
||
3. ✅ Поднят `docker compose up -d` → контейнер Up.
|
||
4. ✅ Проверено: панель `https://vpn-panel.mallexxx.duckdns.org/` → HTTP 200, inbound vless-ws:10095 активен.
|
||
5. ✅ Создан portal-контейнер `xray-reverse-portal` на TrueNAS (interconn :12346 + SOCKS `local`:12345) + Caddy маршрут `/rvs`. [Затем: переведён на TCP+REALITY, см. секции «Reverse деплой».]
|
||
6. ✅ Создан bridge-контейнер `xray-reverse-bridge` на Kraken (→ TrueNAS, egress direct). Reverse-канал установлен. [Затем: переведён на TCP+REALITY.]
|
||
7. 🔑 **End-to-end НЕ работал** (curl через SOCKS 12345 → 000) на WS и на TCP+REALITY (flow и без flow) — **причина найдена (issue #6612)**: с v26.5+ у freedom/direct дефолт блокирует VLESS Reverse payload без явного `finalRules`. **Фикс залит** на bridge-конфиг /home/kraken/xray-reverse/config.json, но **не применён** — Kraken по docker недоступен (USB-HDD `sda`=0B, docker в `activating`). См. «КОРЕНЬ ПРОБЛЕМЫ НАЙДЕН» и «ФИКС ПРИМЕНЁН, но заблокирован» выше. **Статус: задание НЕ завершено — нужен фикс HDD/docker Kraken + пересоздать bridge + тест.**
|
||
8. ⏳ Обновить Obsidian: truenas-infrastructure.md, kraken-access.md, vps-qentra.md. **TODO для следующей сессии.** (Основной tech-doc `personal/tech/xray-reverse-tunnel-kraken-truenas.md` уже обновлён 2026-09-01 с корнем/фиксом.)
|
||
|
||
## ❌ ФИНАЛ СЕССИИ 2026-09-02: downgrade обеих сторон НЕ помог — reverse по-прежнему мёртв
|
||
|
||
> Гипотезы выше (#6612, #6242 → «понизить bridge до 26.4.25») были **проверены на практике и НЕ решили проблему**. Это фактический итог — читать вместо старых «корень найден» теорий.
|
||
|
||
### Выполнено (по согласованию, не трогая vpn.mallexxx/xray-admin)
|
||
- **Bridge (Kraken)** `docker-compose.yml`: образ `teddysun/xray:latest` → **`teddysun/xray:26.4.25`** (бэкап `.bak-26.7.28`). Контейнер на 26.4.25 (arm64).
|
||
- **Portal (TrueNAS)** `/mnt/RED_2TB/docker/reverse-portal/docker-compose.yml`: тоже → **`teddysun/xray:26.4.25`** (бэкап `.bak-26.7.28`). Образ 21.6MB Pull, контейнер пересоздан (amd64).
|
||
- Portal `config.json` → `loglevel: debug` (на время диагностики).
|
||
- Локальные копии на Mac для правки: `~/xray-test/` (`docker-compose.bridge.yml`, `docker-compose.portal.yml`, `portal.config.json`, `config.json` — тестовый xray-клиент vpn.mallexxx).
|
||
- После смены версий bridge перезапускался для переустановки канала к новому portal.
|
||
|
||
### Результат end-to-end (обе стороны 26.4.25)
|
||
- Reverse-канал у bridge **есть**: `dialing TCP → tunneling → received request for udp:reverse:0`. Portal принимает (`received request for tcp:v1.rvs.cool:0 → dispatching to udp:reverse:0`).
|
||
- **Payload НЕ проходит**: `curl` через `xray-reverse-portal:12345` → `Empty reply from server` / `exit=52`.
|
||
- **Portal debug (ключевое):** `taking detour [reverse-out] for [tcp:api.ipify.org:80]` → **и ничего дальше** (ни dial, ни ошибки). Dispatch в reverse-out молча глотается. Фоново: `common/mux: failed to read metadata ... connection reset by peer` (:12346).
|
||
- **На TrueNAS НЕТ постоянного ESTABLISHED TCP на :12346** от bridge (`ss -tn sport=:12346` пусто) → reverse-канал **не удерживается постоянным** (только эфемерные контрольные прочёты), data-stream до bridge не доходит. Bridge никогда не логирует приём reverse-in TCP-payload.
|
||
|
||
### Итог
|
||
Проблема **НЕ** регрессия bridge-v26.5+ (#6242) — downgrade до заведомо рабочей пары 26.4.25↔26.4.25 не помог. **Настоящая причина лежит глубже:** VLESS Reverse sub-protocol нестабилен (предупреждение PR #5101) и между разнесёнными docker-реализациями (Kraken arm64 ↔ TrueNAS amd64) reverse-канал не удерживается постоянным на TCP-уровне → портал не может передать данные в bridge.
|
||
|
||
### Нереализованные гипотезы (на будущее, треб.WB)
|
||
1. Убрать REALITY/camouflage с канала TrueNAS↔Kraken (это внутренний обмен между сервисами, не извне) — оставить чистый VLESS-TCP/простой шифр, исключив REALITY-handshake как источник нестабильного mux.
|
||
2. Аудит конфига bridge — что именно заставляет xray НЕ держать постоянный единственный канал (в reverse bridge обычно держит persistent-соединение).
|
||
3. При необходимости консультация/живой разбор рабочего egress-конфига (канон доки не дал полного рабочего варианта).
|
||
|
||
### ⚠️ Текущее состояние системы (2026-09-02)
|
||
- **Версии:** portal + bridge сейчас **обе на `teddysun/xray:26.4.25`** (исходно `:latest`=26.7.28). Откат: вернуть в compose образ `teddysun/xray:latest` → `docker compose up -d`.
|
||
- Bridge config содержит фикс #6612 (`finalRules:allow`). Portal config на `loglevel: debug`.
|
||
- `vpn.mallexxx` / `xray-admin` (3x-ui) / Caddy — НЕ тронуты, работают (рабочий Xray-VPN через TrueNAS, end-to-end проверен 2026-09-02).
|
||
- **Reverse к Kraken НЕ внедрён/не работает end-to-end** — остаётся открытой задачей.
|
||
|
||
## Ограничения / риски
|
||
|
||
- Кра́кен в NAT ⇒ только исходящие соединения; reverse-канал держит Kraken.
|
||
- Не ломать существующий Caddy/домены (бэкапить Caddyfile, перезапуск Caddy аккуратно).
|
||
- `vless-proxy` (Hermes-Taiga) не трогать — настроен под local SOCKS.
|
||
- Внешний Xray-порт: через Caddy по пути `/vless` (WS). Для полноценного reverse возможно потребуется отдельный VLESS+Reality inbound на отдельном порту + проброс на роутере для Kraken — ДОБАВИТЬ после проверки связности панели.
|