Files
obsidian-vault/personal/tech/xray-reverse-limits-private-network.md
Taiga b53dd70a15 [2026-09-26 09:10:28] syncthing: personal/tech/archive-org-collection-harvest.md personal/tech/balda-go-fx-pitfalls.md personal/tech/bilety-oxota-interaktiv.md personal/tech/cloudflare-tunnel-ssh-published-route.md personal/tech/deepseek-language-drift.md personal/tech/docker-data-root-mount-race.md personal/tech/docker-mac-disk-issues.md personal/tech/docker_colima_setup.md personal/tech/eagle-dashboard-launchd.md personal/tech/hermes-agent-improvements.md personal/tech/hermes-browser-toolsets.md personal/tech/hermes-fork-vs-upstream.md personal/tech/hermes-git-repo.md personal/tech/hermes-memory-architecture.md personal/tech/hermes-secret-redaction-bypass.md personal/tech/hermes-self-improvement-review.md personal/tech/home-network-config.md personal/tech/inter-site-throughput-taiga-to-mac.md personal/tech/inter-site-throughput-taiga-to-mac.md.bak-nedstab2 personal/tech/jellyfin-db-schema-mismatch.md personal/tech/karabiner-keyboard-config.md personal/tech/kraken-media-inventory-facts.md personal/tech/kraken-truenas-media-copies.md personal/tech/lampa-jellyfin-plugin.md personal/tech/lampac-deployment.md personal/tech/lampac-torrserver.md personal/tech/llm-model-selection-2026.md personal/tech/mac-print-shared-services.md personal/tech/modbus-rtu-sniffer-debugging.md personal/tech/multistream-single-flow-limit.md personal/tech/multistream-single-flow-limit.md.bak-nedstab2 personal/tech/music-tags-repair-truenas.md personal/tech/obsidian-mcp-ecosystem.md personal/tech/original-xbox-2025-guide.md personal/tech/prowlarr-flaresolverr-cloudflare.md personal/tech/radarr-sonarr-phantom-records.md personal/tech/roundtrip-key-verification.md personal/tech/ryujinx-mac-setup.md personal/tech/skill-arr-media-stack-setup-additions.md personal/tech/skill-docker-data-root-mount-race.md personal/tech/skill-lampac-kraken-deploy.md personal/tech/tirith-trust.md personal/tech/truenas-local-tree-comparison.md personal/tech/truenas-nfs4-acl-and-arrmultiuser.md personal/tech/truenas-zfs-panic-recovery.md personal/tech/vault-doc-pruning.md personal/tech/vless-space-subscription-egress.md personal/tech/watchlist-sync-feed.md personal/tech/watchtower-docker-updates.md personal/tech/xray-outbound-subscription-3xui.md personal/tech/xray-reverse-limits-private-network.md personal/tech/xray-reverse-tunnel-kraken-truenas.md personal/tech/xray-reverse-tunnel-kraken-truenas.md.bak-nedstab2 personal/tech/yandex-music-api.md
2026-09-26 09:10:28 +00:00

7.7 KiB
Executable File
Raw Permalink Blame History

title, created, type, namespace, tags, status, related
title created type namespace tags status related
Xray reverse — граница возможностей (forward proxy в приватные сети) 2026-09-23 tech personal
xray
reverse
vless
vpn
networking
pitfall
verified
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-каналом в сеть публичной стороны нельзя.

Пример конфига внутренней стороны (бридж) с разрешением в локалку:

{
  "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.

Связанные заметки