VLESS 套 CDN:用自有域名配置 WebSocket 或 XHTTP

VLESS 套 CDN:用自有域名配置 WebSocket 或 XHTTP

Jason Chen
2026年10月14日· 7 分钟阅读

VLESS 套 CDN,是在客户端与你自己控制的 Ubuntu VPS 之间加一层 CDN 边缘节点:客户端连接边缘上的自有域名,CDN 只把一个秘密路径转发回源站,Xray 只在本机回环地址上接收。本文使用 Xray v26.3.27、源站 Nginx 反向代理,并以 Cloudflare 作为 CDN 示例,传输方式在 WebSocket 与 XHTTP 中二选一。[1]

关键要点

  • 动手前先读 CDN 当前条款;隧道能用,不代表这种用法被允许。
  • 回源使用 Cloudflare Full (strict) 这类严格 TLS 模式,不用跳过证书校验的模式。
  • Xray 只监听 127.0.0.1,每种传输只由 Nginx 转发一个秘密路径。
  • 套 CDN 时 XHTTP packet-up 是稳妥选择,WebSocket 更简单也更老。
  • 把“客户端连上了”和“流量走了 CDN”分开验证:分别测试直连源站、错误路径与错误 UUID 被拒。

本文依据文末官方来源整理,未完成完整端到端实测。版本号只说明所依据的文档,不是作者实测环境。开始前,先按自建规划与恢复清单明确归属、访问权限和恢复方式。

你真的需要 VLESS 套 CDN 吗?

只在你拥有或有权管理的 VPS 和域名上操作。你需要不依赖代理的控制台访问、按已核验 known_hosts 严格校验主机密钥的 SSH,以及现有 Nginx、防火墙和 Xray 文件的备份。不要借用他人域名、免费子域名服务或第三方 Worker 来承载自己的入口。

CDN 会改变谁能看到并终结你的流量。边缘节点先解密客户端的 TLS,再向源站建立第二条 TLS 连接,因此 CDN 运营方会在中间经手你的代理流。如果你只需要稳定的日常出口,不想自己维护证书、Nginx 和 Xray,先评估托管 VPN 是否更省事,再决定是否多加一个环节。边缘与源站的一般关系,可参考 CDN 如何位于你和网站之间。

配置之前先核对 CDN 条款

Cloudflare 服务专属条款保留这样的权利:在未购买相应付费服务的情况下,若用 CDN 提供视频或不成比例的大文件,可以停用或限制其 CDN 使用。[2] 承载流媒体或大量下载的代理可能落入这一情形。请阅读当前条款和你所用套餐的限制;如果需要一条不受 CDN 政策影响的路径,保留一个直连入口,例如 VLESS REALITY 服务器。

本文的任何步骤都不能让线路“不会被封”。CDN 可能重启边缘服务器、执行空闲超时或调整功能;Cloudflare 也写明,发布更新时可能中断已打开的 WebSocket 连接。[3]

WebSocket 还是 XHTTP:哪种传输适合走 CDN?

两种传输都把 VLESS 装在 HTTP 里,因此能代理 HTTP 的 CDN 都可以转发。区别在于数据流的组织方式,以及 CDN 需要放行什么。

问题VLESS WebSocket TLS 配置VLESS XHTTP 套 CDN(packet-up)
数据如何传输一条升级后的 HTTP/1.1 连接上行拆成编号 POST 请求,下行是流式 GET
对 CDN 的要求该区域开启 WebSockets普通 HTTP 代理即可,不需要协议升级
Project X 的建议文档建议改用 XHTTP,因为 WebSocket 的 ALPN 是 http/1.1packet-up 被描述为在 CDN 和反代后兼容性最强的模式
源站反代要求传递 Upgrade 与 Connection 头请求体和响应体都不缓冲
主要取舍简单,客户端支持广泛较新,客户端和服务端内核都必须支持

