15 KiB
Reverse Xray (3x-ui) — TrueNAS ↔ Kraken
Создано: 2026-09-01. Цель: проксировать трафик локальных клиентов (сеть TrueNAS 192.168.2.x) через TrueNAS → Kraken → интернет. Kraken = точка выхода (exit node). TrueNAS = bridge/контроллер.
Архитектура
ЛОКАЛЬНЫЕ КЛИЕНТЫ (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).
Ключевые факты (прояснены)
- На 443 у TrueNAS — Caddy (reverso-proxy, валидные LE-серты), НЕ Xray REALITY. Хостовый маппинг:
0.0.0.0:8443→443(контейнер),2019(admin),8088→80. - Xray на TrueNAS раньше был задуман как 3x-ui:
- База
/mnt/RED_2TB/docker/xray-admin/x-ui.db(3x-ui), inboundvless-wsport10095, tagin-10095-tcp, path/vless, hostvpn.mallexxx.duckdns.org, protocol vless. - Композ-файла в
xray-admin/нет; контейнер НЕ запущен.
- База
- Caddyfile уже проксирует (мёртвые ссылки на
xray-admin):vpn.mallexxx.duckdns.org→@ws path /vless→xray-admin:10095vpn-panel.mallexxx.duckdns.org→xray-admin:443/xray-admin:2053(path /sub/*)- Сертификаты для этих поддоменов уже выданы (DNS на TrueNAS IP).
vless-proxy(teddysun/xray) на TrueNAS — КЛИЕНТ: слушает 1080/1081 (SOCKS/HTTP), outbound на мёртвыйv.qentra.top:443(VPS удалён). Используется Hermes-Taiga.- VPS qentra.top (91.207.28.205) УДАЛЁН. Вся старая VLESS+REALITY инфраструктура на нём недоступна.
- Открытые порты 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
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-wsport 10095, tagin-10095-tcp, path/vless, hostvpn.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)
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, imageteddysun/xray:latest(Xray 26.7.28) - конфиг
config.json(portal reverse):- inbound
interconn: VLESS на:12346, ws path/rvs, hostvpn.mallexxx.duckdns.org, clienta81c3179-312b-4c5e-8a46-6bf3c30c2941,"reverse":{"tag":"reverse-out"} - inbound
local: SOCKS на:12345(для клиентов сети TrueNAS),udp:true - routing:
inboundTag:["local"] → outboundTag:"reverse-out" - outbounds:
freedom(placeholder)
- inbound
- проброс на 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:
@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; править на хосте через alpinecp /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"
- outbounds:
- Питфолл: 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, финал)
- ✅ Бэкап:
/mnt/RED_2TB/docker/backups/reverse-xray-3xui-20260901-113625/(Caddyfile + x-ui.db + docker-inventory). - ✅ Создан
/mnt/RED_2TB/docker/xray-admin/docker-compose.yml(deployed версия — см. «Фактически развёрнутый compose»). - ✅ Поднят
docker compose up -d→ контейнер Up. - ✅ Проверено: панель
https://vpn-panel.mallexxx.duckdns.org/→ HTTP 200, inbound vless-ws:10095 активен. - ✅ Создан portal-контейнер
xray-reverse-portalна TrueNAS (VLESS-WSinterconn:12346 + SOCKSlocal:12345) + Caddy маршрут/rvs. - ✅ Создан bridge-контейнер
xray-reverse-bridgeна Kraken (VLESS-WS → TrueNAS, egress direct). Reverse-канал установлен. - ❌ End-to-end НЕ работает (curl через SOCKS 12345 → 000; payload теряется на WS). Гипотеза — перевести reverse на прямой TCP + проброс порта (см. секцию «Reverse деплой»). ВНЕДРЕНИЕ TCP-варианта ОТЛОЖЕНО (незавершено).
- ⏳ Обновить 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 — ДОБАВИТЬ после проверки связности панели.