逐跳搭建并验证 Xray 代理链:出口、DNS 与故障恢复

逐跳搭建并验证 Xray 代理链:出口、DNS 与故障恢复

Ryan Foster
2026年10月11日· 7 分钟阅读

Xray 代理链让指定应用先经过入口 A,再经过出口 B。先分别检查每一跳,再让 B 的拨号连接通过 A 建立;任何一跳失效时,指定请求应停止,而不是悄悄改为直连。

关键要点

  • 两台服务器及目标必须自有,或已取得所有者明确授权。
  • 最终出口地址不能证明请求经过哪个入口。
  • 认证、TLS 校验、选路和 DNS 要分别验证。
  • 本例只覆盖明确配置代理的 TCP 应用,不是全设备隧道,也不支持 UDP。

Xray 代理链覆盖哪些流量?

本文按 Xray-core v26.3.27 官方文档整理,客户端采用 Ubuntu 24.04 LTS 命令行环境,两端是已配置好的授权 Trojan over TLS 服务。未进行完整端到端实测;固定版本用于说明示例,不代表最新版,也不意味着可以忽略安全更新。[1]

变更前先检查自建网络的责任与恢复条件。双跳的信任边界解释了两跳能隐藏及不能隐藏什么;增加一跳不等于匿名、更快或更抗封。Xray 与 V2Ray 的角色区别则帮助区分核心程序和管理它的应用。

如果你只需要日常设备出口,不需要控制两台服务器,可比较设备级覆盖和应用代理。这是另一种任务选择,不是用产品修复本代理链。

步骤 1:预留拓扑与独立恢复入口

使用独立客户端和专用测试身份。不要为完成示例关闭或修改日常使用的代理或 VPN 客户端;若其现有路由影响实验,应记录这层路径,或使用获授权的隔离机器,不能把结果称为纯粹的两跳路径。

角色必须控制的范围私下保留的证据
客户端 C测试进程与回环端口核心版本、配置位置、进程所有者
入口 A带认证的 TLS 端点测试身份、来源限制、到 B 的连接
出口 B带认证的 TLS 端点来自 A 的连接、获准目标、出口地址族
目标 T授权 HTTPS 服务证书身份和时间可对应的请求记录

保留不依赖代理链的控制台或管理连接。记录原监听、具体防火墙管理者、DNS 与应用代理设置,仅备份要改的文件并限制权限。若一个进程或配置还服务其他用户,停止操作,另建独立测试实例。

A、B 必须已有不同的 Trojan 凭据、与各自名称匹配的有效证书、兼容传输设置及精确放行范围。按官方协议文档核对入站和出站字段。[2] 条件允许时,A 只接收获准客户端来源,链式测试的 B 只接收 A,两端只允许授权目标。不能创建匿名监听、关闭防火墙或借用未获授权的住宅出口。

步骤 2:核对 Xray dialerProxy 配置与归属

dialerProxy 指定用于建立另一个出站底层连接的出站标识。本例应用选择 exit-b,而 exit-b 通过 entry-a 连接 B;entry-a 不能再指回 B 或自身。[3] tag 必须唯一,引用关系不能成环。

以普通测试用户建立私有工作目录,将下面完整客户端配置保存为 chain.json。文档地址、证书名称、端口和两个密码占位符都要换成获授权端点;示例不是可用节点。密码不得放进命令行参数或共享日志。

{
  "log": {"loglevel": "warning"},
  "inbounds": [
    {
      "tag": "lab-socks",
      "listen": "127.0.0.1",
      "port": 10818,
      "protocol": "socks",
      "settings": {"auth": "noauth", "udp": false}
    }
  ],
  "outbounds": [
    {"tag": "deny", "protocol": "blackhole", "settings": {}},
    {
      "tag": "entry-a",
      "protocol": "trojan",
      "settings": {
        "servers": [{"address": "192.0.2.10", "port": 18443,
          "password": "REPLACE_ENTRY_PASSWORD"}]
      },
      "streamSettings": {
        "network": "raw", "security": "tls",
        "tlsSettings": {"serverName": "a.example.com", "allowInsecure": false}
      }
    },
    {
      "tag": "exit-b",
      "protocol": "trojan",
      "settings": {
        "servers": [{"address": "198.51.100.20", "port": 18443,
          "password": "REPLACE_EXIT_PASSWORD"}]
      },
      "streamSettings": {
        "network": "raw", "security": "tls",
        "tlsSettings": {"serverName": "b.example.com", "allowInsecure": false},
        "sockopt": {"dialerProxy": "entry-a"}
      }
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {"type": "field", "inboundTag": ["lab-socks"],
        "network": "tcp", "outboundTag": "exit-b"}
    ]
  }
}

