Files
ttx-project-doc/运维/VLESS-Reality与AnyTLS双协议部署指南.md

491 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VLESS + REALITY 与 AnyTLS 双协议部署指南
## 1. 方案目标
在同一台 Linux 服务器上部署两个相互独立的代理入口:
| 优先级 | 协议 | 服务端实现 | 监听端口 | 用途 |
| --- | --- | --- | --- | --- |
| 主力 | VLESS + TCP + XTLS Vision + REALITY | Xray-core | `443/TCP` | 日常主要连接 |
| 备用 | AnyTLS | AnyTLS-go | `8443/TCP` | 主力入口不可用时切换 |
```text
客户端
|-- 主力节点 ------ TCP/443 ------> Xray: VLESS + REALITY ------> Internet
`-- 备用节点 ------ TCP/8443 ------> AnyTLS-go -----------------> Internet
```
两个服务不互相转发,也不共享端口。所谓“主力/备用”由客户端节点选择或客户端故障转移策略决定;服务器不会自动把 VLESS 连接切换到 AnyTLS。
本文示例版本和核对日期:
| 软件 | 示例版本 | 核对日期 |
| --- | --- | --- |
| Xray-core | `v26.3.27` | 2026-07-25 |
| AnyTLS-go | `v0.0.13` | 2026-07-25 |
## 2. 部署前准备
准备以下参数,文档中的尖括号内容均为待替换占位符:
| 参数 | 用途 |
| --- | --- |
| `<SERVER_IP>` | 服务器公网 IP;连接 REALITY 不要求拥有域名 |
| `<REALITY_TARGET>` | REALITY 借用 TLS 外观的目标站点域名 |
| `<VLESS_UUID>` | VLESS 用户 ID |
| `<REALITY_PRIVATE_KEY>` | 只保存在服务端的 X25519 私钥 |
| `<REALITY_PASSWORD>` | 与私钥对应、配置在客户端的公开连接参数 |
| `<REALITY_SHORT_ID>` | 最长 16 位、偶数长度的十六进制字符串 |
| `<ANYTLS_PASSWORD>` | AnyTLS 的独立随机密码 |
安全组和服务器防火墙需要放行 `443/TCP``8443/TCP`。不需要放行 UDP 端口。
## 3. 系统检查
```bash
uname -m
cat /etc/os-release
timedatectl status
sudo ss -lntp 'sport = :443 or sport = :8443'
```
要求:
- Linux 使用 systemd。
- CPU 架构为 `x86_64``aarch64``arm64`
- `443``8443` 未被其他进程监听。
- 系统时间同步正常。
安装依赖时按发行版选择一组命令:
```bash
# Debian / Ubuntu
sudo apt-get update
sudo apt-get install -y curl unzip openssl ca-certificates
```
```bash
# RHEL / Rocky Linux / AlmaLinux
sudo dnf install -y curl unzip openssl ca-certificates
```
## 4. 安装 Xray-core
以下命令固定安装 `v26.3.27`,并根据服务器架构选择 GitHub Release 文件与 SHA-256 摘要:
```bash
XRAY_VERSION=26.3.27
case "$(uname -m)" in
x86_64|amd64)
XRAY_ARCH=64
XRAY_SHA256=23cd9af937744d97776ee35ecad4972cf4b2109d1e0fe6be9930467608f7c8ae
;;
aarch64|arm64)
XRAY_ARCH=arm64-v8a
XRAY_SHA256=4d30283ae614e3057f730f67cd088a42be6fdf91f8639d82cb69e48cde80413c
;;
*)
echo "不支持的 CPU 架构: $(uname -m)" >&2
exit 1
;;
esac
XRAY_WORK_DIR="$(mktemp -d)"
XRAY_PACKAGE="Xray-linux-${XRAY_ARCH}.zip"
curl --fail --location \
--output "${XRAY_WORK_DIR}/${XRAY_PACKAGE}" \
"https://github.com/XTLS/Xray-core/releases/download/v${XRAY_VERSION}/${XRAY_PACKAGE}"
echo "${XRAY_SHA256} ${XRAY_WORK_DIR}/${XRAY_PACKAGE}" | sha256sum --check -
unzip "${XRAY_WORK_DIR}/${XRAY_PACKAGE}" -d "${XRAY_WORK_DIR}/xray"
sudo install -m 0755 "${XRAY_WORK_DIR}/xray/xray" /usr/local/bin/xray
/usr/local/bin/xray version
```
只有摘要检查显示 `OK` 后才继续。升级版本时必须同时更新版本号和相应架构的官方摘要。
创建专用账号和配置目录:
```bash
sudo groupadd --system xray
sudo useradd --system --gid xray --no-create-home --shell /usr/sbin/nologin xray
sudo install -d -m 0750 -o root -g xray /usr/local/etc/xray
```
## 5. 选择 REALITY 目标站点
REALITY 鉴权失败时,Xray 会将流量转发给 `target`。目标选择不当可能让服务器成为第三方站点的转发入口,因此不要直接照抄一个公共示例域名。
目标站点应满足:
- 从该服务器访问延迟低、连接稳定,优先选择与服务器相同 ASN 的站点。
- 支持 TLS 1.3,并能正常完成 TLS 握手。
- `serverNames` 使用目标证书 SAN 中存在的域名。
- 避免使用 Cloudflare 等公共 CDN 站点,减少被扫描后偷跑转发流量的风险。
- 不使用银行、支付、政府或其他敏感站点。
对候选站点执行:
```bash
/usr/local/bin/xray tls ping <REALITY_TARGET>:443
openssl s_client -connect <REALITY_TARGET>:443 -servername <REALITY_TARGET> </dev/null
```
确认握手、证书域名和延迟符合要求后,再固定 `<REALITY_TARGET>`。服务端 `target``serverNames`、客户端 `serverName` 必须使用同一目标域名。
## 6. 生成 VLESS 和 REALITY 参数
生成 VLESS UUID
```bash
/usr/local/bin/xray uuid
```
生成 REALITY X25519 密钥对:
```bash
/usr/local/bin/xray x25519
```
记录输出中的两项:
- `PrivateKey`:填入服务端 `<REALITY_PRIVATE_KEY>`,不得发送给客户端或他人。
- `Password`:填入客户端 `<REALITY_PASSWORD>`。这是当前 Xray 对原 `publicKey` 字段的新名称,不是登录密码。
生成 8 字节 short ID
```bash
openssl rand -hex 8
```
将 16 位十六进制输出记录为 `<REALITY_SHORT_ID>`。UUID、私钥和 short ID 不要使用本文中的占位符或公共示例值。
## 7. 配置 VLESS + REALITY 主入口
创建配置:
```bash
sudoedit /usr/local/etc/xray/config.json
```
写入以下 JSON 并替换全部占位符:
```json
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "vless-reality-in",
"listen": "0.0.0.0",
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "<VLESS_UUID>",
"flow": "xtls-rprx-vision",
"email": "primary-client"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"target": "<REALITY_TARGET>:443",
"xver": 0,
"serverNames": [
"<REALITY_TARGET>"
],
"privateKey": "<REALITY_PRIVATE_KEY>",
"shortIds": [
"<REALITY_SHORT_ID>"
]
}
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls",
"quic"
],
"routeOnly": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"0.0.0.0/8",
"10.0.0.0/8",
"100.64.0.0/10",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.0.0.0/24",
"192.168.0.0/16",
"198.18.0.0/15",
"224.0.0.0/4",
"::1/128",
"fc00::/7",
"fe80::/10"
],
"outboundTag": "block"
}
]
}
}
```
上述路由规则阻止代理客户端访问服务器所在的常见私网、链路本地地址和云元数据地址。若确实需要通过代理访问某个私网,应逐项评估后修改对应网段,不要直接删除整个限制。
设置权限并验证配置:
```bash
sudo chown root:xray /usr/local/etc/xray/config.json
sudo chmod 0640 /usr/local/etc/xray/config.json
sudo -u xray /usr/local/bin/xray run -test -config /usr/local/etc/xray/config.json
```
验证失败时不要启动服务,先根据输出修正占位符和 JSON 格式。
## 8. 创建 Xray systemd 服务
```bash
sudoedit /etc/systemd/system/xray.service
```
写入:
```ini
[Unit]
Description=Xray VLESS REALITY Server
Documentation=https://github.com/XTLS/Xray-core
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=xray
Group=xray
ExecStart=/usr/local/bin/xray run -config /usr/local/etc/xray/config.json
Restart=on-failure
RestartSec=5s
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_INET AF_INET6
LockPersonality=true
MemoryDenyWriteExecute=true
UMask=0077
[Install]
WantedBy=multi-user.target
```
`CAP_NET_BIND_SERVICE` 只用于让非 root 的 `xray` 用户监听 `443`,不要将服务改成 root 运行。
启动主入口:
```bash
sudo systemd-analyze verify /etc/systemd/system/xray.service
sudo systemctl daemon-reload
sudo systemctl enable --now xray
sudo systemctl status xray --no-pager
```
## 9. 部署 AnyTLS 备用入口
按照 [AnyTLS-go 服务器安装指南](AnyTLS-go服务器安装指南.md) 完成以下部分:
1. 安装 AnyTLS-go `v0.0.13`
2. 创建独立的 `anytls` 系统账号。
3. 生成与 VLESS UUID、REALITY 密钥完全无关的 AnyTLS 随机密码。
4. 保持监听地址为 `0.0.0.0:8443`
5. 启动 `anytls-go.service`
AnyTLS-go 是协议参考实现,会在启动时生成临时自签名证书,客户端必须使用与该实现相符的跳过证书校验设置。它不应占用 `443`,也不要与 Xray 共用账号、配置或密钥。
## 10. 防火墙和安全组
云平台安全组放行:
| 协议 | 端口 | 来源 |
| --- | --- | --- |
| TCP | `443` | 实际客户端来源;无法固定时为公网 |
| TCP | `8443` | 实际客户端来源;无法固定时为公网 |
主机使用 UFW 时:
```bash
sudo ufw allow 443/tcp
sudo ufw allow 8443/tcp
sudo ufw status
```
主机使用 firewalld 时:
```bash
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --permanent --add-port=8443/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports
```
UFW 与 firewalld 只选择服务器实际使用的一种,不要重复配置。
## 11. 客户端参数
### 11.1 VLESS + REALITY 主节点
| 客户端字段 | 值 |
| --- | --- |
| 地址 | `<SERVER_IP>` |
| 端口 | `443` |
| 协议 | VLESS |
| UUID | `<VLESS_UUID>` |
| Flow | `xtls-rprx-vision` |
| 传输 | TCP/RAW |
| 传输安全 | REALITY |
| SNI/Server Name | `<REALITY_TARGET>` |
| Fingerprint | `chrome` |
| Public Key/Password | `<REALITY_PASSWORD>` |
| Short ID | `<REALITY_SHORT_ID>` |
| Spider X | `/` 或留空 |
常见客户端仍可能把当前 Xray 文档中的 `password` 显示为 `Public Key``pbk`,填入的都是 `xray x25519` 输出的 `Password` 值。
通用分享 URI 结构:
```text
vless://<VLESS_UUID>@<SERVER_IP>:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=<REALITY_TARGET>&fp=chrome&pbk=<REALITY_PASSWORD>&sid=<REALITY_SHORT_ID>&type=tcp#VLESS-REALITY
```
### 11.2 AnyTLS 备用节点
| 客户端字段 | 值 |
| --- | --- |
| 地址 | `<SERVER_IP>` |
| 端口 | `8443` |
| 协议 | AnyTLS |
| 密码 | `<ANYTLS_PASSWORD>` |
| 跳过证书验证 | 仅对 AnyTLS-go 参考服务端启用 |
参考 URI
```text
anytls://<ANYTLS_PASSWORD>@<SERVER_IP>:8443
```
### 11.3 主备策略
客户端中创建两个独立节点,顺序保持 VLESS + REALITY 在前、AnyTLS 在后。需要自动切换时,使用客户端自身的 `fallback` 或健康检查组;需要稳定可控时,使用手动选择组。
不要把两个协议配置成同时向同一连接转发。切换策略只发生在客户端节点层。
## 12. 联合验收
服务端检查:
```bash
sudo systemctl is-active xray
sudo systemctl is-active anytls-go
sudo ss -lntp 'sport = :443 or sport = :8443'
sudo journalctl -u xray -n 50 --no-pager
sudo journalctl -u anytls-go -n 50 --no-pager
```
预期结果:
- `xray``anytls-go` 均返回 `active`
- Xray 监听 `0.0.0.0:443`AnyTLS-go 监听 `0.0.0.0:8443`
- 日志中没有配置解析、权限或端口占用错误。
客户端按以下顺序验收:
1. 只选择 VLESS + REALITY 节点,访问出口 IP 检测网站并完成实际网页、下载测试。
2. 只选择 AnyTLS 节点,重复相同测试。
3. 在客户端关闭或临时禁用主节点,确认主备组能切换到 AnyTLS。
4. 恢复主节点,确认客户端策略按预期回到 VLESS + REALITY。
端口连通性可从外部设备辅助检查:
```bash
nc -vz <SERVER_IP> 443
nc -vz <SERVER_IP> 8443
```
TCP 端口可连接不代表协议配置正确,最终以代理请求成功为准。
## 13. 日常运维
```bash
# 查看状态
sudo systemctl status xray anytls-go --no-pager
# 查看实时日志
sudo journalctl -u xray -f
sudo journalctl -u anytls-go -f
# 重启单个入口
sudo systemctl restart xray
sudo systemctl restart anytls-go
```
修改 Xray 配置前先备份私钥和客户端参数;修改后先执行配置测试,再重启:
```bash
sudo -u xray /usr/local/bin/xray run -test -config /usr/local/etc/xray/config.json
sudo systemctl restart xray
sudo systemctl status xray --no-pager
```
升级任一服务时,只替换对应二进制并单独验收,不要同时升级两个入口。这样其中一个入口出现兼容问题时,另一个仍可用于连接。
## 14. 故障定位
| 现象 | 优先检查 |
| --- | --- |
| Xray 无法启动 | JSON 校验、配置权限、`443` 占用、systemd capability |
| REALITY 握手失败 | UUID、`flow``serverName``password/pbk`、short ID 是否完全一致 |
| REALITY 偶发超时 | 目标站点连通性、服务器时间、线路丢包、目标是否变更 TLS 配置 |
| AnyTLS 无法启动 | 环境文件权限、密码是否填写、`8443` 占用 |
| 端口都通但无法代理 | 客户端协议字段、服务日志、安全软件或上游网络限制 |
| 主节点故障后未切换 | 客户端是否使用 fallback/健康检查组及其探测 URL、间隔设置 |
| 服务器出现异常转发流量 | REALITY 目标是否为公共 CDN;重新选择同 ASN 的非 CDN 目标 |
## 15. 参考资料
- [Xray-core 官方仓库](https://github.com/XTLS/Xray-core)
- [Xray 官方 REALITY 配置文档](https://xtls.github.io/config/transports/reality.html)
- [Xray 官方 VLESS + TCP + XTLS Vision + REALITY 示例](https://github.com/XTLS/Xray-examples/tree/main/VLESS-TCP-XTLS-Vision-REALITY)
- [Xray-core Releases](https://github.com/XTLS/Xray-core/releases)
- [AnyTLS-go 官方仓库](https://github.com/anytls/anytls-go)
- [AnyTLS-go 服务器安装指南](AnyTLS-go服务器安装指南.md)