Project X 的 WebSocket 页面建议改用 XHTTP,以避开 WebSocket 明显的 http/1.1 ALPN 特征。[4] XHTTP 传输条目指向项目的 XHTTP 讨论帖;帖中建议在 CDN 或反向代理不放行其它模式时选择 packet-up,并指出经 Cloudflare 使用 stream-up 需要开启 gRPC 支持。[5][6] 本文把 XHTTP 固定为 packet-up,让源站保持普通的 HTTP/1.1 反代。如果你已经有直连的 XHTTP 入口,请让它与这个 CDN 入口保持独立。

步骤 1:准备域名、证书和源站防火墙

创建一条指向 VPS 的 DNS 记录,例如 proxy.example.com,并设为经 CDN 代理。在 Cloudflare 中把该区域的 SSL/TLS 模式设为 Full (strict):边缘节点会校验源站证书,证书可以来自公共 CA,也可以来自 Cloudflare Origin CA。[7] 不要使用 Flexible 或 Full,前者回源不加密,后者接受无效证书。

如果选择 WebSocket,在区域的 Network 设置里开启 WebSockets。[3] 把源站证书和私钥放在 /etc/ssl/vless-cdn/fullchain.pem 与 /etc/ssl/vless-cdn/privkey.pem,属主为 root,私钥权限 0600。

把源站 TCP 443 限制为只接受 CDN 公布的地址段,客户端就无法绕过边缘直连。[8] 保留 SSH 规则,以及仍需访问服务器的证书续期路径。CDN 更新地址段时要重新核对,过期的名单可能让入口在没有提示的情况下失效。

步骤 2:让 Xray 入站只监听本机回环

从官方 v26.3.27 发布页下载 Linux 64 位压缩包,查看发布说明和官方提供的校验材料,把可执行文件安装到 /opt/xray-cdn/v26.3.27/xray,属主 root,权限 0755。用 /opt/xray-cdn/v26.3.27/xray uuid 生成 UUID,并为每种传输选一个随机路径段。创建不可登录的系统账号 xray-cdn,把下面内容保存为 /etc/xray-cdn/server.json,权限 0640,属主 root:xray-cdn。[1]

{
  "log": {"loglevel": "warning"},
  "inbounds": [
    {
      "tag": "vless-ws",
      "listen": "127.0.0.1",
      "port": 10001,
      "protocol": "vless",
      "settings": {"clients": [{"id": "REPLACE_UUID"}], "decryption": "none"},
      "streamSettings": {"network": "ws", "wsSettings": {"path": "/ws-REPLACE_SECRET"}}
    },
    {
      "tag": "vless-xhttp",
      "listen": "127.0.0.1",
      "port": 10002,
      "protocol": "vless",
      "settings": {"clients": [{"id": "REPLACE_UUID"}], "decryption": "none"},
      "streamSettings": {"network": "xhttp", "xhttpSettings": {"path": "/xh-REPLACE_SECRET/", "mode": "packet-up"}}
    }
  ],
  "outbounds": [{"tag": "direct", "protocol": "freedom"}]
}

只保留你所选传输对应的那个入站。两个入站都不启用 TLS,因为 TLS 在同一台主机的 Nginx 上终结;这只在两者都监听 127.0.0.1 时才安全。VLESS 的 decryption: none 表示 VLESS 本身不额外加密。用 sudo -u xray-cdn /opt/xray-cdn/v26.3.27/xray run -test -config /etc/xray-cdn/server.json 检查配置,再以 xray-cdn 账号作为 systemd 服务运行。

步骤 3:用 Nginx 只转发秘密路径

为 proxy.example.com 添加一个 server 块。除秘密路径外,所有路径都返回 404,扫描源站的人只会看到一个背后什么都没有的普通 HTTPS 站点。

server {
    listen 443 ssl;
    server_name proxy.example.com;
    ssl_certificate     /etc/ssl/vless-cdn/fullchain.pem;
    ssl_certificate_key /etc/ssl/vless-cdn/privkey.pem;

    location = /ws-REPLACE_SECRET {
        proxy_pass http://127.0.0.1:10001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 300s;
    }

    location /xh-REPLACE_SECRET/ {
        proxy_pass http://127.0.0.1:10002;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_request_buffering off;
        proxy_set_header Host $host;
        proxy_read_timeout 300s;
    }

    location / { return 404; }
}

