VLESS + WebSocket + Cloudflare 保底方案:隐藏源站 IP 的备用线路
用 Cloudflare 代理域名和 Nginx 反代搭建 VLESS WebSocket 备用线路。

- 搭建 Cloudflare 代理域名入口
- 用 Nginx 反代 Xray WebSocket
- 区分 Reality SNI 和 WS SNI
- 域名托管到 Cloudflare
- 准备 ws 子域名
- 源站有可用 HTTPS 证书
来源与后续讨论
这里不是普通友情链接,而是读完文章后最应该跳转确认的地方:官网确认版本,GitHub 看源码和 Issue,第三方来源做交叉参考,X 帖子看后续补充和讨论。
Cloudflare Full 和 Full (strict) 模式说明
Xray 官方核心项目
Xray 官方安装脚本;作为补充来源保留,不占用 GitHub 主链接槽位。
Nginx 官方文档;Cloudflare 文档已作为主官方链接,本链接作为补充来源保留。
查看文章发布后的补充、读者反馈和最新讨论。
VLESS + WebSocket + Cloudflare 保底方案:隐藏源站 IP 的备用线路
Reality 直连线路的优点是链路短、延迟低,但它依赖客户端能直接访问 VPS IP。WebSocket + Cloudflare 的定位不同:把入口放到 Cloudflare 代理域名上,让客户端只连接 Cloudflare,再由 Cloudflare 转发到源站。
这条线路更适合作为保底方案。它不一定比 Reality 更快,但在你需要隐藏源站 IP、保留备用入口、或让连接路径经 Cloudflare 中转时很有用。
与 Reality 的区别
| 对比项 | Reality 直连 | WS + Cloudflare |
|---|---|---|
| 客户端连接 | VPS IP | Cloudflare 代理域名 |
| 源站 IP 暴露 | 会暴露给客户端 | 客户端侧不直接暴露 |
| 延迟 | 通常更低 | 通常更高 |
| 域名要求 | 不需要 | 需要域名托管到 Cloudflare |
| Nginx 角色 | 可选,用于 SNI 分流 | 必需,用于 WebSocket 反代 |
| 适合定位 | 主力线路 | 备用线路或源站隐藏 |
如果你还没读总览,可以先看 自建 VLESS 代理完全指南。
架构
本文采用更稳妥的 443 stream 入口:
客户端 | | VLESS + WebSocket + TLS vCloudflare:443 | | HTTPS 回源到 VPS:443 vNginx stream:443 | | SNI=ws.example.com vNginx HTTPS server:127.0.0.1:8080 | | WebSocket 反代 vXray WS inbound:127.0.0.1:10443这样公网只需要暴露 443。8080 和 10443 都是本机内部端口。
前置条件
你需要准备:
- 一个域名,DNS 托管到 Cloudflare。
- 一个子域名,例如
ws.example.com。 - VPS 上安装 Nginx,且支持 stream 模块。
- VPS 上安装 Xray-core。
- 一张源站证书。如果使用 Cloudflare Full (strict),建议使用 Let’s Encrypt 或 Cloudflare Origin Certificate。
Cloudflare 官方文档建议优先使用 Full 或 Full (strict) 模式。Full 不验证源站证书有效性,Full (strict) 会验证源站证书,更适合长期生产使用。
步骤一:配置 Cloudflare DNS
在 Cloudflare DNS 里添加记录:
| 类型 | 名称 | 内容 | 代理状态 |
|---|---|---|---|
| A | ws | <VPS_IP> | Proxied |
然后进入 SSL/TLS 设置:
- 推荐:Full (strict),源站使用有效证书。
- 可用但较弱:Full,源站可以使用自签证书。
- 不建议:Flexible,容易造成回源协议不一致和重定向问题。
发布前要确认 ws.example.com 解析出来的是 Cloudflare 代理 IP,而不是你的 VPS 原始 IP:
dig ws.example.com +short步骤二:安装 Xray 并生成 UUID
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ installxray uuidWebSocket 方案不使用 Reality 的 X25519 密钥对。你只需要 <UUID>。
步骤三:配置 Xray WebSocket inbound
编辑:
vim /usr/local/etc/xray/config.json写入:
{ "log": { "loglevel": "warning" }, "inbounds": [ { "tag": "ws-in", "listen": "127.0.0.1", "port": 10443, "protocol": "vless", "settings": { "clients": [ { "id": "<UUID>", "flow": "" } ], "decryption": "none" }, "streamSettings": { "network": "ws", "security": "none", "wsSettings": { "path": "/gl2025ws" } }, "sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"], "routeOnly": true } } ], "outbounds": [ { "protocol": "freedom", "tag": "direct" }, { "protocol": "blackhole", "tag": "block" } ], "routing": { "domainStrategy": "IPIfNonMatch", "rules": [ { "type": "field", "ip": ["geoip:private"], "outboundTag": "block" }, { "type": "field", "protocol": ["bittorrent"], "outboundTag": "block" } ] }}检查并启动:
xray -test -config /usr/local/etc/xray/config.jsonsystemctl daemon-reloadsystemctl enable --now xraysystemctl restart xrayss -tulnp | grep ':10443'/gl2025ws 是 WebSocket 路径,可以改成更难猜的字符串。服务端、Nginx 和客户端必须保持一致。
步骤四:配置 Nginx WebSocket HTTPS 后端
创建站点配置:
vim /etc/nginx/conf.d/ws.example.com.conf示例:
server { listen 127.0.0.1:8080 ssl http2; server_name ws.example.com; ssl_certificate /etc/letsencrypt/live/ws.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ws.example.com/privkey.pem; location /gl2025ws { if ($http_upgrade != "websocket") { return 404; } proxy_redirect off; proxy_pass http://127.0.0.1:10443; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location / { return 404; }}如果你使用 Cloudflare Origin Certificate,证书路径按实际保存位置填写。使用 Full (strict) 时,证书必须能被 Cloudflare 接受。
步骤五:配置 Nginx stream 入口
编辑:
vim /etc/nginx/nginx.conf在最外层加入:
stream { map $ssl_preread_server_name $backend { www.example.com 127.0.0.1:8080; # 一定要配置这个匹配上ws ws.example.com 127.0.0.1:8080; default 127.0.0.1:8080; } server { listen 443; ssl_preread on; proxy_pass $backend; proxy_connect_timeout 10s; proxy_timeout 300s; }}如果同一台机器还跑主站,请把主站域名也映射到对应 HTTPS 后端。并行版会在 Reality + WS 并行部署 里给出完整分流。
检查:
nginx -tsystemctl reload nginxss -tulnp | grep -E ':443|:8080|:10443'步骤六:配置防火墙
推荐只对外暴露 22 和 443:
ufw allow 22/tcpufw allow 443/tcpufw deny 8080/tcpufw deny 10443/tcpufw enableufw status如果你选择让 Cloudflare 直接回源到 8080,而不是通过 443 stream 回源,那么 8080 只能限制给 Cloudflare IP 段访问。不要把 8080 无限制开放到公网。
步骤七:验证 WebSocket 链路
先验证 Xray 内部 WebSocket inbound:
curl -si http://127.0.0.1:10443/gl2025ws \ -H 'Connection: Upgrade' \ -H 'Upgrade: websocket' \ -H 'Host: ws.example.com' \ -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \ -H 'Sec-WebSocket-Version: 13' \ | grep -iE '^HTTP|upgrade'预期能看到 101 Switching Protocols。如果返回 400 或无响应,先检查 Xray 的 path、端口和服务状态。
再验证 Nginx HTTPS 后端:
curl -k -si https://127.0.0.1:8080/gl2025ws \ -H 'Connection: Upgrade' \ -H 'Upgrade: websocket' \ -H 'Host: ws.example.com' \ -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \ -H 'Sec-WebSocket-Version: 13' \ | grep -iE '^HTTP|upgrade'最后用客户端从外部连接 ws.example.com:443,确认能完成握手并访问网络。
客户端参数
| 参数 | 值 |
|---|---|
| 协议 | VLESS |
| 地址 | ws.example.com |
| 端口 | 443 |
| UUID | <UUID> |
| Flow | 留空 |
| 传输 | ws |
| 路径 | /gl2025ws |
| TLS | tls |
| SNI | ws.example.com |
| Host | ws.example.com |
| Fingerprint | chrome |
小结
WS + Cloudflare 不是 Reality 的简单替代品,而是一条不同定位的备用链路:
- 客户端连接 Cloudflare 代理域名,而不是 VPS IP。
- Cloudflare SSL/TLS 模式建议使用 Full 或 Full (strict)。
- Nginx 负责 HTTPS 终止和 WebSocket Upgrade 反代。
- Xray WS inbound 只监听本机端口。
- 8080 和 10443 不应无限制暴露到公网。
如果你想把 Reality 主力和 WS 保底放在同一台机器上,继续看 Reality 主力 + WS 保底并行部署。
按文章步骤复核自己的 VPS、域名、端口和客户端参数。
这篇已经可以直接看完,可以继续下一篇。