参考项目

https://github.com/XTLS/Xray-core/

https://github.com/DanOps-1/Xray-VPN-OneClick/blob/main/docs/installation-guide.md

适用情况

出口IP在当前网络环境下被监测,如校园网等,且在该网络环境下对梯子节点地址进行了屏蔽(无法使用)。使用VLESS reality方法将访问的地址伪装成国内的地址,从而实现绕过。通过服务器中转VPN同样实现代理的效果。

准备工作

公网服务器(Linux)、可用机场节点

原理

xray-code通常作为一个自建节点的项目,其中可以自定义vless reality协议,要达到伪装流量的效果就要用到该协议。配置文件中我们将outbounds出站设置成对应的可用机场订阅地址(vmess、vless、trojan、shadowsocks、socks5、http协议等),在inbounds入站统一改为vless reality协议,从而达到中转流量的效果。公网服务器在其中就起到一个中转转发的作用。

Reality 的工作原理

简化版:

客户端 → 代理服务器 (VPS)
↓
VPS 与 客户端 进行 TLS 握手,但 TLS 证书是 Google 的
↓
VPS 用 server_name=www.google.com 给客户端发证书
↓
DPI 看到:客户端在访问 Google,证书校验通过
↓
之后所有流量都加密(VLESS 协议)

关键 trick:VPS 自己不需要证书。它发给客户端的证书是 VPS 从真 Google 服务器实时取回来的。

更具体一些:

  1. 客户端发起 TLS ClientHello,SNI 写 www.google.com
  2. VPS 收到后做两件事并发:
    • 把 ClientHello 转发给真的 Google
    • 取回真 Google 的 ServerHello(含真证书)
  3. VPS 把真 ServerHello 返给客户端
  4. 客户端校验证书:通过(因为是真 Google 证书)
  5. 客户端用 public_key 验证 short_id:确认是 Reality 服务端而不是真 Google
  6. 后续数据走 VLESS 加密

DPI 视角:客户端访问 Google,握手正常,证书有效。检测不出代理。

xray-code搭建

0x01 初步安装

按照官方搭建命令进行安装

bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

如果服务器没有代理用以上脚本安装超时的话,可以通过访问https://github.com/XTLS/Xray-core/releases/download/v26.11.9/Xray-linux-64.zip下载内核包,然后复制到服务器安装

bash install-release.sh --local Xray-linux-64.zip install

img

img

安装完成后输入 xray 检测有没有装好

img

0x02 配置 Xray 服务

生成配置参数

VLESS + XTLS-Reality 需要几个关键参数:UUID、x25519 密钥对、Short ID。

  1. 生成 UUID

UUID 是客户端的唯一标识符。

cat /proc/sys/kernel/random/uuid

image-20261111202733910

  1. 生成 x25519 密钥对

Reality 协议使用 x25519 密钥对进行加密。

/usr/local/bin/xray x25519

image-20261111202744989

这里得到privatekey是私钥,是放在服务器里的,可以不用管。

password是公钥,要作为连接reality的参数。

  1. 生成 Short ID

Short ID 是一个 16 位十六进制字符串。

openssl rand -hex 8

image-20261111202752839

将生成的参数记录下来,后续配置会用到。

设置config.json

我们需要使用生成的参数创建 Xray 配置文件 /usr/local/etc/xray/config.json。生成前做好备份。

# 备份默认配置(如果存在)
sudo cp /usr/local/etc/xray/config.json /usr/local/etc/xray/config.json.bak

# 创建新配置
vim /usr/local/etc/xray/config.json

将以下内容复制到配置文件中,替换相应参数:

{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"port": 443,
"protocol": "vless",
"tag": "vless_tls",
"settings": {
"clients": [
{
"id": "5b6ec5d1-93a1-4056-b90f-9be61021144d",
"flow": "xtls-rprx-vision",
"email": "user@example.com"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "www.microsoft.com:443",
"xver": 0,
"serverNames": [
"www.microsoft.com"
],
"privateKey": "mNFnuEMXo8fDEZKB_eYdHmQ0ic5Qr2vuZwHCeEJGakM",
"shortIds": [
"f611741eea195fcf",
""
]
}
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
"unds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "block"
}
]
}
}

image-20261111202457033

配置参数说明

Inbound 配置

参数 说明 示例值
port 监听端口 443 (HTTPS 标准端口,更难被检测)
protocol 协议类型 vless
clients.id 客户端 UUID 替换为你生成的 UUID
flow 流控模式 xtls-rprx-vision (推荐)

Reality 配置

