|
# StarAgent Native (Go)
StarAgent 原生 Go 实现,遵循 [`../spec/protocol.md`](/NewLife/Stardust/Blob/master/StarAgent.Native/go/../spec/protocol.md) 与
[`../spec/schemas/node-agent.schema.json`](/NewLife/Stardust/Blob/master/StarAgent.Native/go/../spec/schemas/node-agent.schema.json)。
## 已实现能力
- 登录 / 注销 / 心跳 / 令牌续期 / `NewServer` 迁移 / 指数退避重连(1s→30s,带抖动)
- HTTP:`/node/login`、`/node/logout`、`/node/ping`、`/node/postevents`、
`/node/commandreply`、`/node/upgrade`
- WebSocket:`/node/notify`(`Authorization: Bearer`),文本 `Ping`/`Pong` 保活,
JSON `CommandModel` 执行后走 HTTP 回复
- 心跳响应中的 `Commands`(HTTP 降级)执行
- 指标:CPU、内存、磁盘容量/挂载点、网络速率、进程数/进程名、运行时长、系统负载;
单项采集失败填 0,不影响心跳
- 命令:按 `Id` 去重 1 小时、过期取消、`StartTime` 延迟执行、默认 30s 超时(最大 300s)、
输出 64KB 头尾截断、进程树终止、最多 4 个并发(shell 串行)
- 内置命令:`bash`(Linux/macOS)、`cmd`(Windows)、`node/synctime`、
`node/setchannel`、`node/restart`;`node/reboot`、`deploy/*`、`framework/install`
返回“不支持命令”
- 安全默认 `AllowExec=false`;开启后仍受 `AllowedCommands` 白名单约束
- 配置文件 `staragent.json` + `STARAGENT_` 环境变量覆盖;`Code`/`Secret` 原子持久化,
权限 `0600`;日志按天滚动并保留 7 天
- CLI:`run`、`once`、`version`、`install`、`uninstall`、`start`、`stop`、`status`
- 服务形态:Linux systemd、OpenWrt procd、Windows 服务(`golang.org/x/sys/windows/svc`)、
macOS launchd
## 目录
```
cmd/staragent CLI 入口与服务检测
internal/config 配置、环境变量覆盖、原子持久化
internal/identity 稳定硬件标识、网络与系统信息
internal/protocol JSON 模型、时间格式、响应包装解析
internal/client HTTP 客户端、401 重登、退避、WebSocket 通知
internal/metrics gopsutil 指标采集与失败降级
internal/command 命令模型执行、去重、白名单、超时与截断
internal/agent 登录/心跳/迁移/事件/命令主循环
internal/service systemd / OpenWrt / launchd / Windows 服务
internal/logging 按天轮转日志
```
## 构建
需要 Go 1.24+(`gopsutil/v4` 要求)。
```bash
cd StarAgent.Native/go
go build ./cmd/staragent
go test ./...
```
可选构建信息:
```bash
go build -ldflags "-X main.Version=1.0.2026.1017 -X 'main.BuildTime=2026-10-17 08:00:00'" ./cmd/staragent
```
## 配置
默认读取当前目录 `staragent.json`(可用 `-config` 或 `STARAGENT_CONFIG` 覆盖):
```json
{
"Server": "https://star.example.com:6600",
"ProductCode": "StarAgent-Go",
"Code": "",
"Secret": "",
"Project": "",
"Channel": "Release",
"DataDir": "/var/lib/staragent",
"LogLevel": "info",
"MetricsInterval": 60,
"AllowExec": false,
"AllowedCommands": [],
"CommandTimeout": 30,
"TlsVerify": true
}
```
环境变量(前缀 `STARAGENT_`,字段名转大写):
| 变量 | 示例 |
|------|------|
| `STARAGENT_SERVER` | `https://star.example.com:6600` |
| `STARAGENT_PRODUCTCODE` | `StarAgent-Go` |
| `STARAGENT_CODE` / `STARAGENT_SECRET` | 已注册节点身份 |
| `STARAGENT_PROJECT` | `demo` |
| `STARAGENT_CHANNEL` | `Release` |
| `STARAGENT_DATADIR` | `/var/lib/staragent` |
| `STARAGENT_LOGLEVEL` | `debug` |
| `STARAGENT_METRICSINTERVAL` | `60` |
| `STARAGENT_ALLOWEXEC` | `false` |
| `STARAGENT_ALLOWEDCOMMANDS` | `node/synctime,bash`(逗号或分号分隔) |
| `STARAGENT_COMMANDTIMEOUT` | `30` |
| `STARAGENT_TLSVERIFY` | `true` |
`Code`/`Secret` 只由登录响应写入文件;`Token` 仅保存在内存,不落盘。
`AllowedCommands` 支持精确名称与后缀 `*`(例如 `node/*`)。
## 运行
```bash
./staragent run -config /opt/staragent/staragent.json
./staragent once -config ./staragent.json # 单次登录、心跳、处理命令后退出
./staragent version
```
命令执行默认关闭。需要时显式开启,并建议同时配置白名单:
```bash
./staragent run -allow-exec
```
## 安装为服务
### Linux(systemd)
```bash
sudo ./staragent install -server https://star.example.com:6600 \
-config /opt/staragent/staragent.json -dir /opt/staragent -user staragent
sudo ./staragent status
```
生成 `/etc/systemd/system/staragent.service`,包含 `Restart=always`、
`KillSignal=SIGTERM`。需要 root。
### OpenWrt(procd)
同一 `install` 命令在检测到 `/etc/openwrt_release` 时改为生成
`/etc/init.d/staragent`(`start_service` / `stop_service` / `respawn`)。
建议使用 `CGO_ENABLED=0` 构建:
```bash
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build -trimpath -o staragent-arm ./cmd/staragent
```
### macOS(launchd)
`sudo ./staragent install -server ...` 写入 `/Library/LaunchDaemons/com.newlifex.staragent.plist`;
非 root 安装写入 `~/Library/LaunchAgents/com.newlifex.staragent.plist`。
### Windows
以管理员身份执行:
```powershell
.\staragent.exe install -server https://star.example.com:6600 `
-config C:\ProgramData\StarAgent\bin\staragent.json
.\staragent.exe start
.\staragent.exe status
.\staragent.exe uninstall
```
服务名 `StarAgentNative`。`run` 由 SCM 启动时会自动进入服务模式。
## 交叉编译
```bash
export CGO_ENABLED=0
GOOS=linux GOARCH=amd64 go build -trimpath -o staragent-linux-amd64 ./cmd/staragent
GOOS=linux GOARCH=arm64 go build -trimpath -o staragent-linux-arm64 ./cmd/staragent
GOOS=linux GOARCH=arm GOARM=7 go build -trimpath -o staragent-linux-arm ./cmd/staragent
GOOS=windows GOARCH=amd64 go build -trimpath -o staragent-windows-amd64.exe ./cmd/staragent
GOOS=windows GOARCH=arm64 go build -trimpath -o staragent-windows-arm64.exe ./cmd/staragent
GOOS=darwin GOARCH=amd64 go build -trimpath -o staragent-darwin-amd64 ./cmd/staragent
GOOS=darwin GOARCH=arm64 go build -trimpath -o staragent-darwin-arm64 ./cmd/staragent
```
本项目不依赖 CGO,OpenWrt 直接使用 `CGO_ENABLED=0` 构建即可。
## 安全说明
- 生产环境保持 `TlsVerify=true`;`false` 仅用于测试。
- 日志不输出 `Secret`、`Token` 与命令完整参数;命令审计只记录名称、Id、状态、耗时与参数字节数。
- shell 命令默认关闭;开启后仍受白名单、8KB 参数上限、超时与 64KB 输出上限约束。
- `node/restart` 使用当前可执行文件与原始参数重新拉起进程后退出,不硬编码进程名。
- 配置与事件队列使用临时文件 + rename 原子写入;配置文件权限 `0600`(Windows 依赖 ACL)。
## 已知限制
- 首版不自动升级:`/node/upgrade` 有可用版本时仅记录日志并上报 `Upgrade` 事件。
- `node/reboot`、`deploy/*`、`framework/install` 明确返回不支持。
- `node/synctime` 需要 root/管理员权限,失败会返回错误与 stderr 摘要。
- 在 systemd/launchd 下使用 `node/restart` 时,监督进程可能同时拉起实例;
生产环境建议改用 `systemctl restart staragent` 等外部编排。
- Windows 服务模式下 `node/restart` 拉起的是普通进程而非 SCM 服务实例,需要外部服务管理器兜底。
- Android/iOS 不在本仓库范围内。
|