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

行动起来,活在当下

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

目 录CONTENT

文章目录

Xray TLS 入口按 SNI 回落到多个网站与 DoH 服务

本文讲解 Xray 终止 TLS 后的 SNI fallback;需要保持 TLS 握手不变的方案见 Nginx stream 分流。

Xray VLESS + TLS 可以占用 443,并把普通 HTTPS 请求按 SNI 回落到本机不同网站。TLS 在 Xray 中终止,所以后端收到的是解密后的协议流量;xver: 1 表示在流量前增加 PROXY protocol v1,并不表示后端再次收到 TLS。

示例使用自己控制的 site.example.com 和 dns.example.com,两者指向同一服务器。前者提供网站,后者只开放 DoH 的 /dns-query;AdGuard Home 管理界面留在内部访问路径。证书覆盖这两个名称,可参考 ACME 泛域名证书。

Xray 入站

下面是已有 Xray 配置中的入站片段。替换 UUID、证书路径和域名,保留自己的出站与路由;示例只协商 HTTP/1.1,避免把 h2 流量错误送给只接受 HTTP/1.1 的端口。

{
  "inbounds": [
    {
      "listen": "0.0.0.0",
      "port": 443,
      "protocol": "vless",
      "settings": {
        "clients": [
          { "id": "00000000-0000-4000-8000-000000000001" }
        ],
        "decryption": "none",
        "fallbacks": [
          { "name": "dns.example.com", "dest": "127.0.0.1:8081", "xver": 1 },
          { "dest": "127.0.0.1:8080", "xver": 1 }
        ]
      },
      "streamSettings": {
        "method": "raw",
        "security": "tls",
        "tlsSettings": {
          "alpn": ["http/1.1"],
          "certificates": [
            {
              "certificateFile": "/etc/ssl/xray/fullchain.pem",
              "keyFile": "/etc/ssl/xray/private.key"
            }
          ]
        }
      }
    }
  ]
}

当前文档使用 method: raw;旧版本常使用 network: tcp/raw。按安装版本核对传输字段,不要直接把新配置写进旧脚本生成的文件。UUID 必须重新生成,上述固定值只能用于展示结构。若服务通过 IPv6 提供入口,还要检查实际监听与防火墙,不能假设 0.0.0.0 会同时接收 IPv6。

这里的 SNI 匹配负责选择回落目标。ALPN 的优先级由 TLS 配置的 alpn 与客户端协商决定,不是靠交换 fallback 数组里的 h2 和 http/1.1 条目实现。需要 h2 时另外准备支持明文 HTTP/2(h2c)的本机后端,再添加匹配的 ALPN 回落规则。VLESS、Fallback、TLS

本机 Nginx 接收回落

Nginx 必须同时启用 HTTP realip 模块、在 listen 中接收 PROXY protocol,并只信任实际转发者。下面两个端口只绑定 loopback,不能额外暴露到公网。

server {
    listen 127.0.0.1:8080 proxy_protocol;
    server_name site.example.com;
    set_real_ip_from 127.0.0.1;
    real_ip_header proxy_protocol;
    root /srv/www/site;
    index index.html;
    location / { try_files $uri $uri/ =404; }
}

server {
    listen 127.0.0.1:8081 proxy_protocol;
    server_name dns.example.com;
    set_real_ip_from 127.0.0.1;
    real_ip_header proxy_protocol;

    location = /dns-query {
        # 替换为自己的固定客户端公网地址;动态客户端需另选认证方式。
        allow 192.0.2.10;
        deny all;
        proxy_pass https://127.0.0.1:8443;
        proxy_set_header Host dns.example.com;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_ssl_server_name on;
        proxy_ssl_name dns.example.com;
        proxy_ssl_verify on;
        proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
        proxy_ssl_protocols TLSv1.2 TLSv1.3;
    }
    location / { return 404; }
}

假设 AdGuard Home 的 HTTPS/DoH 已监听 127.0.0.1:8443,证书对 dns.example.com 有效且链能被所列 CA 文件验证;若使用自签证书,改为信任自己的 CA 并保持名称校验。CA bundle 路径随系统不同,不能通过 proxy_ssl_verify off 绕过配置问题。192.0.2.10 是文档地址,必须替换,否则真实客户端会被拒绝。

访问控制使用 realip 还原后的客户端地址。直接向后端发送普通 HTTP 会因为缺少 PROXY 前缀失败;公网用户无法直接访问 loopback 后端,也不能自行提供可信 PROXY 地址。只代理 /dns-query 可以避免把 AdGuard Home 登录、设置和管理 API 一起暴露;需要管理时通过 VPN 或内部入口。

可选:代理自己的 HTTPS 网站

如果网站不在本机静态目录,将第一个 server 的 location 改为自己的上游。域名、Host、SNI 与证书名称需要对应,开启上游证书校验:

location / {
    proxy_pass https://origin.example.com;
    proxy_set_header Host origin.example.com;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_ssl_server_name on;
    proxy_ssl_name origin.example.com;
    proxy_ssl_verify on;
    proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
    proxy_ssl_protocols TLSv1.2 TLSv1.3;
}

应用应配置公开域名和可信代理地址,重定向、Cookie、CSP 与绝对 URL 需要按应用处理,不能靠全局 sub_filter 可靠地改写。HSTS preload 也不是通用反代配置,确认整个域名及子域长期支持 HTTPS 后才考虑它。Nginx HTTPS 上游校验、realip

应用配置前后检查

先用实际的 Xray 二进制执行配置检查,再以实际 Nginx 的 -t 检查配置,通过后重载对应服务。例如 xray-agent 项目与手工安装可能使用不同的配置组织,/etc/nginx/conf.d/alone.conf 不是所有部署通用的固定路径。

从外网用真实证书访问两个域名,分别检查网站、DoH GET/POST、未授权请求拒绝、管理路径 404 与访问日志中的来源地址。测试通过的范围必须包含这整条链路;单独确认 Nginx 语法正确不能证明 Xray 回落和 AdGuard Home 的证书/访问控制已经工作。

0

评论区