侧边栏壁纸
博主头像
いちごみるく

行动起来,活在当下

  • 累计撰写 69 篇文章
  • 累计创建 48 个标签
  • 累计收到 55 条评论

目 录CONTENT

文章目录

Nginx 监听 443:用 stream SNI 分流网站与 Xray REALITY

维护于 2026-10-01:保留 Nginx 预读 SNI 的做法,删除旧版 REALITY h2/grpc 组合与固定目标站示例。传输名称及 PROXY protocol 的配置应以实际安装的 Xray 版本为准。

一、适用条件

Nginx 监听 TCP 443,读取可见 ClientHello 的 SNI,把自有网站流量交给 TLS 网站后端,把配置的 REALITY 名称交给 Xray。Nginx 不在这里终止 TLS,REALITY 认证也仍由 Xray 负责。

这是一种端口复用结构,不能仅凭这个结构判断网络可用性、隐蔽性或安全性。REALITY 的目标应满足 Xray 传输配置的实际要求;第三方站点持有通配证书,不代表可以任意选其子域名作为有效目标。CDN 是否支持某种传输也应另行核实。

二、Nginx 配置

以下 www.example.org 是 REALITY serverNames 中一个已核实的目标名称占位值,.example.com 是自己的站点名称占位值。请先替换域名和端口。网站后端需要 TLS 证书,Xray 后端需要完整的 REALITY 入站配置。

stream {
    map $ssl_preread_server_name $backend {
        hostnames;
        .example.com    website;
        www.example.org reality;
        default         website;
    }
    upstream website { server 127.0.0.1:2096; }
    upstream reality { server 127.0.0.1:8443; }

    server {
        listen 443;
        listen [::]:443;
        ssl_preread on;
        proxy_pass $backend;
    }
}

hostnames 下 .example.com 同时匹配根域和子域;*.example.com 只匹配子域。原文的正则没有正确限定域名边界,应使用明确的主机名规则。没有 SNI、未知 SNI 和目标站被更换的情况,都应验证实际落到哪个后端。SNI 是客户端输入,不能作为访问认证。Nginx 官方模块文档说明了预读变量。

三、是否传递 PROXY protocol

先使用不发送 PROXY protocol 的上面配置,确认连接可用。此时 Xray 看到的来源通常是 127.0.0.1。若业务需要原始客户端地址,再同时配置发送端与接收端:Nginx 增加 proxy_protocol on;,所有可能命中的后端都要接受该前缀。

当前 Xray 文档中的 RAW 传输可使用下面的 streamSettings 片段:

{
  "network": "raw",
  "security": "reality",
  "rawSettings": {
    "acceptProxyProtocol": true
  }
}

这里省略了必须保留的 realitySettings 等入站配置,这个片段不是完整的可启动配置。旧版本可能使用 tcp/tcpSettings;不要混用不同版本的字段。参见 RAW 官方配置。其他传输若采用 sockopt.acceptProxyProtocol,应核对对应版本和传输的支持情况,不能把旧 h2 例子直接套到新版 XHTTP。

将 Xray 入站绑定 127.0.0.1,网站后端也绑定 loopback,并按PROXY protocol 说明设置可信来源。只改 Xray 接收而忘记网站分支,会让网站 TLS 握手失败。

四、验证

先分别校验 Xray 完整配置和 nginx -t,再 reload。用域名 HTTPS 验证网站,用当前客户端验证 REALITY,再检查日志里的后端选择和来源地址。还要测试未知 SNI 的兜底行为。本轮没有运行 Xray 或 Nginx,只完成静态配置与官方资料核查。

0

评论区