ProxyNode Xray Caddy Integration

完成 ProxyNode 场景下的 Xray、Caddy 与 Mihomo(Clash Meta) 联动配置,并整理为可复用归档。

背景 / 目标

目标是基于 reality.example.comcdn.example.com 搭建一套可同时支持 XTLS+RealityXHTTP 的服务端。

服务端由 Xray + Caddy 组成,客户端使用 mihomo / Clash Meta。成功标准是服务端配置能够对齐,客户端配置中的 ProxyNode 节点可被正式纳入分组引用,并形成一套可复看的配置记录。

初始问题现象

  • 在执行 sudo systemctl edit xray 时出现 temporary file is empty,导致 override 未生效。
  • 按笔记将 User=caddy 写入 override 后,xray 启动失败。
  • clash.yaml 中虽然已有 ProxyNode 相关节点定义,但并未完整纳入常用分组。

关键报错与观察

systemctl edit 报错:

Editing "/etc/systemd/system/xray.service.d/override.conf" canceled: temporary file is empty.

说明 systemctl edit 最终没有保存出有效内容。

xray 启动报错:

status=217/USER

这是典型的 systemd 用户切换失败,说明当时指定的运行用户存在问题,或用户尚未准备好。

后续在安装 Caddy 后确认:

  • id caddy 可查询到 uid=998(caddy) gid=999(caddy)
  • systemctl show xray --property=User,Group 显示 User=caddy

排查过程

  1. 确认原始安装笔记和目标是参考 Mihomo 讨论中的 Xray + Caddy + XHTTP 方案。
  2. 针对 systemctl edit xray 的异常,没有继续卡在编辑器层面,而是改用直接创建 /etc/systemd/system/xray.service.d/override.conf 的方式规避问题。
  3. 从新的报错 status=217/USER 反推,确认问题不是 Xray 配置语法,而是 systemd 切换运行用户失败。
  4. 结合后续安装 Caddy 的记录,确认系统中 caddy 用户已经存在,且 xray 已能切换为 User=caddy
  5. 读取并对齐 Caddyfile 与 Xray 配置:统一两个域名、统一 XHTTP path、统一 UUID / publicKey / shortId
  6. 直接生成一套新的客户端与 Reality 参数进行脱敏配置。
  7. 检查 clash.yaml 后发现 4 条 ProxyNode 节点定义已经存在,只差正式进入分组。
  8. 按最终需求,将 4 条 ProxyNode 节点加入常用分组,完成客户端引用补齐。

正确操作步骤

1. 安装或升级 Xray,并保留服务文件默认逻辑。
2. 安装 Caddy,确保系统内存在 caddy 用户。
3. 如需统一 socket 访问权限,不依赖 systemctl edit,直接写入:

[Service]
User=caddy

4. 创建证书目录与文件:

sudo mkdir -p /etc/caddy/certs
sudo nano /etc/caddy/certs/cf.crt
sudo nano /etc/caddy/certs/cf.key
sudo chmod 644 /etc/caddy/certs/cf.crt
sudo chmod 600 /etc/caddy/certs/cf.key

5. 统一服务端配置中的关键值:

  • 域名:reality.example.comcdn.example.com
  • XHTTP path/xhttp-secret-gate
  • UUID_01[REDACTED-UUID-1]
  • UUID_02[REDACTED-UUID-2]
  • REALITY_PRIVATE_KEY[PRIVATE_KEY_REDACTED]
  • REALITY_PUBLIC_KEY[PUBLIC_KEY_REDACTED]
  • SHORT_ID[SHORT_ID_REDACTED]

6. 重载并重启服务:

sudo systemctl daemon-reload
sudo systemctl restart xray
sudo systemctl restart caddy
sudo systemctl status xray
sudo systemctl status caddy

最终结果 & 易错点教训

  • 结果:各端配置已完成同一套参数收口,节点被正式加入分组便于切换。
  • systemctl edittemporary file is empty 时,不一定是操作手法错,也可能是 systemd 最终没有识别到有效内容。
  • status=217/USER 优先看运行用户是否真实存在,而不是先怀疑 Xray 配置本身。
  • XrayCaddyClash 三端里,域名、pathUUIDReality key 必须严格对齐。

可复用命令 (Cheat Sheet)

id caddy
systemctl show xray --property=User,Group
sudo systemctl cat xray
sudo systemctl daemon-reload
sudo systemctl restart xray
sudo systemctl restart caddy
sudo journalctl -u xray -n 50 --no-pager
sudo journalctl -u caddy -n 50 --no-pager