[2026-09-01] eagle: family/plans/reverse-xray-3xui-kraken.md personal/tech/xray-reverse-tunnel-kraken-truenas.md

This commit is contained in:
Alexey Martemyanov
2026-09-01 13:02:25 +06:00
parent 35ff547f9e
commit 0a259820b2
2 changed files with 110 additions and 11 deletions
+52 -6
View File
@@ -124,18 +124,64 @@ networks:
```
> Черновик выше (секция «Композ-файл») — предварительный; фактический файл на TrueNAS содержит `hostname`, `TZ`, `PUID/PGID`. Панель внутри слушает **2053** (не 54321) — это то, что Caddyfile проксирует через `vpn-panel`. Хостовый 54321-проброс не используется панелью (панель = 2053), можно убрать.
**Следующий шаг:** развернуть reverse-клиент на Kraken (exit node) и настроить reverse-bridge в 3x-ui (TrueNAS) + локальный SOCKS/HTTP для клиентов сети TrueNAS. См. `personal/tech/xray-reverse-tunnel-kraken-truenas.md` — основной doc архитектуры с деталями.
**Следующий шаг:** ✅ Выполнено — reverse развёрнут (см. ниже). Основной doc архитектуры: `personal/tech/xray-reverse-tunnel-kraken-truenas.md`.
## Порядок работ (отметки → фактический статус 2026-09-01)
## Reverse деплой — ПОЛНЫЙ СТАТУС (2026-09-01, финал сессии)
### Развёрнутые контейнеры (фактические конфиги)
**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. ⏳ Через панель 3x-ui создать/настроить **reverse inbound** и клиента для Kraken + локальный SOCKS/HTTP для клиентов. **НЕ сделано.**
6. ⏳ На Kraken поднять Xray reverse-клиент (Docker compose) с выходом в интернет. **НЕ сделано.**
7. ⏳ Проверка end-to-end: клиент → TrueNAS → Kraken → интернет (с IP Kraken).
8. ⏳ Обновить Obsidian: truenas-infrastructure.md, kraken-access.md, vps-qentra.md (VPS удалён — уже отмечено).
5. ✅ Создан portal-контейнер `xray-reverse-portal` на TrueNAS (VLESS-WS `interconn`:12346 + SOCKS `local`:12345) + Caddy маршрут `/rvs`.
6. ✅ Создан bridge-контейнер `xray-reverse-bridge` на Kraken (VLESS-WS → TrueNAS, egress direct). Reverse-канал установлен.
7. ❌ End-to-end НЕ работает (curl через SOCKS 12345 → 000; payload теряется на WS). Гипотеза — перевести reverse на прямой TCP + проброс порта (см. секцию «Reverse деплой»). **ВНЕДРЕНИЕ TCP-варианта ОТЛОЖЕНО (незавершено).**
8. ⏳ Обновить Obsidian: truenas-infrastructure.md, kraken-access.md, vps-qentra.md. **TODO для следующей сессии.**
## Ограничения / риски
@@ -15,7 +15,7 @@ related:
# Xray Reverse Tunnel — Kraken ↔ TrueNAS
> **Статус: ЧАСТИЧНО ВНЕДРЕН (2026-09-01).** ✅ 3x-ui развёрнут на TrueNAS и работает. ⏳ Осталось: reverse-клиент на Kraken + reverse-bridge в 3x-ui.
> **Статус: ЧАСТИЧНО ВНЕДРЕН (2026-09-01).** ✅ 3x-ui развёрнут и работает. ✅ reverse portal (TrueNAS) + bridge (Kraken) развёрнуты, reverse-канал установлен. ❌ **End-to-end payload НЕ проходит** (curl 000) — предположительно из-за WS-транспорта reverse (гипотеза: нужен прямой TCP). **TCP-вариант + проброс порта = следующая задача (отложена).**
> Архитектурное решение: проксировать исходящий трафик локальных клиентов сети TrueNAS через **TrueNAS → Kraken → интернет**.
## Контекст / Почему
@@ -89,8 +89,60 @@ Kraken ──┘ держит ИСХОДЯЩИЙ reverse-канал к TrueNAS,
### Мелочь/питфолл
Скопированный в volume `docker-compose.yml` оказался внутри контейнера `/etc/x-ui/` (т.к. volume смонтирован туда) — удалить лишний файл из контейнера: `docker exec xray-admin rm -f /etc/x-ui/docker-compose.yml`.
## ⏳ Следующий шаг (НЕ сделан)
Развернуть **reverse-клиент (outstation) на Kraken** (exit node) и настроить **reverse-bridge в 3x-ui (TrueNAS)** + локальный SOCKS/HTTP для клиентов сети TrueNAS. Механика: `dokodemo-door` + `reverse` + routing; Kraken (outstation) подключается к TrueNAS по публичному `vpn.mallexxx.duckdns.org/vless`, регистрирует локальный SOCKS-выход; bridge (TrueNAS) выставляет алиас-порт для локальных клиентов.
## ✅ ВНЕДРЕНО 2026-09-01: Reverse portal (TrueNAS) + bridge (Kraken) — VLESS-WS
После 3x-ui развёрнут полноценный reverse. **Ключевое открытие:** Xray **26.x заменил legacy reverse на "VLESS Reverse Proxy"** — старая схема `reverse.bridges/portals` (Xray-examples/ReverseProxy) **не работает** в этой версии (ошибка `The feature "legacy reverse" has been removed and migrated to "VLESS Reverse Proxy"`). Новая схема: `reverse.tag` в VLESS-клиентах/аутбаундах (примеры — `xtls.github.io/en/document/level-2/vless_reverse.html`, use case "Home Broadband Egress").
### Роли (новая терминология VLESS Reverse)
- **Internal device (Kraken) = BRIDGE**: VLESS-**outbound** с `"reverse":{"tag":"reverse-in"}` → активно устанавливает канал к TrueNAS; на своей стороне создаётся виртуальный **inbound** `reverse-in`, чей трафик направляется в freedom (интернет).
- **Public server (TrueNAS) = PORTAL**: VLESS-**inbound** с `"reverse":{"tag":"reverse-out"}` у клиента → создаёт **routable-маутбаунд** `reverse-out`; локальные клиенты (SOCKS) маршрутизируются в `reverse-out`.
- `reverse.tag` на двух сторонах **не обязаны совпадать** — соответствие через общий UUID соединения.
### TrueNAS — `xray-reverse-portal` (папка `/mnt/RED_2TB/docker/reverse-portal/`)
compose: image `teddysun/xray:latest` (26.7.28), сеть `caddy_default`, volume `config.json:/etc/xray/config.json:ro`, проброс host **`12345:12345`**.
`config.json`:
- inbound `interconn` (:12346, VLESS, ws path `/rvs`, host `vpn.mallexxx.duckdns.org`, client id `a81c3179-312b-4c5e-8a46-6bf3c30c2941`, `"reverse":{"tag":"reverse-out"}`)
- inbound `local` (:12345, SOCKS `noauth udp:true`) — точка входа для клиентов сети TrueNAS
- routing: `inboundTag:["local"] → outboundTag:"reverse-out"`
- outbounds: `freedom` (placeholder — обязателен, иначе `reverse-out` станет default и весь трафик уйдёт в reverse)
- Порт 12346 НЕ проброшен наружу — к нему обращается Caddy по имени `xray-reverse-portal:12346` в docker-сети.
### TrueNAS — Caddyfile (bind mount `/mnt/RED_2TB/docker/caddy/Caddyfile`)
Добавлен маршрут в блок `vpn.mallexxx.duckdns.org`:
```caddy
@rvs path /rvs
reverse_proxy @rvs xray-reverse-portal:12346
```
Питфоллы: **Caddyfile нельзя править `docker cp`** в контейнер (volume → `device or resource busy`) — править на хосте через `docker run --rm -v /:/host alpine cp /host/tmp/...`. Валидация `docker exec caddy caddy validate --config /tmp/Caddyfile.new` → "Valid configuration". Перезапуск `docker restart caddy` безопасен. Бэкап: `Caddyfile.pre-reverse`.
### Kraken — `xray-reverse-bridge` (папка `/home/kraken/xray-reverse/`)
compose: image `teddysun/xray:latest`, volume `config.json:/etc/xray/config.json:ro`.
`config.json`:
- outbound `direct` = `freedom` + `"finalRules":[{"action":"allow","network":"tcp,udp","ip":["0.0.0.0/0"]}]` (интернет-egress Kraken)
- outbound `conn` = **VLESS упрощённого стиля** (`settings.address/port/id/encryption/reverse` — НЕ `vnext[]`!) → `vpn.mallexxx.duckdns.org:443` ws `/rvs` `"reverse":{"tag":"reverse-in"}`, security tls, tlsSettings.serverName `vpn.mallexxx.duckdns.org`
- routing: `inboundTag:["reverse-in"] → outboundTag:"direct"`
- **Питфолл:** VLESS-outbound с `reverse` должен быть упрощённого стиля. Если через `vnext[]/users[]` → Xray 26.x: `VLESS users: please use simplified outbound's config style to use "reverse"`.
- `loglevel debug` (для диагностики).
### Reverse-канал: ✅ установлен
- Kraken `netstat`: `172.24.0.2:... → 90.189.160.148:443 ESTABLISHED`
- Portal: `::ffff:172.16.1.7:12346 ::ffff:172.16.1.3:52616 ESTABLISHED` (172.16.1.3 = Caddy)
- Bridge logs: `common/mux: received request for udp:reverse:0`
### ❌ End-to-end payload НЕ работает
- `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]` — запрос ушёл в reverse-out.
- **Bridge НЕ логирует received для этого TCP-payload** — данные теряются между reverse-out (portal) и reverse-in (bridge).
- Kraken имеет прямой интернет (`api.ipify``92.62.70.41`), проблема не в egress.
### 💡 Гипотеза (вероятная) и след. шаг
**WebSocket-транспорт не пропускает reverse-payload.** В официальных VLESS-reverse примерах канал bridge↔portal идёт **по прямому TCP** + `flow: xtls-rprx-vision` (REALITY). UDP-reverse создаётся, но TCP-payload по WS не доходит.
**План (отложен):** перевести reverse-канал на **прямой TCP**:
1. TrueNAS: VLESS-inbound `interconn` на отдельном TCP-порту (напр. `:12346` наружу) + проброс на роутере `внешний :12346 → 192.168.2.197:12346` (Alex подтвердил «пробросить не проблема»).
2. Kraken: bridge VLESS-outbound → **TCP** (не WS), address `mallexxx.duckdns.org:12346`.
3. Возможно нужен `flow: xtls-rprx-vision` + шифрование на канале (REALITY) — по доке.
## ⏳ Открытые вопросы по reverse (требуют ответа/действия Alex)
## План реализации (история; Шаг 1 устарел — см. «ВНЕДРЕНО» выше)
@@ -121,9 +173,10 @@ Kraken ──┘ держит ИСХОДЯЩИЙ reverse-канал к TrueNAS,
## Открытые вопросы (требуют ответа Alex)
1. ✅ (расcмотрено при внедрении 3x-ui) **Проброс порта на роутере** — НЕ потребовался: переиспользовали уже существующий Caddy-путь `vpn.mallexxx.duckdns.org/vless` (WS) и готовую интеграцию 3x-ui↔Caddyfile. Reverse от Kraken пойдёт через этот же публичный путь.
1. **Проброс порта для reverse** — теперь НУЖЕН для перевода reverse-канала на TCP (end-to-end payload не проходит по WS). Alex подтвердил «пробросить не проблема». Параметры: `внешний :12346 → 192.168.2.197:12346` (или отдельный VLESS+REALITY порт).
2. **Какой трафик TrueNAS пустить через Kraken** — весь исходящий интернет, или конкретные сервисы/подсети? (Влияет на маршрутизацию на Kraken.) — всё ещё открыто.
3. **Docker-демон Kraken работает нестабильно** (рвёт SSH, `docker ps` не завершается) — чинить перед деплоем reverse-клиента? — открыто, важно для Шага reverse на Kraken.
3. **Kraken docker** — РАБОТАЕТ (после перезагрузки 2026-09-01): Server 29.4.3, Docker Root Dir `/srv/dev-disk-by-uuid-6194539b-.../docker-data` (актуальный UUID, HDD смонтирован), **30 образов сохранены, но 0 контейнеров** (all контейнеры не восстановлены после сбоя). Reverse-bridge-контейнер развёрнут поверх. НО: известные контейнеры (jellyfin, ha, transmission и т.д.) требуется пересоздать — отдельная задача, не входила в reverse-сферу.
4.**End-to-end payload не проходит** — главный блокер (см. секцию «Reverse деплой» выше). Гипотеза WS-проблема → следующий шаг перевести на TCP + проброс порта. Не завершено.
## Связанные заметки
- [[family/how-to/vps-qentra]] — VPS на 2026-09-01 УДАЛЁН