回环 SOCKS 入口仅适用于可信的单用户客户端,其他本机用户也可能访问它;共享机器不能采用这个无认证入口。UDP 已明确禁用。[4] TLS 名称必须匹配有效证书;本教程不混入 REALITY、Vision、复用或透明捕获。传输安全和拨号出站选择是不同设置。[2][5]

路由按顺序匹配,未命中规则时使用第一个出站。因此把 deny 放在首位,让未匹配流量默认拒绝;显式 TCP 规则则把测试入口交给 B。[6] 不添加直连出站或回退负载均衡器。未来若确需直连例外,应独立记录目的、范围及失效证据。

步骤 3:分别验证代理链的组成部分

使用实际预定的二进制路径运行检查,必要时替换命令中的路径:

xray version
xray run -test -config ./chain.json
ss -lntp '( sport = :10818 )'

启动前端口必须空闲。配置检查成功只证明可解析,并未连接两台服务器、完成认证或证明路径。二进制版本或加载文件与登记不符时停止。

为单跳检查建立两份私有副本。A 副本把路由规则改为选择 entry-a;B 副本仍选择 exit-b,但只移除 B 的 sockopt.dialerProxy。每次只运行一个前台实例,使用预留端口请求 T,保留对应服务器证据,再按 Ctrl-C 停止该实例,随后才启动下一份。

B 的单跳检查必须来自已有授权来源或 B 自己受控的测试环境。如果 B 只允许 A,就从 A 做 B 单跳检查,不能为了客户端基线扩大公网访问范围。基线来源与预期出口要和最终代理链分别登记。

选择自有、证书正常可校验的 HTTPS 目标。以下是读者操作示例,不是本文的实测结果:

curl --fail --show-error --connect-timeout 5 --max-time 15 \
  --noproxy "" --proxy socks5h://127.0.0.1:10818 https://target.example.com/health

运行前替换目标。socks5h 把目标名称交给代理,不会捕获无关系统 DNS 或浏览器自己的安全 DNS 请求。先区分连接拒绝、TLS 错误、凭据错误和目标拒绝,再组合两跳。

--noproxy "" 仅为本命令覆盖继承的 NO_PROXY/no_proxy 排除列表,否则匹配目标即使指定 --proxy 也可能直连。单跳、链式和断跳检查都须保留此参数;它不会修改其他应用的代理设置。[7]

步骤 4:组合两跳并对照证据

恢复原始链式配置,再检查一次,使用 xray run -config ./chain.json 前台启动。通过显式代理命令发起新请求,对照 C、A、B、T 的时间和授权目标,考虑时钟差异;复用旧连接可能掩盖新认证失败。

在 A 确认获准客户端身份及到 B 的出站连接。在 B 确认来源对应 A,并存在目标请求。A 的出口可能经过 NAT,因此应登记转换后的预期来源,不能假定 B 看到的就是 A 的接口地址。

比较公网出口时,用明确设置了该 SOCKS 入口的浏览器配置核对网站看到的出口地址。该请求预期显示 B 的出口;它只能支持这一次请求的观察,不能替代逐跳记录,也不能证明所有应用都经过 B。

日志仅采集短时诊断范围并限制访问。若通过实例的官方日志配置临时启用访问日志,保留所需时段后恢复原策略。不收集载荷、不公开密码,也不能仅因缺少日志就断言流量已阻断。

步骤 5:检查 DNS、地址族及失效行为

