本文记录如何在 Ubuntu 24.04 上部署一套 VLESS + REALITY + Vision 服务,并使用 Mihomo 作为客户端。重点不是“一键安装”,而是建立一套可以检查、升级和排错的配置流程。
开始前请确认当地法律、服务器提供商条款和网络使用政策。本文仅讨论个人服务器的网络服务部署与运维。
Xray 和 Mihomo 的配置字段仍在演进。本文采用写作时的当前字段,实际部署前应同时查看 Xray REALITY 文档 ↗和 Mihomo VLESS 文档 ↗。
部署结构#
本文使用以下结构:
Mihomo 客户端
↓ VLESS + REALITY + Vision
Ubuntu 24.04 / Xray :443
↓
目标 TLS 站点 :443text示例统一使用 TCP 端口 443。如果它已经被 Nginx、Caddy 或其他服务占用,可以改用其他空闲 TCP 端口,但服务端、客户端和防火墙必须保持一致。生产环境还应先规划好现有 Web 服务与 Xray 的共存方式,不要直接覆盖正在监听的端口。
安装前检查#
更新软件包索引并安装本文需要的工具:
sudo apt update
sudo apt upgrade
sudo apt install curl openssl jq ufwbash检查端口占用:
sudo ss -lntpbash确认系统时间和时区正常:
timedatectl statusbashREALITY 握手依赖客户端和服务端时间。时间偏差较大时,应先检查 systemd-timesyncd、chrony 或云服务商提供的时间同步能力。
安装 Xray#
Xray 官方维护了安装脚本。先下载到本地并检查内容,再以 root 权限执行:
curl -LO https://github.com/XTLS/Xray-install/raw/main/install-release.sh
less install-release.sh
sudo bash install-release.shbash验证安装结果:
xray version
systemctl cat xraybash默认配置文件通常位于:
/usr/local/etc/xray/config.jsontext服务由 systemd 管理:
sudo systemctl status xray
sudo journalctl -u xray -n 50 --no-pagerbash安装脚本和版本发布信息可以在 XTLS/Xray-install ↗ 与 XTLS/Xray-core ↗ 仓库中核对。
生成服务凭据#
部署需要三组值:
- VLESS 用户 UUID;
- REALITY X25519 密钥对;
- REALITY Short ID。
UUID#
生成 UUID:
xray uuidbashUUID 要同时写入服务端的 clients[].id 和客户端的 uuid。
X25519 密钥对#
生成 REALITY 使用的 X25519 密钥对:
xray x25519bash输出名称会随 Xray 版本变化,通常包括:
PrivateKey: ...
Password: ...textPrivateKey 只写入服务端。与它对应的客户端值在当前 Xray 文档中称为 password,旧版本称为 publicKey;Mihomo 仍将这个字段命名为 reality-opts.public-key。
如果已有服务端私钥,可以重新计算客户端值:
xray x25519 -i 'YOUR_PRIVATE_KEY'bash不要把私钥或客户端凭据提交到 Git 仓库、粘贴到公开日志或写进博客示例。
Short ID#
生成 8 字节、16 个十六进制字符的 Short ID:
openssl rand -hex 8bash服务端使用 shortIds 数组,Mihomo 客户端使用其中一个值。Short ID 最长为 16 个十六进制字符,字符数量必须是偶数。
选择 REALITY target#
REALITY 会把未通过认证的连接转发到 target,所以目标选择会直接影响服务行为。部署前至少检查以下事项:
- 服务器能够直接访问该目标的
443端口; - 目标支持合适的 TLS 协议;
serverNames是目标证书接受的 SNI 名称;- 不要随意使用可能让服务器成为公共转发入口的 CDN 目标。
可以使用 Xray 自带命令观察目标 TLS 行为:
xray tls ping TARGET_DOMAINbash通常应让 serverNames 与 target 保持一致。不要像下面这样把彼此无关的域名放进同一个列表:
target: www.example-a.com:443
serverNames: www.example-a.com, www.example-b.comtext除非已经验证它们确实由同一个目标接受,否则这种配置容易导致握手失败或产生异常特征。
服务端配置#
先备份现有配置:
sudo cp -p /usr/local/etc/xray/config.json /usr/local/etc/xray/config.json.backupbash编辑配置:
sudo vim /usr/local/etc/xray/config.jsonbash下面是一份最小化模板。部署前必须替换所有 YOUR_... 占位符:
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "vless-reality",
"listen": "0.0.0.0",
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "YOUR_UUID",
"flow": "xtls-rprx-vision"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "raw",
"security": "reality",
"realitySettings": {
"show": false,
"target": "YOUR_TARGET_DOMAIN:443",
"serverNames": ["YOUR_TARGET_DOMAIN"],
"privateKey": "YOUR_PRIVATE_KEY",
"shortIds": ["YOUR_SHORT_ID"]
}
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"],
"routeOnly": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom"
}
]
}json先格式化并查看 JSON,再让 Xray 验证语义:
jq . /usr/local/etc/xray/config.json
sudo xray run -test -config /usr/local/etc/xray/config.jsonbash只有看到配置验证成功后,才重启服务:
sudo systemctl restart xray
sudo systemctl enable xray
sudo systemctl status xray --no-pagerbash如果重启失败,不要连续反复修改。先查看完整日志:
sudo journalctl -u xray -n 100 --no-pagerbash配置 UFW#
远程服务器启用防火墙前,必须先确认当前 SSH 端口已经放行,否则可能把自己锁在服务器之外。以下示例假设 SSH 使用端口 22,Xray 使用端口 443:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit 22/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbosebash如果 SSH 使用其他端口,应先替换 22。云服务器还可能有独立的安全组或提供商防火墙,UFW 放行并不代表外层防火墙也已经放行。
检查 Xray 是否监听预期端口:
sudo ss -lntp | grep ':443'bash从另一台机器测试 TCP 连通性:
nc -vz SERVER_ADDRESS 443bashTCP 可连接只代表网络路径畅通,并不代表 REALITY 参数正确。
Mihomo 客户端配置#
在 Mihomo 配置的 proxies 中加入以下节点,并替换全部占位符:
proxies:
- name: VLESS-REALITY
type: vless
server: YOUR_SERVER_ADDRESS
port: 443
uuid: YOUR_UUID
network: tcp
tls: true
udp: true
flow: xtls-rprx-vision
servername: YOUR_TARGET_DOMAIN
client-fingerprint: chrome
reality-opts:
public-key: YOUR_CLIENT_PASSWORD
short-id: YOUR_SHORT_IDyaml客户端字段必须与服务端一一对应:
| Mihomo 字段 | 服务端来源 |
|---|---|
server、port | 服务器地址与 Xray 监听端口 |
uuid | clients[].id |
servername | realitySettings.serverNames 中的一项 |
public-key | xray x25519 生成的客户端 Password |
short-id | realitySettings.shortIds 中的一项 |
不要因为字段名是 public-key 就把它当作可公开信息。当前 Xray 文档将其视为客户端 password,分享配置或日志时应一并遮盖。
安全地修改配置#
日常修改建议采用固定流程:
sudo cp -p /usr/local/etc/xray/config.json /usr/local/etc/xray/config.json.backup
sudo vim /usr/local/etc/xray/config.json
jq . /usr/local/etc/xray/config.json
sudo xray run -test -config /usr/local/etc/xray/config.json
sudo systemctl restart xray
sudo systemctl status xray --no-pagerbash如果配置验证或服务启动失败,可以恢复上一个版本:
sudo cp -p /usr/local/etc/xray/config.json.backup /usr/local/etc/xray/config.json
sudo xray run -test -config /usr/local/etc/xray/config.json
sudo systemctl restart xraybash备份文件中包含完整凭据,应限制读取权限,并避免无限累积:
sudo chmod 600 /usr/local/etc/xray/config.json.backupbash升级 Xray#
升级前记录当前版本并备份配置:
xray version
sudo cp -p /usr/local/etc/xray/config.json /usr/local/etc/xray/config.json.before-upgradebash重新下载并检查官方安装脚本:
curl -LO https://github.com/XTLS/Xray-install/raw/main/install-release.sh
less install-release.sh
sudo bash install-release.shbash升级后再次检查配置和服务:
xray version
sudo xray run -test -config /usr/local/etc/xray/config.json
sudo systemctl restart xray
sudo systemctl status xray --no-pagerbash不要只确认进程处于 active (running);还应使用客户端完成一次实际连接测试。如果升级涉及 REALITY 字段变化,应优先对照当前官方文档,而不是直接复用旧教程中的配置。
故障排查#
服务无法启动#
依次执行:
jq . /usr/local/etc/xray/config.json
sudo xray run -test -config /usr/local/etc/xray/config.json
sudo journalctl -u xray -n 100 --no-pagerbash常见原因包括 JSON 语法错误、字段拼写错误、端口已被占用,以及复制凭据时包含了多余空格。
端口无法连接#
分别检查监听、本机防火墙和云平台安全组:
sudo ss -lntp | grep ':443'
sudo ufw status numbered
sudo journalctl -u xray -n 50 --no-pagerbash然后从外部机器运行:
nc -vz SERVER_ADDRESS 443bashinvalid request user id#
这通常表示客户端 uuid 与服务端 clients[].id 不一致。重新复制 UUID,并检查是否连接到了错误的服务器或端口。
REALITY 握手失败#
逐项核对:
- Mihomo
public-key是否来自当前服务端privateKey; - 客户端
short-id是否存在于服务端shortIds; - 客户端
servername是否存在于服务端serverNames; target是否可从服务器访问;- 服务器和客户端时间是否准确;
- Mihomo 是否使用支持 REALITY 的当前版本。
修改多个参数后仍无法定位问题时,应先恢复一份最小配置,再逐项加入路由、DNS 和其他高级选项。
发布日志前的脱敏清单#
排错时经常需要分享配置和日志。至少应该遮盖:
- REALITY
privateKey; - Mihomo
reality-opts.public-key; - VLESS UUID;
- Short ID;
- 服务器地址以及不希望公开的域名;
- SSH 私钥、令牌和其他无关凭据。
脱敏后仍要保留字段名、错误消息和配置结构,否则他人很难判断参数之间是否对应。
总结#
一套可维护的 Xray REALITY 部署,应至少做到:
- 服务端与客户端使用完全对应的 UUID、密钥、Short ID 和 Server Name;
target与serverNames经过验证,而不是随意拼接域名;- 每次重启前先执行 JSON 和 Xray 配置检查;
- 同时检查 UFW、云安全组和实际端口监听;
- 升级前备份,升级后完成真实连接测试;
- 分享配置和日志前清除所有服务端及客户端凭据。
这样即使版本升级或网络环境发生变化,也能把问题缩小到配置、服务、网络或客户端中的具体一层,而不是依赖反复尝试。