参数 说明 示例值
dest 伪装目标网站 www.microsoft.com:443
serverNames SNI 服务器名称 ["www.microsoft.com"]
privateKey 服务端私钥 替换为你生成的 PrivateKey
shortIds Short ID 列表 替换为你生成的 Short ID

伪装目标选择建议

测试配置文件

使用以下命令进行配置测试

sudo /usr/local/bin/xray run -test -config /usr/local/etc/xray/config.json

如果显示 “Configuration OK.”,说明配置文件格式正确。

image-20261111201614008

启动并验证服务

修改 systemd 服务配置

默认情况下,Xray 以 nobody 用户运行,可能没有权限监听 443 端口。需要修改为 root 用户。

# 修改服务文件中的用户
sudo sed -i 's/User=nobody/User=root/' /etc/systemd/system/xray.service

# 重新加载 systemd 配置
sudo systemctl daemon-reload

image-20261111201736901

启动 Xray 服务

这里建议重启一下服务,因为我们之前我们配置了新配置需要重启更新。

# 启动服务
sudo systemctl start xray

# 重启服务
sudo systemctl restart xray

# 查看服务状态
sudo systemctl status xray

# 设置开机自启
sudo systemctl enable xray

显示active就是运行成功了。运行失败注意一下配置文件里的端口是否被占用。

image-20261111202415477

0x03 生成订阅链接导入

使用以下脚本生成分享链接:

python3 << 'EOF'
import urllib.parse

# 替换为你的实际参数
UUID = "008f72b1-a919-4b63-9c98-6b5c7b308c82"
SERVER = "192.168.65.128" # 换成你的服务器公网 IP
PORT = "443"
PUBLIC_KEY = "NyyMkDh1FQtCyckh0rYjOEkOGjgPiZ1Gly4Kkqt3pmk"
SHORT_ID = "f4c97d2eeb44e6a0"
SNI = "www.qq.com"
FLOW = "xtls-rprx-vision"
REMARK = "Xray-Reality-Server"

pbk_encoded = urllib.parse.quote(PUBLIC_KEY, safe='')
vless_link = f"vless://{UUID}@{SERVER}:{PORT}?encryption=none&flow={FLOW}&security=reality&sni={SNI}&fp=chrome&pbk={pbk_encoded}&sid={SHORT_ID}&type=tcp&headerType=none#{REMARK}"

print(vless_link)
EOF

image-20261111202809506

复制生成的链接,然后打开v2rayN粘贴到订阅分组里,就出现对应的节点了

image-20261111202904855

image-20261111203003917

此时通过代理软件连接该节点就是以服务器的IP作为出口代理流量,通常有以下几个问题:

  • 服务器是境内服务器,无法代理外网流量
  • 服务器是境外服务器,但是访问外网很卡

以上为以服务器自建节点的教程。作为个人购买的服务器,使用这种方法不能满足我们的日常需求,所以这里要做的是把机场的订阅接入到Xray-code,个人服务器作为中转,出口走的是机场订阅的流量,入口走的是reality伪装域名。

xray-code接入机场订阅

接入原理

xray的配置文件支持这些协议:vmess、vless、trojan、shadowsocks、socks5、http,而大部分机场的订阅地址都属于这部分协议,因此我们可以把机场订阅的这些地址接入。

之前配置文件中的outbounds我们设置的是直连direct,这部分配置即为出站流量。可以根据不同协议设置对应的outbounds配置(具体不知道怎么配置可以问问AI)

image-20261111204046735

常见协议接入

1. VLESS

Reality(机场节点带 pbk/sid/sni 参数)

机场链接样例:

vless://d99db07c-...@节点地址:2087?security=reality&flow=xtls-rprx-vision&pbk=xxx&sid=xxx&sni=repost.aws&fp=ios#香港-01

出站配置:

{
"protocol": "vless",
"tag": "out_50006",
"settings": {
"vnext": [{
"address": "节点地址",
"port": 2087,
"users": [{"id": "d99db07c-...", "flow": "xtls-rprx-vision", "encryption": "none"}]
}]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"serverName": "repost.aws",
"fingerprint": "ios",
"publicKey": "pbk值",
"shortId": "sid值",
"spiderX": "/"
}
}
}

TLS(机场节点带 sni,非 Reality)

{
"protocol": "vless",
"tag": "out_50006",
"settings": {
"vnext": [{
"address": "节点地址",
"port": 443,
"users": [{"id": "uuid", "encryption": "none"}]
}]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {"serverName": "sni域名", "allowInsecure": false}
}
}