WebSocket 块传递 Upgrade 和 Connection 头,否则逐跳代理会把它们丢掉。[9] XHTTP 块关闭双向缓冲;在 proxy_http_version 1.1 下,Nginx 可以边收边把请求体交给 Xray,而不是先收齐再转发。[10] XHTTP 用前缀匹配,因为每个请求都会在路径后追加自己的后缀。先运行 sudo nginx -t,通过后再重载。

步骤 4:让客户端连接 CDN 上的域名

在 Ubuntu 客户端安装同一版本的 Xray,为 WebSocket 路线保存一个私有 client.json(权限 0600):

{
  "inbounds": [{"listen": "127.0.0.1", "port": 1083, "protocol": "socks", "settings": {"auth": "noauth", "udp": false}}],
  "outbounds": [{
    "tag": "cdn-ws",
    "protocol": "vless",
    "settings": {"vnext": [{"address": "proxy.example.com", "port": 443, "users": [{"id": "REPLACE_UUID", "encryption": "none"}]}]},
    "streamSettings": {
      "network": "ws",
      "security": "tls",
      "tlsSettings": {"serverName": "proxy.example.com", "allowInsecure": false},
      "wsSettings": {"path": "/ws-REPLACE_SECRET"}
    }
  }]
}

选择 XHTTP 时,保留同一个出站,只替换传输字段:

"network": "xhttp",
"xhttpSettings": {"path": "/xh-REPLACE_SECRET/", "mode": "packet-up"}

地址和 serverName 都写你的域名,不写源站 IP,这样客户端的 TLS 会话在边缘终结,证书校验保持开启。运行 xray run -test -config ./client.json,然后在前台启动客户端,只让一个测试应用使用 SOCKS5 127.0.0.1:1083。

如何证明流量确实经过 CDN?

通过代理打开一个网页,只能说明“某条路径”可用。每次只改一个条件,分别检查每道边界,测试之间恢复可用的配置。

检查方法预期现象不符时的处理
对自己的端点执行 curl --proxy socks5h://127.0.0.1:1083 https://check.example.net/health经代理得到预期响应先看 Nginx 和 Xray 日志,再考虑换传输
dig +short proxy.example.com返回 CDN 边缘地址,而不是 VPS IP记录没有走代理;先修 DNS,再信任其它结果
在外部主机执行 curl --resolve proxy.example.com:443:ORIGIN_IP https://proxy.example.com/连接超时或被拒绝源站防火墙仍放行非 CDN 来源
经边缘请求 https://proxy.example.com/wrong-pathNginx 返回 404location 范围过宽,转发了多余路径
客户端副本换成另一个有效 UUID代理请求失败确认旧客户端进程已停止、UUID 列表正确
客户端副本使用边缘证书上没有的 serverNameTLS 校验失败保持 allowInsecure: false,不要靠关闭校验来“修复”

然后在设置了本地 SOCKS 端口的浏览器中打开 IP 地址检测工具。它应显示 VPS 的出口地址:CDN 只承载入站这一段,Xray 的 freedom 出站从服务器发出。这个结果只覆盖浏览器这一个请求,不代表其它应用的 DNS、IPv6 或 UDP。

如果 WebSocket 请求失败,而同一边缘上的普通 HTTPS 正常,可以用 WebSocket 失败但 HTTPS 正常的排查方法区分 CDN 设置、代理和客户端问题。XHTTP 方面,如果 CDN 会在空闲后切断下行,表现为长请求中途断开;XHTTP 讨论帖指出,Cloudflare 会切断 100 秒没有实际数据的 HTTP 响应。[6]

如何回退或停用 CDN 入口?

修改前,私下保存 server.json、Nginx 站点文件、防火墙规则和客户端文件的副本。客户端回退就是恢复之前的配置,并用一次新请求确认。服务器端停用新的 Nginx 站点和 xray-cdn 服务,重载 Nginx,再用 sudo ss -lntp 确认 10001 和 10002 端口已无人监听。

