187 lines
19 KiB
Markdown
187 lines
19 KiB
Markdown
---
|
||
title: Xray Reverse Tunnel — Kraken ↔ TrueNAS
|
||
created: '2026-09-01'
|
||
updated: '2026-09-01'
|
||
type: tech
|
||
namespace: personal
|
||
tags: [xray, reverse, kraken, truenas, tunnel, networking]
|
||
confidence: medium
|
||
related:
|
||
- "[[family/how-to/vps-qentra]]"
|
||
- "[[family/how-to/truenas-infrastructure]]"
|
||
- "[[family/how-to/kraken-access]]"
|
||
- "[[family/how-to/rasputin-router]]"
|
||
---
|
||
|
||
# Xray Reverse Tunnel — Kraken ↔ TrueNAS
|
||
|
||
> **Статус: ЧАСТИЧНО ВНЕДРЕН (2026-09-01).** ✅ 3x-ui развёрнут и работает. ✅ reverse portal (TrueNAS) + bridge (Kraken) развёрнуты, reverse-канал установлен. ❌ **End-to-end payload НЕ проходит** (curl 000) — предположительно из-за WS-транспорта reverse (гипотеза: нужен прямой TCP). **TCP-вариант + проброс порта = следующая задача (отложена).**
|
||
> Архитектурное решение: проксировать исходящий трафик локальных клиентов сети TrueNAS через **TrueNAS → Kraken → интернет**.
|
||
|
||
## Контекст / Почему
|
||
|
||
- **VPS qentra.top (91.207.28.205) УДАЛЁН** — вся прежняя Xray-инфраструктура на нём (VLESS+REALITY, OpenVPN, WebSocket v.qentra.top) больше не существует.
|
||
- Нужен новый путь для выхода локальных клиентов сети TrueNAS в интернет через другую точку выхода (Kraken).
|
||
- Белый IP есть только у **TrueNAS** (`mallexxx.duckdns.org` = `90.189.160.148`).
|
||
- **Kraken за NAT**, входящие не принимает — только исходящие соединения.
|
||
|
||
## Принятая схема
|
||
|
||
```
|
||
Локальные клиенты (сеть TrueNAS, 192.168.2.x)
|
||
│ шлют трафик на локальный прокси TrueNAS (SOCKS 1080 / HTTP 1081)
|
||
▼
|
||
TrueNAS ←── контроллер / bridge (белый IP, mallexxx.duckdns.org), принимает
|
||
│ TrueNAS заворачивает трафик в reverse-канал
|
||
▼ ▲
|
||
Kraken ──┘ держит ИСХОДЯЩИЙ reverse-канал к TrueNAS, отпускает трафик → интернет
|
||
▼
|
||
интернет
|
||
```
|
||
|
||
**Тип решения: Xray `reverse`.** Роли по Xray:
|
||
|
||
| Узел | Роль | Держит канал? | Выход в интернет? |
|
||
|------|------|---------------|-------------------|
|
||
| **TrueNAS** | bridge/контроллер (inbound `reverse`) | ❌ слушает | ❌ |
|
||
| **Kraken** | outbound reverse-нода + exit | ✅ **исходящий** к TrueNAS | ✅ **да** |
|
||
| **Локальные клиенты** | используют TrueNAS как локальный прокси-шлюз | — | через Kraken |
|
||
|
||
**Ключевое физическое ограничение:** Kraken за NAT не может принимать входящих. Поэтому канал держит **Kraken исходящим** к TrueNAS. Для передачи клиентского трафика TrueNAS → Kraken используются конструкции `dokodemo-door` + `reverse` + policy-маршрутизация (routing rules). Это чуть сложнее "поставить reverse и всё", конфиг нужен аккуратный.
|
||
|
||
## ⚠️ Факты, проверенные 2026-09-01 (важно, ломают прежние допущения)
|
||
|
||
1. **На 443 у TrueNAS НЕ Xray.** Проверено `openssl s_client`: на `mallexxx.duckdns.org:443` отвечает **обычный TLS 1.3 с валидным Let's Encrypt сертификатом для `mallexxx.duckdns.org`** (`issuer=Let's Encrypt/CN=YE2`). Это **Caddy/nginx reverse-proxy**, НЕ Xray REALITY (у REALITY сертификат был бы чужой/поддельный). → Твоя память «на 443 висел xray server» не подтверждается.
|
||
2. **`vless-proxy` на TrueNAS** (контейнер `teddysun/xray:latest`, Up 7 дней):
|
||
- inbound: SOCKS `0.0.0.0:1080`, HTTP `0.0.0.0:1081` (локально в LAN TrueNAS)
|
||
- outbound: VLESS+WS+TLS на `v.qentra.top:443`, path `/qentra`, id `2D9F24C4-21FE-4784-9843-F11C384DA67A` — **указывает на УДАЛЁННЫЙ VPS → сейчас мёртвый**.
|
||
- ⚠️ Используется Hermes-Taiga как SOCKS5-прокси (`vless-proxy:1080`) → **Hermes-Taiga сейчас без рабочего прокси**.
|
||
3. **Kraken→TrueNAS по `mallexxx.duckdns.org`:** открыты **только 22 (SSH) и 443 (HTTPS/TLS)**. `8443/8964/8080/9000` — closed. Порт 443 — TLS (Caddy), не сырой.
|
||
4. **Kraken:** Docker установлен (`/usr/bin/docker`), но демон отвечает медленно/рвёт SSH (проверка `docker ps` не завершилась за 40s). Xray на Kraken **отсутствует** (`which xray` пусто) — нужен Docker-контейнер.
|
||
5. **Связанность Kraken↔TrueNAS по 22/443 — подтверждена** (оба OPEN с Kraken).
|
||
|
||
## ✅ ВНЕДРЕНО 2026-09-01: 3x-ui на TrueNAS (фронтенд + Docker Compose)
|
||
|
||
**Решение Alex:** использовать **3x-ui frontend** + **Docker Compose** (управление клиентами через панель), а не ручной Caddy-pass-through с сырым Xray. Это изменило исходный план реализации (Шаг 1 ниже устарел по способу).
|
||
|
||
### Развёрнут контейнер `xray-admin` (TrueNAS)
|
||
- **Имя контейнера:** `xray-admin` (строго, т.к. Caddyfile резолвит `xray-admin` по имени в docker-сети).
|
||
- **Образ:** `ghcr.io/mhsanaei/3x-ui:latest` (**3.7.0**, Xray **26.7.28**).
|
||
- **Сеть:** `caddy_default` (external) — там же Caddy, чтобы резолвить имя.
|
||
- **Volume:** `/mnt/RED_2TB/docker/xray-admin:/etc/x-ui` (туда лёг существующий `x-ui.db`).
|
||
- **Порт панели:** хостовый `54321 → 54321` (внутри панель реально слушает **2053** — Caddy проксирует `vpn-panel.mallexxx.duckdns.org` → `xray-admin:2053`).
|
||
- **Compose-файл:** `/mnt/RED_2TB/docker/xray-admin/docker-compose.yml` (deployed версия с `TZ=Asia/Novosibirsk`, `PUID/PGID=950`; см. актуальный файл на TrueNAS — отличается от черновика в плане).
|
||
- **Панель доступна:** `https://vpn-panel.mallexxx.duckdns.org/` → **HTTP 200**.
|
||
- **Sub-сервер:** `[::]:443` (path `/sub`), панель `[::]:2053`, inbound `vless-ws:10095` (path `/vless`, host `vpn.mallexxx.duckdns.org`).
|
||
|
||
### Почему это заработало «из коробки» (важно)
|
||
База `/mnt/RED_2TB/docker/xray-admin/x-ui.db` **уже была настроена под эту Caddy-интеграцию** (раньше 3x-ui уже задумывался на TrueNAS): inbound `vless-ws` port 10095 tag `in-10095-tcp`, subDomain `vpn-panel.mallexxx.duckdns.org`, subPort 443, subScheme https. Caddyfile уже содержал (мёртвые до подъёма) блоки:
|
||
- `vpn.mallexxx.duckdns.org` → `@ws path /vless` → `xray-admin:10095` (WS)
|
||
- `vpn-panel.mallexxx.duckdns.org` → `@sub path /sub/*` → `xray-admin:443` + fallback `xray-admin:2053`
|
||
- LE-сертификаты для этих поддоменов уже выданы.
|
||
|
||
### 3x-ui поддерживает reverse
|
||
В бинарнике `/app/x-ui` присутствует **`clientReverseTags`** → reverse-настройка реализуема через панель 3x-ui (3.7.0).
|
||
|
||
### Бэкап (сделан до изменений)
|
||
`/mnt/RED_2TB/docker/backups/reverse-xray-3xui-20260901-113625/` — содержит: `caddy/Caddyfile` (копия из контейнера, 90 строк), `xray-admin/x-ui.db`, `docker-inventory.txt`.
|
||
|
||
### Мелочь/питфолл
|
||
Скопированный в volume `docker-compose.yml` оказался внутри контейнера `/etc/x-ui/` (т.к. volume смонтирован туда) — удалить лишний файл из контейнера: `docker exec xray-admin rm -f /etc/x-ui/docker-compose.yml`.
|
||
|
||
## ✅ ВНЕДРЕНО 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 устарел — см. «ВНЕДРЕНО» выше)
|
||
|
||
### Шаг 1 — TrueNAS: Xray reverse-server поверх Caddy
|
||
- **Способ (рекомендован): Caddy TLS-pass-through.** Добавить в Caddy TCP-правило: поддомен `xray.mallexxx.duckdns.org:443` → внутренний порт Xray-контейнера (напр. `localhost:8443`). Caddy передаёт сырой TLS-стрим дальше. Xray на TrueNAS принимает VLESS+Reality/TLS. Kraken ходит на `xray.mallexxx.duckdns.org:443`.
|
||
- Плюс: переиспользуем уже открытый/проброшенный 443 на роутере, не трогаем роутер, туннель маскируется под HTTPS.
|
||
- Альтернатива: пробросить отдельный порт на роутере (напр. 8443) → требует доступа к роутеру. Менее предпочтительно.
|
||
- Новый/доразвернутый Xray-контейнер:
|
||
- inbound `reverse`/`dokodemo-door` на 8443 (извне по pass-through)
|
||
- local inbound SOCKS/HTTP (уже есть 1080/1081)
|
||
- routing: трафик клиентов → в reverse-канал к Kraken
|
||
|
||
### Шаг 2 — TrueNAS: бэкап перед изменением
|
||
- Снять копию текущего конфига `vless-proxy` (config.json), в `/mnt/RED_2TB/docker/<app>/backup/` (паттерн как с cups-splix).
|
||
|
||
### Шаг 3 — Kraken: Xray outbound reverse в Docker
|
||
- Контейнер Xray на Kraken (`docker run --restart unless-stopped`, как остальные).
|
||
- outbound vless → `xray.mallexxx.duckdns.org:443` (через Caddy pass-through).
|
||
- inbound SOCKS/HTTP на Kraken — точка выхода.
|
||
- reverse-конфиг: Kraken регистрирует «сервис» (весь трафик через dokodemo-door) наружу через канал к TrueNAS.
|
||
|
||
### Шаг 4 — Проверка связности
|
||
- Kraken → `xray.mallexxx.duckdns.org:443` (TCP).
|
||
- Локальный клиент → TrueNAS:1080 → curl через прокси → должен выйти с IP Kraken.
|
||
|
||
### Шаг 5 — Обновить Obsidian после внедрения
|
||
- Дополнить `family/how-to/truenas-infrastructure.md` (Xray reverse-настройка), `family/how-to/kraken-access.md`; обновить `personal/tech/vps-qentra.md` (VPS удалён, ссылки на него).
|
||
|
||
## Открытые вопросы (требуют ответа Alex)
|
||
|
||
1. ❌ **Проброс порта для reverse** — теперь НУЖЕН для перевода reverse-канала на TCP (end-to-end payload не проходит по WS). Alex подтвердил «пробросить не проблема». Параметры: `внешний :12346 → 192.168.2.197:12346` (или отдельный VLESS+REALITY порт).
|
||
2. **Какой трафик TrueNAS пустить через Kraken** — весь исходящий интернет, или конкретные сервисы/подсети? (Влияет на маршрутизацию на 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 УДАЛЁН
|
||
- [[family/how-to/truenas-infrastructure]] — TrueNAS Caddy/контейнеры
|
||
- [[family/how-to/kraken-access]] — Docker Kraken
|
||
- [[family/how-to/rasputin-router]] — прежний VLESS-туннель на VPS (тоже требует пересмотра, VPS нет)
|
||
- [[family/how-to/wireguard-vpn]] — WG Eagle↔VPS↔Kraken (VPS-звено теперь мёртво)
|