节点 Agent¶
节点 Agent 是一个 Go 程序,同时管理 Hysteria 2 与 Xray 节点,负责:
- 使用节点 Token 建立到面板的 WebSocket 长连接;
- 接收并落盘 Hysteria 2 YAML 或 Xray JSON;
- 生成/复用自签名证书;managed 模式向面板提交 CSR 并安装面板签发的证书;
- 启动、停止、重启 Hysteria;
- 维护端口跳跃 iptables 规则;
- 采集 Hysteria 日志并批量上报;
- 轮询 Hysteria
trafficStats或 XrayStatsService,上报每用户流量; - 每 10 秒上报 CPU / 内存 / 磁盘 / load / uptime。
部署方式¶
方式 A:单容器(推荐)¶
面板内 Nodes → Install 会生成带 Token 的完整命令。镜像内已经包含 Hysteria:
docker run -d --name mikvace-node --restart unless-stopped \
--network host --cap-add NET_ADMIN \
-e PANEL_URL="https://panel.example.com" \
-e NODE_TOKEN="mtn_xxx" \
-e HY2_RUNTIME=process \
-v /var/lib/mikvace:/data \
ghcr.io/axmishell/mikvacepanel-node:main
或使用 docker-compose.node.yml:
PANEL_URL=https://panel.example.com NODE_TOKEN=mtn_xxx \
docker compose -f docker-compose.node.yml up -d
方式 B:Agent 管理 Hysteria 容器¶
Agent 自己也在容器里,但通过挂载 Docker socket 启动同机的 Hysteria 容器:
docker run -d --name mikvace-node --restart unless-stopped \
--network host --cap-add NET_ADMIN \
-e PANEL_URL="https://panel.example.com" \
-e NODE_TOKEN="mtn_xxx" \
-e HY2_RUNTIME=docker \
-e HOST_DATA_DIR=/var/lib/mikvace \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/mikvace:/data \
ghcr.io/axmishell/mikvacepanel-node:main
此时 Hysteria 容器使用 tobyxdd/hysteria:latest,挂载宿主机 /var/lib/mikvace 到 /data。Agent 在容器内看到的 /data 并不是宿主机路径,因此必须用 HOST_DATA_DIR 告诉它宿主机实际路径。
方式 C:二进制 + systemd¶
/etc/systemd/system/mikvace-node.service:
[Unit]
Description=MikvAce Node Agent
After=network-online.target
[Service]
Type=simple
Environment=PANEL_URL=https://panel.example.com
Environment=NODE_TOKEN=mtn_xxx
Environment=DATA_DIR=/var/lib/mikvace
Environment=HY2_RUNTIME=process
Environment=HYSTERIA_BIN=/usr/local/bin/hysteria
ExecStart=/usr/local/bin/mikvace-node
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
需要以 root 运行(绑定 443、写 iptables、读 /proc)。
环境变量¶
| 变量 | 默认 | 说明 |
|---|---|---|
PANEL_URL |
— | 面板地址,http(s)://;Agent 自动转换成 ws(s)://.../api/node/ws |
NODE_TOKEN |
— | 节点 Token |
DATA_DIR |
/data |
配置、证书、状态目录 |
HOST_DATA_DIR |
/var/lib/mikvace |
Docker 模式下的宿主机数据路径 |
HY2_RUNTIME |
process |
process 或 docker |
HYSTERIA_BIN |
hysteria |
进程模式 Hysteria 路径 |
XRAY_BIN |
xray |
进程模式 Xray 路径 |
HY2_IMAGE |
tobyxdd/hysteria:latest |
Hysteria Docker 模式镜像 |
XRAY_IMAGE |
ghcr.io/xtls/xray-core:latest |
Xray Docker 模式镜像 |
HY2_CONTAINER |
mikvace-hysteria |
Docker 模式容器名 |
PANEL_INSECURE |
false |
跳过面板 TLS 校验(仅自签名面板) |
LOG_LEVEL |
info |
debug/info/warn/error |
对应命令行参数:--panel、--token、--data-dir、--host-data-dir、--runtime、--hysteria-bin、--hysteria-image、--container、--insecure、--log-level。
数据目录¶
/data/
├── config/config.yaml # 面板下发的 Hysteria 配置
├── config/config.json # 面板下发的 Xray 配置
├── log/access.log # Xray access log(Agent 自动 tail)
├── certs/cert.pem # 自签名证书(selfsigned 模式)
├── certs/key.pem
└── state/meta.json # revision / protocol / port hopping 元信息
进程模式下,Agent 会把配置中的 /data/ 前缀改写为实际 DATA_DIR;Docker 模式下保持不变,因为 Hysteria 容器也把数据目录挂载到 /data。
Xray / VLESS / REALITY¶
节点设置中的 xray 对象:
| 字段 | 说明 |
|---|---|
transport |
tcp / ws / grpc |
security |
reality / tls / none |
flow |
TCP + REALITY/TLS 使用 xtls-rprx-vision |
fingerprint |
uTLS 指纹,默认 chrome |
alpn |
TLS ALPN,默认 h2,http/1.1 |
realityDest |
REALITY 伪装目标,默认 www.cloudflare.com:443 |
realitySni |
REALITY serverNames 数组 |
realityPrivateKey / realityPublicKey |
面板生成/保存的 x25519 密钥 |
realityShortIds |
REALITY short id 数组 |
wsPath / wsHost |
WebSocket 传输参数 |
grpcServiceName |
gRPC 服务名 |
apiPort |
Xray StatsService 本地端口,默认 61000 |
inboundTag |
VLESS 入站标签,默认 vless-in |
节点类型选择 Xray 后,面板生成包含全部授权用户的 config.json,Agent 运行:
- 支持 TCP、WebSocket、gRPC;
- 支持 REALITY、TLS(使用 Agent 生成的自签名证书)和无加密;
- REALITY 的 x25519 密钥与 short id 由面板生成;
- Xray access log 写入
/data/log/access.log,Agent 自动 tail 并上报; - 用户流量通过
xray api statsquery获取,按 email(userId)聚合; - 新增/修改/禁用用户后,面板会重新渲染并下发所有 Xray 节点配置。
SSH 自动安装¶
节点编辑页可保存 SSH 端口、用户、密码或私钥。点击 Auto setup 后,面板通过 SSH 执行安装脚本,创建/重建 mikvace-node 容器。要求:
- 面板服务器能访问节点 SSH;
- 使用 root 或具备 Docker 权限的用户;
- 默认不验证 SSH host key(使用
InsecureIgnoreHostKey),请限制面板出口 IP 并使用专用凭据; - 可选自动执行
get.docker.com安装 Docker; - 私钥暂不支持 passphrase。
证书¶
tlsMode=selfsigned:Agent 生成 ECDSA P-256 证书,10 年有效,包含节点domain或ip的 SAN;如果现有证书不含当前主机名或即将过期(7 天内)会重新生成。tlsMode=managed:Agent 生成私钥与 CSR,面板通过 ACME DNS-01 签发后通过 WebSocket 下发证书链;私钥不出节点。详见 certificates.md。tlsMode=acme(旧模式):面板生成acme.domains配置,由 Hysteria 内置 ACME 处理。已强制使用 TLS-ALPN(disableHTTP: true),不占用 80 端口;需要 443/TCP 与 443/UDP 可用,且 ACME 缓存写入/data/acme。
自签名模式下,订阅中会带 insecure=1,客户端跳过证书校验。
端口跳跃¶
节点设置 portRange 后:
- 订阅生成
mport与mportHopInt; - Agent 在节点上执行等价规则:
- 配置变化时会删除旧 range 规则并安装新规则;
- 需要
--cap-add NET_ADMIN与--network host; - IPv6 端口跳跃暂未实现。
日志上报细节¶
- 进程模式:读取子进程 stdout/stderr;
- Docker 模式:
docker logs -f --tail 0; - 每 2 秒或累计 100 行发送一个批次;
- 每批带随机 batch id,未收到
log.ack时每 10 秒重发; - 内存中最多保留 200 个未确认批次,超出后丢弃最旧的批次;
- 面板关闭日志采集时仍会 ack,Agent 不会无限重试。
流量统计¶
Agent 每 15 秒请求:
GET http://127.0.0.1:<statsPort>/traffic?clear=1
GET http://127.0.0.1:<statsPort>/online
Authorization: <statsSecret>
把用户维度增量发给面板;面板用 (node_id, batch_id) 唯一索引保证只应用一次。在线用户列表为空时也会发送,以便面板清除过期的在线状态。
故障排查¶
invalid node token:在面板重置 Token 并更新启动命令。port hopping rules: ...:容器缺少 NET_ADMIN、iptables 或使用了非 host 网络。hysteria exited after applying the configuration:查看同批次 Hysteria 日志(面板 Logs 页面或容器日志),常见原因是端口被占用、证书路径错误、ACME 域名不可达。- 面板显示节点离线:检查面板 URL 是否可从节点访问、反代是否支持 WebSocket Upgrade、
PANEL_INSECURE是否正确。