适用于:已有一台带公网 IP 的 VPS、可控制自己的域名解析,并希望通过 Xray + Nginx + Cloudflare 搭一条可长期维护的个人代理链路。

整体链路如下:

Text
客户端
  ↓
Cloudflare(代理 + Edge TLS)
  ↓
Nginx :443(源站 TLS)
  ├─ /      → 可选静态首页
  └─ /ray   → 127.0.0.1:10000(Xray WebSocket 入站)

Why this matters

如果你已经有一台公网 VPS,那么把代理入口、TLS 和 Web 服务入口整理到同一条链路里,会比“只开一个裸端口”更容易维护。Nginx 统一接管 443,Xray 只监听本地端口,后续你要加静态页、反向代理或证书调整时都比较顺手。

这套方案的核心是:客户端走 VLESS + WebSocket,Cloudflare 负责公网边缘接入,Nginx 负责源站 TLS 和反向代理,Xray 在本地提供实际代理服务。这样做的好处是结构清楚,组件边界明确,排错时也容易逐层验证。

准备工作

开始之前,先准备下面这些东西:

  • 一台带公网 IP 的 VPS。原文使用的是 Vultr。
  • 一个自己的域名,例如 vpn-sg.example.com。
  • 将域名托管到 Cloudflare。

Cloudflare 域名配置

先在 Cloudflare 中新增一条 A 记录,把子域名指向你的 VPS 公网 IP。

Cloudflare DNS 记录配置

然后在 SSL/TLS 中把模式切到 Full (strict),确保 Cloudflare 到源站这一段也校验证书。

Cloudflare SSL 模式配置

接着在 SSL/TLS -> 源服务器 中签发一张 Cloudflare Origin CA 证书。建议只给当前代理子域名使用,生成后把证书和私钥都保存下来,稍后写入 Nginx。

Cloudflare Origin CA 证书配置

安装 Nginx

先安装并启动 Nginx:

Bash
sudo apt update
sudo apt install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
sudo systemctl status nginx

然后为当前域名准备证书目录,把刚才从 Cloudflare 拿到的源证书和私钥分别写入文件:

Bash
sudo mkdir -p /etc/nginx/ssl/vpn.sg

sudo vim /etc/nginx/ssl/vpn.sg/origin.pem
sudo vim /etc/nginx/ssl/vpn.sg/origin.key

安装 Xray

切到 root 用户后执行官方安装脚本:

Bash
sudo su - root
bash <(curl -Ls https://raw.githubusercontent.com/XTLS/Xray-install/main/install-release.sh)

安装完成后先确认版本:

Bash
xray version

再生成一个 UUID,后面会写到客户端配置里:

Bash
cat /proc/sys/kernel/random/uuid

配置 Xray

编辑配置文件:

Bash
vim /usr/local/etc/xray/config.json

写入下面这份最小配置。注意把 clients.id 改成刚才生成的 UUID,监听端口保持为本地 10000:

JSON
{
  "log": {
    "loglevel": "warning",
    "access": "/var/log/xray/access.log",
    "error": "/var/log/xray/error.log"
  },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 10000,
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "<你的 UUID>"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "ws",
        "security": "none",
        "wsSettings": {
          "path": "/ray"
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom"
    }
  ]
}

配置完成后先做语法检查:

Bash
xray run -test -config /usr/local/etc/xray/config.json

没有报错再重启并设置开机自启:

Bash
systemctl restart xray
systemctl enable xray

最后确认监听端口已经起来:

Bash
ss -tlnp | grep 10000

预期能看到类似输出:

Text
LISTEN 0      4096       127.0.0.1:10000      0.0.0.0:*    users:(("xray",pid=80276,fd=4))

配置 Nginx 反向代理

创建站点配置文件:

Bash
sudo vim /etc/nginx/sites-available/vpn-sg.conf

写入如下配置。这里让 Nginx 统一监听 80/443,HTTP 自动跳转到 HTTPS,/ray 代理到本地 Xray 的 WebSocket 入站:

Nginx
server {
    listen 80;
    server_name vpn-sg.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name vpn-sg.example.com;

    ssl_certificate     /etc/nginx/ssl/vpn.sg/origin.pem;
    ssl_certificate_key /etc/nginx/ssl/vpn.sg/origin.key;

    ssl_protocols TLSv1.2 TLSv1.3;

    location = / {
        default_type text/html;
        return 200 '<html><body><h1>OK</h1></body></html>';
    }

    location /ray {
        proxy_redirect off;
        proxy_pass http://127.0.0.1:10000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 86400;
    }
}

启用配置并重载 Nginx:

Bash
sudo ln -s /etc/nginx/sites-available/vpn-sg.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

如果服务器启用了 ufw,记得把 80、443 和 SSH 端口放开:

Bash
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 22/tcp
sudo ufw enable

Practical checks

可以按下面这个顺序排查整条链路:

  1. 确认 Xray 只监听在本地:
Bash
ss -tlnp | grep xray
  1. 浏览器访问自己的域名:
Text
https://vpn-sg.<你的域名>.com

如果首页能直接返回 OK,说明 Cloudflare -> Nginx -> 源证书 这一段已经通了。

  1. 如果访问失败,重点检查这些位置:
  • Cloudflare 的 SSL 模式是否为 Full (strict)。
  • 源站证书与私钥是否写入了正确路径。
  • nginx -t 是否通过。
  • VPS 防火墙与云厂商安全组是否开放了 80/443。
  • Xray 的 wsSettings.path 与 Nginx 的 location /ray 是否完全一致。

客户端连接

Android 可以使用 v2rayNG,Windows 可以使用 v2rayN,协议选择 VLESS。核心参数如下:

Text
地址: vpn-sg.example.com
端口: 443
UUID: <你的 UUID>
传输: ws
路径: /ray
TLS: 开启
SNI: vpn-sg.example.com
Host: vpn-sg.example.com

VLESS 客户端配置示例

Closing notes

这套配置的重点不在“命令要敲多少”,而在几个边界要保持一致:

  • DNS 子域名、Nginx server_name、客户端 SNI/Host 必须一致。
  • Cloudflare 到源站要使用有效的 Origin CA 证书。
  • Xray 的 WebSocket 路径要和 Nginx 反向代理路径一致。
  • Xray 监听本地回环地址即可,不需要直接暴露公网端口。

如果后续继续扩展,可以优先补上这几项:

  • 把 UUID 和证书私钥安全保存,不要直接外传。
  • 为 VPS 增加 SSH 加固和 Fail2Ban。
  • 给根路径返回一个更像正常站点的静态页,减少过于明显的默认特征。

升级方案:https://www.rendering.me/blog/ebfGdo

感谢读到这里

日志还会继续,欢迎常来。

返回首页