彻底停用时,删除这条代理 DNS 记录或关闭它的 CDN 代理,从剩余配置中删除该 UUID;如果源站证书不再有其它用途,就吊销或删除它。只为 CDN 设的防火墙规则最后再删,先弄清服务器上还有哪些站点依赖 443 端口。升级也按同样方式:准备新的版本目录,对两个文件运行 -test,重做上面的验证表后再切换服务。

总结

  • 配置前先确认 CDN 条款和你自己的恢复通道。
  • 回源使用严格 TLS 模式,Xray 只经本机回环上的 Nginx 对外提供服务。
  • 想简单选 WebSocket,想稳妥走 CDN 选 XHTTP packet-up,同一客户端不要两者混用。
  • 用拒绝测试证明 CDN 路径,而不是只看一次网页成功打开。

常见问题

VLESS 前面加 CDN,会比直连入口更私密吗?

不会自动更私密。CDN 会终结客户端的 TLS,再自行连接你的源站,因此它能看到承载 VLESS 流量的那段代理 HTTP 流,隐私边界要按这一点来评估。

为了省事,能用 Cloudflare 的 Flexible 模式吗?

不建议。Flexible 从边缘到源站不使用 TLS;Full (strict) 会校验源站证书,既保护第二段传输,也能防止有人冒充你的源站接收流量。

WebSocket 和 XHTTP 能放在同一个域名上吗?

可以,像示例那样分别使用独立的秘密路径和独立的 Nginx location 即可。但每个客户端只用一种传输,出现故障时才能判断是哪条路径的问题。

为什么这里的 XHTTP 用 packet-up 而不是 auto?

项目指南把 packet-up 列为在 CDN 和反向代理后兼容性最强的模式,它也让源站保持普通 HTTP/1.1,不需要额外的 gRPC 设置。

把源站藏在 CDN 后面,就能挡住所有直连扫描吗?

只有源站防火墙只放行 CDN 地址段时才行。没有这条规则,任何知道 VPS 地址的人都可以直接连接 Nginx,完全绕过边缘节点。

这样能保证代理在任何网络封锁下都可用吗?

不能。经 CDN 的入口仍可能被限速、过滤,或被 CDN 自身限制,边缘节点重启也会关闭已打开的连接,所以请另外保留一条恢复路径。

源站防火墙里的 CDN 地址段多久更新一次?

按固定周期核对 CDN 公布的地址段,并在收到服务商通知后立即检查。过期的放行名单会悄悄拒绝来自边缘节点的正常回源连接。

免责声明: 本文仅供一般信息参考,不构成法律、技术或其他专业建议。我们不保证内容的准确性、完整性或时效性。

来源:

  1. Xray-core release v26.3.27 — https://github.com/XTLS/Xray-core/releases/tag/v26.3.27
  2. Cloudflare Service-Specific Terms — https://www.cloudflare.com/service-specific-terms-application-services/
  3. Cloudflare Docs: WebSockets — https://developers.cloudflare.com/network/websockets/
  4. Project X: WebSocket transport — https://xtls.github.io/en/config/transports/websocket.html
  5. Project X: XHTTP (SplitHTTP) transport entry — https://xtls.github.io/en/config/transports/splithttp.html
  6. Project X: XHTTP: Beyond REALITY — https://github.com/XTLS/Xray-core/discussions/4113
  7. Cloudflare Docs: SSL/TLS encryption modes — https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/
  8. Cloudflare IP ranges — https://www.cloudflare.com/ips/
  9. NGINX: WebSocket proxying — https://nginx.org/en/docs/http/websocket.html
  10. NGINX: ngx_http_proxy_module — https://nginx.org/en/docs/http/ngx_http_proxy_module.html

Sources checked 2026 年 10 月 14 日。

延伸阅读:

开启 3 天免费试用

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

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

VLESS 套 CDN:用自有域名配置 WebSocket 或 XHTTP | AethoVPN