关键字段:

  • id=UUID
  • flow=流控(vision 才有)
  • security=reality/tls/none
  • realitySettings 里的 pbk/sid/sni/fp。

2. VMess

机场链接一般是 base64 的 JSON,解出来长这样:

{"v":"2","ps":"美国-01","add":"节点地址","port":"443","id":"uuid","aid":"0","scy":"auto","net":"ws","type":"none","host":"域名","path":"/path","tls":"tls","sni":"域名"}

出站(WS+TLS 为例):

{
"protocol": "vmess",
"tag": "out_50006",
"settings": {
"vnext": [{
"address": "节点地址",
"port": 443,
"users": [{"id": "uuid", "security": "auto", "alterId": 0}]
}]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"wsSettings": {"path": "/path", "headers": {"Host": "域名"}},
"tlsSettings": {"serverName": "sni域名", "allowInsecure": false}
}
}

关键字段:

  • id=UUID
  • alterId(新版一般 0)
  • security=vmess 加密方式(auto/aes-128-gcm/chacha20-poly1305/none)
  • network+wsSettings/tlsSettings 按机场给的 net/tls 来。

3. Trojan

机场链接:

trojan://密码@节点地址:443?sni=域名&type=tcp#香港-01

出站:

{
"protocol": "trojan",
"tag": "out_50006",
"settings": {
"servers": [{
"address": "节点地址",
"port": 443,
"password": "密码"
}]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {"serverName": "sni域名", "allowInsecure": false}
}
}

关键字段:

  • password=密码
  • tlsSettings.serverName=SNI

Trojan 必须走 TLS

4. Shadowsocks

机场链接:

ss://base64(加密方式:密码)@节点地址:8388#香港-01

出站:

{
"protocol": "shadowsocks",
"tag": "out_50006",
"settings": {
"servers": [{
"address": "节点地址",
"port": 8388,
"method": "aes-256-gcm",
"password": "密码"
}]
}
}

关键字段:

  • method=加密方式(aes-256-gcm / chacha20-poly1305 等)
  • password。

SS 没有 streamSettings。

5. SOCKS5

机场直接给 socks5 代理地址时用:

{
"protocol": "socks",
"tag": "out_50006",
"settings": {
"servers": [{
"address": "节点地址",
"port": 1080,
"users": [{"user": "账号", "pass": "密码"}]
}]
}
}

无账号密码就把 users 删掉。

6. HTTP

机场给 http 代理地址时用:

{
"protocol": "http",
"tag": "out_50006",
"settings": {
"servers": [{
"address": "节点地址",
"port": 8080,
"users": [{"user": "账号", "pass": "密码"}]
}]
}
}

多端口分发

常见的机场订阅有多个订阅地址,不同地址对应不同的端口。所以VPS作为VPN中转,最好也设置多端口分发的操作。

每个机场节点分配一个本地端口,客户端想用哪个机场端口就切哪个端口。

配置文件参考如下:

{
"log": { "loglevel": "warning" },

"inbounds": [
{
// 入站一
"port": 443,
"protocol": "vless",
"tag": "in_443",
"settings": {
"clients": [
{ "id": "1035902b-7d3d-4c3a-b5cb-05a78efb8478", "flow": "xtls-rprx-vision", "email": "user@example.com" }
], //UUID
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "www.qq.com:443",
"xver": 0,
"serverNames": ["www.qq.com"], //伪装域名
"privateKey": "0Crstbk2...GlEYX3o", //私钥
"shortIds": ["04c2...4686", ""] //shortIds
}
},
"sniffing": { "enabled": true, "destOverride": ["http", "tls"] }
},
{
// 入站二
"port": 50006,
"protocol": "vless",
"tag": "in_50006",
"settings": {
"clients": [
{ "id": "bf3c2508-4194-45f2-a0b6-719d44b3e1f3", "flow": "xtls-rprx-vision", "email": "user@example.com" }
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "www.qq.com:443",
"xver": 0,
"serverNames": ["www.qq.com"],
"privateKey": "iFxnKcFn...HQyRWGG5tWRlY",
"shortIds": ["571d7...c8a288", ""]
}
},
"sniffing": { "enabled": true, "destOverride": ["http", "tls"] }
},
{
// 入站三
"port": 50009,
"protocol": "vless",
"tag": "in_50009",
"settings": {
"clients": [
{ "id": "aea57ab7-4c86-497a-881d-3f53248a15b1", "flow": "xtls-rprx-vision", "email": "user@example.com" }
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "www.qq.com:443",
"xver": 0,
"serverNames": ["www.qq.com"],
"privateKey": "eF3sJfjDTO6K...-IgKA9aoHA",
"shortIds": ["244d97...ef7ad75", ""]
}
},
"sniffing": { "enabled": true, "destOverride": ["http", "tls"] }
}
],