下表是读者检查方法和预期策略,不是已测结果。每次只变一个条件,并发起新连接;下一项开始前恢复已知正常配置。

检查方法预期现象失败时处理
新建链式 TCP 请求A、B 记录可与 T 对应停止,核对 tag、TLS 与路由
依次给 A、B 填错误测试密码对应新请求均失败检查身份选择和意外路由
仅停止专用 A 实例新链式请求失败查直连分支或额外代理层
恢复 A,再仅停专用 B新链式请求失败不能将仅经过 A 的出口当成功
请求受控 IPv4-only、IPv6-only 目标声明支持的地址族均通过 B 到 T标明未支持范围,检查 B 的路由
对比名称请求与数字地址请求目标 DNS 路径符合所述解析设计分别检查客户端、A、B 和应用解析器
应用需要 UDP 或 QUIC本 TCP 示例不足以覆盖另选有文档和验证的设计

故障测试不能停共享服务。示例用 IP 字面量连接 A、B,避免两端引导解析,但 TLS 仍校验各自名称。SOCKS 转交的目标名称需要在相关出口路径解析;单独设置 routing.domainStrategy 不等于 DNS 防泄漏策略。[3][6]

若浏览器选择不同协议或绕过代理设置,需要单独核对。受控私网目标因地址冲突失败时,先解决重叠网段的拓扑问题,再加一跳不能区分两个同地址主机。

步骤 6:撤销测试并恢复基线

仅停止你启动的前台进程,确认回环监听已消失。撤销 A、B 的专用身份,并验证使用这些身份的新认证连接失败;若服务端撤销机制不关闭旧连接,还须终止残留测试会话。

仅恢复本次应用代理、临时日志和精确防火墙例外。按策略留下最少脱敏证据后删除私有配置副本。不能删除共享配置目录或清空防火墙来收尾。

独立回读管理访问、原监听、路由和 DNS。无法确认恢复时停止后续实验,使用恢复控制台。若保留代理链,另行确定凭据轮换、证书续期、日志留存和失效行为的运维责任。

总结

  • 先证明确实能用每一跳,再使用链式拨号。
  • 逐跳记录与最终出口观察共同组成证据。
  • 明确 TCP、DNS 和地址族限制。
  • 意外直连应视为验收失败。

常见问题

两跳是否自动带来匿名性?

不是。运营者、时间关联、账户和目标标识仍可能关联活动;增加一跳只是改变路径,不能据此证明匿名。

dialerProxy 应写在 A 还是 B 的出站上?

本客户端设计将它写在 B 的出站上,引用 A 的出站 tag,使连接 B 的底层连接经过 A。

可以把直连出站留作默认吗?

本验收策略不允许。未匹配流量必须拒绝;任何另行获准的直连分支都需要明确范围与失效检查。

一个网站显示 B,是否就证明 Xray 代理链成立?

不能。网站只看到自己的出口;还需关联 A、B 的证据,才能区分完整链路与直接连接 B。

本配置覆盖 UDP 和整台设备吗?

不覆盖。入口禁用 UDP,仅接受显式配置代理的应用;系统服务和其他应用仍使用各自原有网络路径。

排障时能否关闭证书校验?

不能。应分别检查证书名称、信任链、系统时间和端点;跳过校验会改变安全契约,而不是修复问题。

无法控制两跳时怎么办?

除非所有者提供必要授权和证据,否则停止此流程。未知第三方端点无法满足本文规定的验收检查。

来源:

  1. Xray-core — Release v26.3.27
  2. Project X — Trojan outbound and credential fields
  3. Project X — Sockopt
  4. Project X — Socks inbound
  5. Project X — Transport Configuration
  6. Project X — Routing
  7. curl — --noproxy and proxy environment variables

Sources checked 2026 年 10 月 11 日。


延伸阅读:

开启 3 天免费试用

注册即可免费体验全部高级功能。

*仅限新用户;每位用户只能获得一次试用。

逐跳搭建并验证 Xray 代理链:出口、DNS 与故障恢复 | AethoVPN