192 lines
15 KiB
Markdown
192 lines
15 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, финал сессии)
|
||
|
||
### Развёрнутые контейнеры (фактические конфиги)
|
||
|
||
**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 (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 для следующей сессии.**
|
||
|
||
## Ограничения / риски
|
||
|
||
- Кра́кен в NAT ⇒ только исходящие соединения; reverse-канал держит Kraken.
|
||
- Не ломать существующий Caddy/домены (бэкапить Caddyfile, перезапуск Caddy аккуратно).
|
||
- `vless-proxy` (Hermes-Taiga) не трогать — настроен под local SOCKS.
|
||
- Внешний Xray-порт: через Caddy по пути `/vless` (WS). Для полноценного reverse возможно потребуется отдельный VLESS+Reality inbound на отдельном порту + проброс на роутере для Kraken — ДОБАВИТЬ после проверки связности панели.
|