From ea6e19f4f8478a13a070c947744b92a0a1d3f630 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Wed, 23 Sep 2026 13:31:20 +0600 Subject: [PATCH] [2026-09-23] eagle: family/how-to/kraken-access.md family/how-to/truenas-infrastructure.md personal/plans/lan-access-via-reverse-tunnel.md personal/tech/xray-reverse-limits-private-network.md personal/tech/xray-reverse-tunnel-kraken-truenas.md --- family/how-to/kraken-access.md | 15 +- family/how-to/truenas-infrastructure.md | 13 ++ .../plans/lan-access-via-reverse-tunnel.md | 131 +++++++++++++----- .../xray-reverse-limits-private-network.md | 118 ++++++++++++++++ .../xray-reverse-tunnel-kraken-truenas.md | 37 ++++- 5 files changed, 274 insertions(+), 40 deletions(-) create mode 100644 personal/tech/xray-reverse-limits-private-network.md diff --git a/family/how-to/kraken-access.md b/family/how-to/kraken-access.md index bb21417d..c5781f13 100644 --- a/family/how-to/kraken-access.md +++ b/family/how-to/kraken-access.md @@ -157,14 +157,17 @@ EP=3 # endpoint ID на Кракене = 3, не 1! - Контейнер **`xray-reverse-bridge`** в `/home/kraken/xray-reverse/` (compose + `config.json`), образ **`teddysun/xray:26.4.25`** + `network_mode: host` (проверенный фикс 2026-09-02). - Outbound VLESS+REALITY TCP → `mallexxx.duckdns.org:12346` (TrueNAS через OpenWrt DNAT), reverse tag `reverse-in`, egress freedom с `finalRules:[{action:allow}]`. -- ✅ **End-to-end payload работает** (верифицировано 2026-09-02: SOCKS `12345` → egress IP Кра́кена). Полная история диагностики (регрессии #6612/#6242, docker bridge/NAT) — в [[tech/xray-reverse-tunnel-kraken-truenas]]. +- ✅ **End-to-end payload работает** (верифицировано 2026-09-02: SOCKS `12345` → egress IP Kraken). Полная история диагностики (регрессии #6612/#6242, docker bridge/NAT) — в [[tech/xray-reverse-tunnel-kraken-truenas]]. - ⚠️ 2026-09-15…20 контейнер был **не запущен** (гонка docker↔mount, см. шапку) — это единственная причина «туннель down». После рестарта daemon — снова Up. -- ✅ **2026-09-23 — канал перепроверен end-to-end после починки гонки, работает.** Egress Кра́кена = **`92.62.77.233`**. - > 🔴 **IP Кра́кена ИЗМЕНИЛСЯ:** `92.62.70.41` (старые записи) → **`92.62.77.233`** (2026-09-23). Во всех доках семейства `family/how-to/*` фигурирует старый `92.62.70.41` — **не доверять ему**, брать актуальный из живого запроса. -- 🔧 **2026-09-23 — в конфиг бриджа добавлен inbound** `lan-in` (`dokodemo-door`, `listen 127.0.0.1:12345`, `followRedirect:true`) + правило `lan-in → conn`. Прежде `inbounds` было **`null`** — бридж мог только отправлять в туннель, принимать не мог. Плюс на хосте Кра́кена поставлено правило `iptables -t nat PREROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -p tcp -j REDIRECT --to-ports 12345`. - - Задача и полное состояние: [[personal/plans/lan-access-via-reverse-tunnel]] +- ✅ **2026-09-23 — канал перепроверен end-to-end после починки гонки. Egress Кра́кена = `92.62.77.233`.** + > 🔴 **IP Кра́кена ИЗМЕНИЛСЯ:** `92.62.70.41` (все старые записи) → **`92.62.77.233`** (2026-09-23, проверено через SOCKS портала). **Не доверять `92.62.70.41`**, брать актуальный живым запросом. +- 🔧 **2026-09-23 — в конфиг бриджа добавлен inbound `lan-in`** (`dokodemo-door`, **`listen 0.0.0.0:12345`**, `followRedirect:true`, `sniffing:false`) + routing `lan-in → conn`. Прежде `inbounds` было **`null`** — бридж мог только отправлять в туннель, принимать не мог. + - ⚠️ **`listen` обязан быть `0.0.0.0`, НЕ `127.0.0.1`.** С `127.0.0.1` REDIRECT-трафик с внешнего адреса не принимается — соединение отбивается мгновенно (`HTTP 000` за ~0.005 с). Ошибка проверена и исправлена. + - Плюс на хосте Кра́кена: `iptables -t nat PREROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -p tcp -j REDIRECT --to-ports 12345`. + - 🏁 **Задача, ради которой это ставилось, — ТУПИК.** Xray reverse намеренно не пускает forward-proxy в приватные сети: портал отдаёт `not allowed to use forward proxy`. Это штатная защита, не баг. Теория: [[personal/tech/xray-reverse-limits-private-network]]. Полное состояние: [[personal/plans/lan-access-via-reverse-tunnel]]. - ⚠️ **`iptables-persistent` НЕ установлен** — правило REDIRECT слетит при reboot. - - ⚠️ Бэкапы: `config.json.bak-lan-in-20260923-130541`, `/home/kraken/backups/iptables.bak-20260923-130541`. + - Бэкапы: `config.json.bak-lan-in-20260923-130541`, `config.json.bak-listen0000-20260923-131655`, `config.json.bak-v3-`, `/home/kraken/backups/iptables.bak-20260923-130541`. + - ⚠️ **`sudo` на Кра́кене через SSH требует `< /dev/null`** — иначе `Connection closed by remote host`. На Кра́кене **нет `ifconfig`** (использовать `ip addr`). ## Docker контейнеры (обновлено 2026-09-20, после фикса) diff --git a/family/how-to/truenas-infrastructure.md b/family/how-to/truenas-infrastructure.md index 7392b99e..28fc488e 100644 --- a/family/how-to/truenas-infrastructure.md +++ b/family/how-to/truenas-infrastructure.md @@ -230,6 +230,19 @@ TrueNAS использует **NFSv4 ACL**, а не стандартный POSIX > 🔴 **`xray-admin`: compose-файл УТРАЧЕН (обнаружено 2026-09-15).** В `/mnt/RED_2TB/docker/xray-admin/` лежат только `x-ui.db`, `-shm`, `-wal`, `system_metrics.gob`. Docker label указывает на `docker-compose.yml`, но файла нет. **Причина (найдено через Zulip DB, `personal/zulip router issues`, id=86681):** 2026-09-01 05:40:08 UTC агент выполнил `docker exec xray-admin rm -f /etc/x-ui/docker-compose.yml` — volume смонтирован как `/etc/x-ui` (bind-mount), поэтому `rm` внутри контейнера снёс файл на хосте, через 1,5 минуты после создания. **Пересоздать контейнер из папки сейчас НЕЛЬЗЯ** — только из `docker inspect`. Подробно и параметры для восстановления: [[family/plans/reverse-xray-3xui-kraken]]. Проверить перед любым `docker compose` по этому сервису. | xray-reverse-portal | teddysun/xray:latest | 12345 (SOCKS), 12346 (VLESS-TCP REALITY interconn) | — (см. `personal/tech/xray-reverse-tunnel-kraken-truenas.md`) | +> ## ⚠️ 2026-09-23 — правки reverse-пары для попытки «доступ в 192.168.2.x снаружи» (ЗАВЕРШИЛАСЬ ТУПИКОМ) +> +> Попытка завернуть клиентов ASUS-сети на `192.168.2.x` через reverse-туннель. **Архитектурный тупик** — reverse по дизайну не пускает forward-proxy в приватные сети. Полный разбор: [[personal/plans/lan-access-via-reverse-tunnel]], теория: [[personal/tech/xray-reverse-limits-private-network]]. +> +> **Что осталось применённым на TrueNAS (решить — откатить или оставить):** +> - `/mnt/RED_2TB/docker/reverse-portal/config.json` — добавлено правило роутинга `192.168.2.0/24 → direct` (выше правила `local → reverse-out`), outbound `direct` с `finalRules:[{action:"allow"}]`. Валидация `Configuration OK.`, портал Up, канал жив. +> - Бэкап: `config.json.before-lanroute` (в той же папке). +> - ⚠️ `loglevel` портала был `debug` — при откате вернуть `warning`, иначе лог быстро растёт. +> +> **Откат:** вернуть `config.json.before-lanroute` → `config.json`, затем `docker restart xray-reverse-portal`. +> +> ✅ **Побочно:** канал впервые подтверждён end-to-end после починки гонки docker↔mount 2026-09-20 — через SOCKS портала `92.62.77.233` ≠ напрямую `90.189.160.148`. **WAN-IP Кра́кена изменился: `92.62.70.41` → `92.62.77.233`.** + ### cups-splix — принтер Samsung CLX-216x (✅ поднят 2026-08-26; ✅ mDNS-фикс 2026-08-31 завершён) **Статус:** контейнер работает, принтер `Samsung_CLX-216x_Series` **idle / enabled / accepting**. CUPS слушает `0.0.0.0:631` (host-сеть). mDNS-анонс **включён** — штатная Android print service теперь видит принтер по mDNS (подробно: [[mac-print-shared-services]]). См. ниже раздел «✅ mDNS/AirPrint анонс принтера». diff --git a/personal/plans/lan-access-via-reverse-tunnel.md b/personal/plans/lan-access-via-reverse-tunnel.md index 82cd3b62..e318710a 100644 --- a/personal/plans/lan-access-via-reverse-tunnel.md +++ b/personal/plans/lan-access-via-reverse-tunnel.md @@ -11,7 +11,7 @@ tags: - asus - routing - vpn -status: partially-applied +status: stopped-architectural-deadlock updated: '2026-09-23' related: - '[[personal/tech/xray-reverse-tunnel-kraken-truenas]]' @@ -21,21 +21,22 @@ related: --- # Доступ к 192.168.2.0/24 с ASUS через reverse-туннель Kraken→TrueNAS -> ## 🔄 СТАТУС: ЧАСТИЧНО ПРИМЕНЕНО (2026-09-23, вечер). Сквозной проход НЕ подтверждён. +> ## 🏁 СТАТУС: ОСТАНОВЛЕНО (2026-09-23, вечер). Архитектурный тупик, схема НЕ доведена. > -> **Применено и проверено:** -> - ✅ Бэкапы: Кра́кен `config.json.bak-lan-in-20260923-130541` + `/home/kraken/backups/iptables.bak-20260923-130541`; TrueNAS `config.json.before-lanroute` -> - ✅ **Правка 2 (портал) ВЫПОЛНЕНА** — добавлено правило `192.168.2.0/24 → direct` (выше правила `local → reverse-out`), outbound `direct` создан с `finalRules:[{action:"allow"}]`. Валидация `xray run -test` → `Configuration OK.` Портал перезапущен → Up, канал жив, egress `92.62.77.233`. -> - ✅ **Правка 1 (бридж) ВЫПОЛНЕНА** — добавлен inbound `lan-in` (`dokodemo-door`, `127.0.0.1:12345`, `followRedirect:true`, `sniffing:false`) + правило `lan-in → conn`. Валидация `Configuration OK.` Бридж перезапущен → Up. -> - ✅ **Правило iptables добавлено** на Кра́кене: `nat PREROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -p tcp -j REDIRECT --to-ports 12345`. Inbound слушает `127.0.0.1:12345` (проверено `ss -tlnp`). +> **Итог:** цепочка «ASUS → Кра́кен → туннель → TrueNAS → 192.168.2.x» **не реализуется** в Xray reverse. Портал отклоняет: `for safety reasons, user a81c3179-… is not allowed to use forward proxy`. Это **штатная защита** Xray от превращения сервера в открытый прокси, не баг конфига. Обходится только `finalRules`-allow, но тогда «домашней» стороной обязан быть Кра́кен, а целевая сеть — его локалка (`192.168.1.x`), **не** `192.168.2.x`. Направление задачи и направление туннеля не совпадают. > -> **🔴 НЕ подтверждено — сквозной проход.** Тест дал `HTTP 000` (3 с), счётчик REDIRECT-правила = **0 пакетов**. +> **Решение Alex:** НЕ принято. Варианты в разделе «Развилка» ниже. Откат возможен в одну команду из бэкапов. > -> **⚠️ ПИТФОЛЛ МЕТОДИКИ (стоил ложного вывода):** тест запускался `curl`-ом **с самого Кра́кена**. Локально-исходящий трафик идёт через `nat OUTPUT`, а **не** через `PREROUTING` → правило физически не могло сработать, счётчик 0. Это **не** доказывает ни поломку, ни работу схемы. **Проверять только с постороннего хоста** в `192.168.1.x` (Mac), а не с узла, где стоит правило. +> **Что осталось применённым на системах (требует решения — откатить или оставить):** +> - Кра́кен: inbound `lan-in` (`dokodemo-door`, `0.0.0.0:12345`) + routing `lan-in → conn`; правило `iptables nat PREROUTING` REDIRECT (не персистентно). Бэкапы: `config.json.bak-lan-in-20260923-130541`, `config.json.bak-listen0000-20260923-131655`, `config.json.bak-v3-`, `iptables.bak-20260923-130541`. +> - TrueNAS: правило `192.168.2.0/24 → direct` в портале. Бэкап: `config.json.before-lanroute`. +> - ASUS: `nvram lan_route` изменён с `192.168.1.2` на `192.168.1.15`. Бэкап: `/jffs/lan_route.bak.20260923-131613`. +> - ⚠️ **Обнаружен и исправлен битый артефакт:** `lan_route` указывал на мёртвый `192.168.1.2` (ARP `FAILED`, MAC нулевой) — трафик на `192.168.2.x` уходил в никуда. Это была **предсуществующая поломка**, не созданная в этой сессии. > -> **🔴 ВТОРАЯ ГИПОТЕЗА (не проверена):** в логах бриджа при reverse-трафике видно `proxy/freedom: applying default private IP blocking policy for inbound vless-reverse`. Если эта политика применится и к `lan-in`, до `192.168.2.x` не дойдёт — тот же класс, что issue #6612. Требует проверки по факту прохода. -> -> **Осталось:** (1) сквозной тест **с Mac**; (2) правка 3 — маршрут на ASUS через веб-UI (SSH `192.168.1.1:22` закрыт); (3) персистентность iptables — `iptables-persistent` **НЕ установлен** на Кра́кене, нужен systemd oneshot-юнит (пакет ставить не стали). +> **✅ ПОЛЕЗНЫЕ ПОБОЧНЫЕ НАХОДКИ (сохранить, не терять):** +> - ✅ **ASUS SSH РАБОТАЕТ:** `ssh -i ~/.ssh/id_rsa admin@192.168.1.1` (пользователь **`admin`**, не `root`). Порт 22 открыт. Прежний вывод «ASUS не пускает по SSH» — **ошибка**: подключался как `root`. Маршруты правятся через `nvram lan_route` (формат `NET:MASK:GW:METRIC`), не через UI. +> - ✅ **Reverse-канал ВПЕРВЫЕ подтверждён end-to-end** после починки гонки docker↔mount 2026-09-20: через SOCKS портала `92.62.77.233` ≠ напрямую `90.189.160.148`. +> - ⚠️ **WAN-IP Кра́кена изменился:** `92.62.70.41` → **`92.62.77.233`**. В `kraken-access.md` / `xray-reverse-tunnel-*` фигурирует старый — актуализировать при следующей правке. > **Исходный статус на момент планирования: ПРЕДЛОЖЕНО.** План согласован к выполнению 2026-09-23. @@ -80,9 +81,51 @@ TrueNAS 192.168.2.197 ── сеть 192.168.2.0/24 (шлюз OpenWrt 192.168. **Чтобы ASUS мог что-то отправить, бриджу нужна точка входа. Сейчас её нет** — `inbounds: null`. Пока правка 1 не сделана, схема физически не может работать. -## Три правки +## 🔴 КРИТИЧНАЯ НАХОДКА (2026-09-23) — направление перевёрнуто -### Правка 1 — Кра́кен: прозрачный перехват (`dokodemo-door` + REDIRECT) +Прогнано вживую. Цепочка «ASUS → Кра́кен → туннель → TrueNAS → 192.168.2.x» **не работает архитектурно**, а не из-за конфига. + +**Что происходит по факту:** +| Шаг | Лог | Результат | +|---|---|---| +| Mac → Кра́кен `lan-in` | `accepted tcp:192.168.2.197:80 [lan-in -> conn]` | ✅ перехват, уход в туннель | +| Туннель → портал | `received request for tcp:192.168.2.197:80` | ✅ дошло | +| Портал выпускает | `for safety reasons, user a81c3179-… is not allowed to use forward proxy` | ❌ **отклонено** | + +**Причина (официальная дока Xray, freedom outbound):** +> Traffic from **VLESS reverse proxy** blocks **all targets** by default. VLESS/VMess/Trojan/Shadowsocks inbounds block **private and reserved IP ranges** by default. To allow clients access to internal services, explicitly configure `allow` rules. + +Портал видит соединение «клиент просит сходить на `192.168.2.197`» и классифицирует это как **forward proxy** — то есть как попытку использовать сервер как открытый прокси. Отсюда отказ. + +**Правильное направление (Use Case 2 «Remote Return Home» из доки Xray):** + +``` +клиент → PUBLIC SERVER (TrueNAS, портал) → reverse-out → туннель + ↓ + INTERNAL DEVICE (Кра́кен, бридж) + ↓ + freedom + finalRules allow + ↓ + 192.168.2.0/24 +``` + +То есть **точка входа должна быть на TrueNAS (портал)**, а `reverse-in → freedom с finalRules[allow ip 192.168.2.0/24]` — **на Кра́кене (бридж)**. + +🔴 **Мой план был построен на перевёрнутой схеме** — «ASUS → Кра́кен → в подсеть». В этой архитектуре Кра́кен выступает «домашней» стороной, и именно ему нужен allow-rule, а вход — на TrueNAS. + +**Проверенные факты по пути (сохранить):** +- `dokodemo-door` **обязан** слушать `0.0.0.0`, не `127.0.0.1` — иначе REDIRECT-трафик с внешнего адреса не принимается. +- `iptables -t nat PREROUTING` **не действует** на локально-исходящий трафик с самого хоста — для теста нужен отдельный netns либо реальный клиент из сети. +- `redirect: ""` в freedom — невалидно; пустая строка ломает конфиг. +- Xray 26.4.25: `xray run -test` **читает stdin** и виснет под SSH без `< /dev/null`. +- Кра́кен: `sudo` через SSH требует `< /dev/null` на каждой команде, иначе `Connection closed by remote host`. +- На Кра́кене **нет `ifconfig`** — каждый вызов печатает `command not found` в stderr (безвредно, но засоряет вывод). + +## Три правки (СУПЕРСИДЕД — см. находку выше) + +### Правка 1 — Кра́кен: `dokodemo-door` + REDIRECT (сделано, но НЕ тот вход) + +Файл `/home/kraken/xray-reverse/config.json`. Применено, канал работает, но это вход **не с той стороны** — см. находку выше. Требует пересмотра. Файл `/home/kraken/xray-reverse/config.json` (bind-mount `:ro` → `/etc/xray/config.json`). @@ -162,22 +205,44 @@ Xray из REDIRECT-сокета читает `SO_ORIGINAL_DST` → узнаёт - ⚠️ Правка конфига на TrueNAS: папка `/mnt/RED_2TB/docker/reverse-portal/` — права root, `truenas_admin` писать не может. Класть через `docker run --rm -v /tmp:/src -v :/dst alpine cp …` + `chown`. - Бэкап ДО: `config.json.bak-lan-route-`. -### Правка 3 — ASUS: статический маршрут +### Правка 3 — ASUS: статический маршрут ✅ ВЫПОЛНЕНО (не через UI) -SSH закрыт (`Connection closed` на `:22`), поэтому — **веб-UI**: -`http://192.168.1.1` → LAN → Route → добавить: +✅ **ASUS доступен по SSH** — прежняя запись «SSH закрыт, только веб-UI» **ОШИБОЧНА**. Правильный вход: +```bash +ssh -i ~/.ssh/id_rsa admin@192.168.1.1 # пользователь admin, НЕ root +``` +Порт 22 открыт; подключение как `root` даёт `Connection closed` — отсюда ложный вывод. -| Поле | Значение | -|---|---| -| Network/Host IP | `192.168.2.0` | -| Netmask | `255.255.255.0` | -| Gateway | `192.168.1.15` (Кра́кен) | -| Metric | `1` | -| Interface | `LAN` | +**Механизм статических маршрутов — `nvram`, не UI.** Формат `NET:MASK:GW:METRIC` в одной строке: +```bash +nvram get lan_route # → 192.168.2.0:255.255.255.0:192.168.1.2:25 +nvram set lan_route="192.168.2.0:255.255.255.0:192.168.1.15:25" +nvram commit +``` +⚠️ `service restart_routing` **НЕ перечитывает** `lan_route` (проверено — таблица осталась со старым шлюзом). Применять явно: +```bash +ip route del 192.168.2.0/24 via 192.168.1.2 dev br0 +ip route add 192.168.2.0/24 via 192.168.1.15 dev br0 metric 25 +``` +Бэкап: `nvram get lan_route > /jffs/lan_route.bak.$(date +%Y%m%d-%H%M%S)` -⚠️ Кра́кен имеет **два** адреса в `192.168.1.0/24`: `.14` (eth0) и `.15` (wlan0). В доке `rasputin-router` зафиксировано: ARP на Распутине резолвит оба в **один** lladdr `2c:cf:67:64:03:f3`. Использовать **`.15`**, как в DNS-записи `address=/kraken/192.168.1.15`. +⚠️ Кра́кен имеет **два** адреса в `192.168.1.0/24`: `.14` (eth0, metric 100) и `.15` (wlan0, metric 600), **разные MAC** (`…03:f3` / `…03:f4`). Использовать **`.15`**, как в DNS-записи `address=/kraken/192.168.1.15`. -⚠️ Правило действует на всем сегменте — **все** клиенты `192.168.1.0/24` пойдут на `192.168.2.x` через туннель. Если нужно выборочно — вместо маршрута на ASUS делать routing на конкретном клиенте, но тогда ASUS не нужен вовсе. +⚠️ Маршрут действует на всём сегменте — **все** клиенты `192.168.1.0/24` пойдут на `192.168.2.x` через `.15`. Если нужно выборочно — routing на конкретном клиенте, но тогда ASUS не нужен. + +## 🏁 РАЗВИЛКА — решение НЕ принято (2026-09-23) + +Тупик: Xray reverse **по дизайну** не пропускает forward-proxy трафик в приватные сети. Направление «ASUS → Кра́кен → в сеть TrueNAS» реализовать нельзя — только обратное («дом = Кра́кен», цель = `192.168.1.x`), что не решает задачу. + +| # | Вариант | Что даёт | Цена | +|---|---|---|---| +| **1** | **Отказаться**, откатить всё из бэкапов | возврат к исходному состоянию | теряется только то, чего и не было | +| **2** | SOCKS-прокси на стороне **клиента** (Mac) — через существующий `vless-proxy` (SOCKS `:1080`) / `xray-admin` | доступ к `192.168.2.x` с Mac | не «через ASUS»; нужен SOCKS-aware клиент или routing на Mac; не работает для других устройств | +| **3** | **WireGuard на TrueNAS** (белый IP + открытый порт уже есть) | **полный IP-стек**: ICMP, UDP, Samba-обзор, «как локальный» | новая служба на TrueNAS; TrueNAS на пределе RAM (17/21 ГБ) | + +**Рекомендация:** вариант **3** — если нужен реально «true VPN» с UDP и Samba; вариант **2** — если хватит доступа с одного Mac. + +⚠️ **Вариант 2 ограничен:** `docker exec vless-proxy wget` **не проверяет SOCKS** (wget не умеет SOCKS5, вернёт локальный IP) — проверять только через `curl --socks5-hostname`. ## Как это будет работать @@ -226,13 +291,13 @@ TrueNAS: xray-reverse-portal | 4 | Проверка, что канал не порвался после рестарта портала | ✅ egress `92.62.77.233` | | 5 | Правка 1 (Кра́кен, бридж) | ✅ выполнено, `Configuration OK.`, бридж Up | | 6 | Правило iptables REDIRECT на Кра́кене | ✅ добавлено, inbound слушает | -| 7 | **Сквозной тест** | 🔴 **НЕ ПРОЙДЕН** — тест с Кра́кена методологически неверен | -| 8 | Повторный тест **с Mac** (посторонний хост) | ⏳ ждёт апрува команды | -| 9 | Фикс private-IP-политики (если подтвердится) | ⏳ по результату п.8 | -| 10 | Персистентность iptables (systemd-юнит) | ⏳ не начато | -| 11 | Правка 3 — маршрут на ASUS через UI | ⏳ руками Alex | -| 12 | Финальная проверка Alex'ом: `http://192.168.2.197:8096` в браузере | ⏳ | -| 13 | Обновить `personal/tech/xray-reverse-tunnel-kraken-truenas.md` + `family/how-to/truenas-infrastructure.md` | ⏳ | +| 7 | **Сквозной тест** | ✅ **ПРОЙДЕН ЧАСТИЧНО** — перехват работает, но портал режет forward-proxy | +| 8 | Повторный тест **с Mac** (посторонний хост) | ✅ выполнен — `HTTP 000` + отказ портала | +| 9 | Диагностика отказа портала | ✅ `not allowed to use forward proxy` — **штатная защита Xray** | +| 10 | Диагностика ASUS-маршрута | ✅ SSH найден, битый `lan_route` → `.2` исправлен на `.15` | +| 11 | **Вывод: архитектурный тупик** | 🏁 зафиксирован, решение Alex **не принято** | +| 12 | Откат или переход к варианту 2/3 | ⏳ ждёт решения | +| 13 | Обновить `personal/tech/xray-reverse-tunnel-kraken-truenas.md` | ⏳ | ### 🔴 Как правильно проверять сквозной проход diff --git a/personal/tech/xray-reverse-limits-private-network.md b/personal/tech/xray-reverse-limits-private-network.md new file mode 100644 index 00000000..a3f25ee9 --- /dev/null +++ b/personal/tech/xray-reverse-limits-private-network.md @@ -0,0 +1,118 @@ +--- +title: Xray reverse — граница возможностей (forward proxy в приватные сети) +created: '2026-09-23' +type: tech +namespace: personal +tags: + - xray + - reverse + - vless + - vpn + - networking + - pitfall +status: verified +related: + - '[[personal/tech/xray-reverse-tunnel-kraken-truenas]]' + - '[[personal/plans/lan-access-via-reverse-tunnel]]' +--- + +# Xray reverse — граница возможностей + +> **Короткий вывод:** Xray reverse **намеренно** не даёт использовать себя как «вход в чужую приватную сеть». Это защита от превращения сервера в открытый прокси — **не баг**, версией Xray не лечится, конфигом не обходится (кроме одного случая, см. ниже). + +Проверено вживую 2026-09-23 на связке TrueNAS (портал) ↔ Кра́кен (бридж), Xray 26.4.25. + +## Симптом + +Настроен рабочий reverse-канал (payload проходит, egress проверен). Подаём в него трафик, адресованный в приватную сеть **публичной** стороны: + +``` +портал: for safety reasons, user a81c3179-312b-4c5e-8a46-6bf3c30c2941 + is not allowed to use forward proxy +``` + +Соединение доходит до портала (`received request for tcp:192.168.2.197:80`), но портал **отказывается его выпускать**. + +## Причина (официальная документация) + +Из доки Xray, outbound `freedom`: + +> ⚠️ **Default fallback safety policy** (server-side / reverse-proxy scenarios): +> - Traffic from **VLESS reverse proxy** blocks **all targets** by default +> - Traffic from `VLESS`, `VMess`, `Trojan`, `Shadowsocks`, `Hysteria`, or `WireGuard` inbounds blocks **private and reserved IP ranges** by default +> - Other traffic is **fully allowed** by default +> +> To allow clients access to internal services, explicitly configure `allow` rules and limit them to necessary `network`, `ip`, and `port`. + +Источник: `https://xtls.github.io/en/config/outbounds/freedom.html` + +Портал классифицирует запрос как **forward proxy** (клиент просит «сходи на `192.168.2.197`») и режет его по политике. + +## Единственная рабочая конфигурация reverse + +Use Case 2 из доки Xray — «Remote Return Home»: + +``` +клиент → PUBLIC SERVER (портал) → reverse-out → туннель + ↓ + INTERNAL DEVICE (бридж) + ↓ + freedom + finalRules[allow ip <локальная сеть>] + ↓ + <сеть «внутренней» стороны> +``` + +🔴 **Ключевое ограничение:** целевая сеть — **локалка «внутренней» стороны** (той, что держит reverse-соединение). Ходить reverse-каналом в сеть **публичной** стороны **нельзя**. + +**Пример конфига внутренней стороны (бридж) с разрешением в локалку:** + +```json +{ + "protocol": "freedom", + "tag": "home-lan", + "settings": { + "domainStrategy": "AsIs", + "finalRules": [ + { "action": "allow", "network": "tcp,udp", "ip": ["192.168.1.0/24"] } + ] + } +} +``` + +И правило роутинга: `{ "inboundTag": ["reverse-in"], "outboundTag": "home-lan" }`. + +⚠️ `finalRules` применяется **только если freedom — финальный outbound**. Если у outbound задан `sockopt.dialerProxy`, freedom перестаёт быть финальным и `finalRules` **не применяется** (из доки). + +## Чем ЭТО обходится (а чем нет) + +| Способ | Помогает? | +|---|---| +| `finalRules: [{action:"allow", ip:[...]}]` | ✅ **да** — но только для локалки «внутренней» стороны | +| Смена версии Xray | ❌ нет, это политика, не регрессия | +| `allowForwardProxy` в inbound | ⚠️ относится к **обычным** proxy-inbound, не снимает reverse-политику | +| `dokodemo-door` / TPROXY / REDIRECT | ❌ нет — меняет способ **приёма** трафика, не политику выпуска | +| Смена `listen` на `0.0.0.0` | ❌ нет — влияет только на приём пакетов | + +⚠️ **Не путать с issue #6612 / #6242** (регрессии версий, лечатся даунгрейдом/`network_mode: host`). Здесь другой класс: **штатная политика безопасности**, она есть во всех версиях. + +## Что делать, если нужен доступ в приватную сеть + +1. **Определить, чья сеть «домашняя».** Reverse пускает только в локалку стороны, держащей соединение. Если нужная сеть — на публичной стороне, reverse не подходит. +2. **Альтернативы для «полного IP-стека»** (ICMP, UDP, broadcast/Samba-обзор): + - **WireGuard** на узле с белым IP — даёт настоящий L3-VPN, всё проходит. + - **SOCKS-прокси на стороне клиента** — только TCP, нужен SOCKS-aware клиент или routing на клиенте. + - **Прозрачный прокси на клиенте** (TPROXY) — TCP; UDP требует отдельной работы. +3. **Reverse оставить для того, для чего он есть** — egress через домашний канал (`reverse-in → direct`). + +## Сопутствующие питфоллы, найденные в той же сессии + +- **`dokodemo-door` обязан слушать `0.0.0.0`, не `127.0.0.1`.** При `listen: 127.0.0.1` REDIRECT-трафик с внешнего адреса (клиент `192.168.1.57`) не принимается — соединение отбивается мгновенно (`HTTP 000` за ~0.005 с). +- **`iptables -t nat PREROUTING` НЕ действует на локально-исходящий трафик того же хоста.** Тест `curl`-ом с самого узла, где стоит правило, всегда даст `000` и счётчик `0` — это **ложный негатив**. Проверять с постороннего хоста либо через `ip netns` (трафик станет транзитным). +- **`redirect: ""` в freedom невалидно** — пустая строка ломает конфиг. Чтобы не менять адрес, использовать `":порт"` (адрес не меняется) либо убрать поле целиком. +- **`xray run -test` читает stdin** — под SSH без `< /dev/null` виснет. +- **`sudo` через SSH на Кра́кене требует `< /dev/null`** — иначе `Connection closed by remote host`. + +## Связанные заметки + +- [[personal/tech/xray-reverse-tunnel-kraken-truenas]] — рабочий reverse-туннель (egress), архитектура +- [[personal/plans/lan-access-via-reverse-tunnel]] — попытка использовать reverse как вход в сеть TrueNAS (тупик) diff --git a/personal/tech/xray-reverse-tunnel-kraken-truenas.md b/personal/tech/xray-reverse-tunnel-kraken-truenas.md index 85889315..65458902 100644 --- a/personal/tech/xray-reverse-tunnel-kraken-truenas.md +++ b/personal/tech/xray-reverse-tunnel-kraken-truenas.md @@ -513,7 +513,42 @@ curl -s --max-time 20 --socks5-hostname 127.0.0.1:12345 https://api.ipify.org 3. ✅ **Kraken docker** — РАБОТАЕТ, ВОССТАНОВИЛСЯ 2026-09-02: `systemctl is-active docker` → `active`, диск `/dev/sda1 1.8T` смонтирован к `/srv/dev-disk-by-uuid-6194539b-...`, 235G свободно (87% занято). **Все контейнеры восстановились** (в отличие от 2026-09-01, когда было 0): transmission, sonarr, prowlarr, homeassistant, jellyfin, radarr, hermes-kraken, portainer, rclone, cloudflared, flaresolverr, watchtower, **xray-reverse-bridge** (Up). 4. ✅ **End-to-end payload проходит.** #6612/#6242 оказались неполными гипотезами. Верифицированный корень — Docker bridge/NAT на Kraken; решение — Xray 26.4.25 + `network_mode: host` на bridge. См. authoritative-секцию ниже. -## ✅ Верифицированный фикс 2026-09-02 (authoritative) +> ## 🚧 2026-09-23 — ГРАНИЦА ВОЗМОЖНОСТЕЙ: reverse НЕ работает как «вход в чужую приватную сеть» +> +> **Попытка:** завернуть клиентов `192.168.1.0/24` (за ASUS) на адреса `192.168.2.x` **через этот reverse-туннель** — то есть использовать его как «вход в сеть TrueNAS». +> +> **Результат: невозможно по дизайну.** План и полный разбор — [[personal/plans/lan-access-via-reverse-tunnel]]. +> +> **Механизм отказа (воспроизведён вживую):** +> ``` +> портал: for safety reasons, user a81c3179-… is not allowed to use forward proxy +> ``` +> **Официальная дока Xray (freedom outbound):** +> > Traffic from **VLESS reverse proxy** blocks **all targets** by default. Traffic from VLESS/VMess/Trojan/Shadowsocks/Hysteria/WireGuard inbounds blocks **private and reserved IP ranges** by default. To allow clients access to internal services, explicitly configure `allow` rules. +> +> То есть reverse **намеренно** не даёт ходить в приватные сети — защита от превращения сервера в открытый прокси. Это **не баг конфига** и не лечится версией Xray. +> +> **Единственная рабочая конфигурация reverse (Use Case 2, «Remote Return Home»):** +> ``` +> клиент → PUBLIC SERVER (портал) → reverse-out → туннель +> ↓ +> INTERNAL DEVICE (бридж) +> ↓ +> freedom + finalRules[allow ip <локальная сеть>] +> ↓ +> <сеть «внутренней» стороны> +> ``` +> Целевая сеть — **локалка «внутренней» стороны** (здесь — Кра́кен, `192.168.1.0/24`), **не** сеть публичной стороны. Направление «пойти в сеть TrueNAS снаружи» reverse-каналом не решается. +> +> **Что это НЕ задевает:** существующие сценарии работают как раньше — +> `kraken-user` (egress через Кра́кен) использует `reverse-in → direct` и не затронут; +> `user1` / `vless-space` — вообще другой механизм (direct / подписка). +> +> ### ✅ Побочный факт: канал впервые проверен end-to-end после починки 2026-09-20 +> через SOCKS портала: `92.62.77.233` ≠ напрямую с TrueNAS `90.189.160.148`. +> ⚠️ **WAN-IP Кра́кена изменился: `92.62.70.41` → `92.62.77.233`.** Везде в этом доке и в `kraken-access.md` фигурирует старый — при следующей правке актуализировать. + +> ## ✅ Верифицированный фикс 2026-09-02 (authoritative) > Эта секция суперсидирует все более ранние выводы «payload мёртв», «нет persistent ESTABLISHED» и предполагаемые корни #6612/#6242. Фикс найден и проверен живыми A/B-тестами.