"outbounds": [
{
// 出站一
"protocol": "vless",
"tag": "out_443", // 和 in_443 对应
"settings": {
"vnext": [{
"address": "02726.xxx.com",
"port": 2087,
"users": [
{ "id": "d99db07c-b326-4581-9370-53eef9056d9b", "flow": "xtls-rprx-vision", "encryption": "none" }
]
}]
},
// 机场订阅配置信息
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"serverName": "repost.aws",
"fingerprint": "ios",
"publicKey": "ALHje8E3d2T...Hj1Yzs7_i_E8",
"shortId": "7b16...a72ed0a",
"spiderX": "/"
}
}
},
{
// 出站二
"protocol": "vless",
"tag": "out_50006",
"settings": {
"vnext": [{
"address": "05557.xxx.com",
"port": 7443,
"users": [
{ "id": "d99db07c-b326-4581-9370-53eef9056d9b", "flow": "xtls-rprx-vision", "encryption": "none" }
]
}]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"serverName": "business.amazon.com.au",
"fingerprint": "chrome",
"publicKey": "CXt1liJy...tM_r_QL28",
"shortId": "b5f8...2b6f",
"spiderX": "/"
}
}
},
{
// 出站三
"protocol": "vless",
"tag": "out_50009",
"settings": {
"vnext": [{
"address": "39411.xxx.com",
"port": 2083,
"users": [
{ "id": "d99db07c-b326-4581-9370-53eef9056d9b", "flow": "xtls-rprx-vision", "encryption": "none" }
]
}]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"serverName": "sellercentral.amazon.ae",
"fingerprint": "safari",
"publicKey": "jfCghsA56F...jv5PsZKXI",
"shortId": "b9a06...73869a9",
"spiderX": "/"
}
}
},
// 这两个协议作为兜底,分别是直连和blackhole
{ "protocol": "freedom", "tag": "direct" },
{ "protocol": "blackhole", "tag": "block" }
],

"routing": {
"domainStrategy": "AsIs",
"rules": [
{ "type": "field", "ip": ["geoip:private"], "outboundTag": "direct" },
// 入站和出战一对一:谁从哪个端口进来,就从对应机场节点出去
{ "type": "field", "inboundTag": ["in_443"], "outboundTag": "out_443" },
{ "type": "field", "inboundTag": ["in_50006"], "outboundTag": "out_50006" },
{ "type": "field", "inboundTag": ["in_50009"], "outboundTag": "out_50009" }
]
}
}

配置完成后测试配置文件、重启服务:

# 配置测试
sudo /usr/local/bin/xray run -test -config /usr/local/etc/xray/config.json

# 重启服务
sudo systemctl restart xray

生成订阅地址

根据配置文件中的节点,每个节点都有对应的分享链接(对应的协议地址),根据不同节点生成对应的分享链接,最后拼接+base64加密就形成了可以导入各代理软件的订阅地址。再把最终内容挂到服务器端口的加密路径下,就实现了随时都可以导入的链接。

生成的订阅地址支持导入V2rayN、Clash

image-20261112165907235

image-20261112165718296

服务器生成订阅地址可以让AI去写,这里不作赘述。

伪装效果自测

将VPS里的节点导入到v2rayN:

image-20261111210701269

v2rayN先用一个无关节点

image-20261111210803139

打开wireshark选择当前网卡:

image-20261111210851739

浏览器用google作为测试:

image-20261111210933671

wireshark开始抓包,浏览器保持访问即可。

image-20261111211006547

同时v2rayN切换到刚刚导入的公网节点并启用代理:

image-20261111211035801

正常这个时候应该可以看到Google页面成功访问了,看到访问成功就可以暂停抓包了。

image-20261111211218419暂停抓包,wireshark用以下语句筛选,ip用你的公网服务器IP,port用你刚刚选择的v2rayN节点的端口

ip.addr == 120.x.x.141 && tcp.port == 50795

image-20261111211402380

筛选中如果能看到Client Hello (SNI=www.qq.com) 就代表伪装成功了,现在入站走的是www.qq.com,和我们配置文件里设置的一样。成功实现了伪装欺骗。

xray-code Web管理页面

为了xray-code快速接入机场节点,让AI写了一个web管理页面,可以自动安装服务并且导入订阅地址,同时支持伪装域名自定义、多端口监听、生成订阅地址等多个功能。

image-20261111230201289

image-20261111230228053

image-20261111230240607