文档类型:API 参考 关联软件:FoxAgent 更新于 2026-09-27

集成与 API

把 IFU 接进现有系统。

把 IFU 接进现有系统

1. 集成方式总览

方式 传输 默认监听 特点
HTTP TCP 0.0.0.0:42101 POST / 下发命令;GET /health、GET /capabilities 查询;/admin/* 管理;/console/ 本机控制台
TCP TCP 0.0.0.0:42102 每行一条 JSON 命令(NDJSON),长连接
UDP UDP 0.0.0.0:42103 单包一条 JSON 命令;同时承载设备发现协议

三种传输共用同一命令契约:同一命令在任一传输上的参数校验、MAC 守卫、响应结构完全一致。

2. 接口清单

接口 / 命令 协议 方法 鉴权 用途
/health HTTP GET 免认证 健康检查
/capabilities HTTP GET 免认证 能力清单
/ HTTP POST 见第 3 节 下发命令
/console/ HTTP GET 页面免认证 本机 Web 控制台(go:embed 内嵌静态资源,与 42101 共用端口、不新增进程;页内管理请求各自鉴权)
/admin/status HTTP GET 需认证 内核运行状态汇总(版本、运行时长、插件就绪比、能力可用比、注册命令数、三端口、认证方式)
/admin/commands HTTP GET 需认证 命令清单(由插件 manifest 派生,含命令作用 desc 与用法 usage、参数与结果 schema,供控制台渲染「功能测试」表单并动态说明命令)
/admin/plugins HTTP GET 需认证 插件清单
/admin/plugins/start HTTP POST 需认证 启动插件(?id=)
/admin/plugins/stop HTTP POST 需认证 停止插件(?id=)
/admin/plugins/enable HTTP POST 需认证 持久启用插件(?id=)
/admin/plugins/disable HTTP POST 需认证 持久禁用插件(?id=)
/admin/plugins/install HTTP POST 需认证 上传安装插件(报文体为插件包)
/admin/plugins/remove HTTP POST 需认证 卸载插件(?id=)
/admin/reload HTTP POST 需认证 重新扫描加载插件目录
/admin/doctor HTTP GET 需认证 触发指定插件能力探测(?id=)
/blob/{id} HTTP GET 需认证 下载插件上报的大对象(截图 / 文件内容 / 日志导出),内容流式返回;id 不合法 → 400,不存在 / 过期 / 未收齐 → 404
命令接口 TCP / UDP - 见第 3 节 与 HTTP POST / 同一契约

3. 认证

按顺序判定,命中即放行:

顺序 凭据 适用范围
1 mTLS 客户端证书 需 TLS 的 HTTP / TCP
2 应用层 HMAC 签名 HTTP / TCP / UDP 三层通用
3 访问令牌 HTTP 用请求头 X-Auth-Token;TCP / UDP 用报文字段 token
4 回环免认证 仅命令端点;管理端点(/admin/*)不适用
  • 令牌首次启动自动生成,写入配置文件 auth.token。
  • 回环来源(127.0.0.1 / ::1)免认证,但叠加 Origin / Referer / Host 校验;高危命令(power.*、screen.*、input.*、clipboard.*、process.kill、timesync.set、notify.toast)即使来自回环也强制认证。内核会把内置默认清单与 config.json 的 auth.high_risk_commands 做并集合并,因此覆盖安装后新增的高危命令自动生效、无需手改配置;可在配置里追加自定义项,但不能靠删配置项缩小保护范围。
  • 管理端点(/admin/*)无论来源一律要求令牌或证书,不接受回环免认证——否则任意网页都能借浏览器发起跨站请求来操作插件。
  • 免认证端点:GET /health、GET /capabilities;/console/ 页面本身为静态资源不鉴权,页内每个管理请求仍需令牌。

HMAC 签名三字段:sig(HMAC-SHA256,base64url 无填充)、ts(Unix 秒)、nonce(16 字节 base64url,同窗口内不重复)。 待签字符串:

FOXAGENT-HMAC-V1





其中 canonicalBody 是报文剔除 sig/ts/nonce 后重新序列化的结果;scope 命令请求为命令名,管理端点为「方法 + 空格 + 完整请求目标(含查询串)」。

4. 请求参数

所有命令均为扁平 JSON,核心字段:

字段 类型 必选 说明
cmd string ✅ 命令名
mac string ✅ 目标 MAC;all 表示广播。支持 aa:bb:cc:dd:ee:ff / aa-bb-.. / aabb.. / all
token string 非回环 访问令牌(HTTP 走请求头,此处可省)
value int 按命令 音量 0–100
mode string 按命令 枚举模式:sleep/hibernate;on/off/toggle
text string 按命令 键盘输入 / 剪贴板内容
key / mods string / []string 按命令 按键名;修饰键 ctrl/shift/alt/win
x / y int 按命令 鼠标屏幕坐标
button string 按命令 left/right/middle(默认 left)
scroll int 按命令 滚轮格数(正=上滚)

传输细节:HTTP POST /,Content-Type: application/json,上限 4KB;TCP 每行一条 JSON 以 结尾,单行上限 4KB;UDP 单包上限 2048 字节。

5. 命令表

插件 能力 命令 参数 响应 data
fox.power power power.off mac,delay,message -
fox.power power power.reboot mac,delay,message -
fox.power power power.abort mac {"aborted":true}
fox.power power power.uptime mac {"seconds":123456,"boot_time":""}
fox.power power power.suspend mac,mode -
fox.volume volume volume.get mac {"volume":50,"muted":false}
fox.volume volume volume.set mac,value -
fox.volume volume volume.mute mac,mode {"muted":true}
fox.volume volume volume.up mac,step {"volume":55}
fox.volume volume volume.down mac,step {"volume":45}
fox.screen screen screen.off / screen.on / screen.lock mac -
fox.input keyboard input.key.tap mac,key,mods -
fox.input keyboard input.key.type mac,text -
fox.input keyboard input.key.hold mac,key,duration,mods -
fox.input mouse input.mouse.move mac,x,y -
fox.input mouse input.mouse.move_relative mac,dx,dy -
fox.input mouse input.mouse.click mac,button,count -
fox.input mouse input.mouse.scroll mac,scroll,horizontal -
fox.input mouse input.mouse.drag mac,from_x,from_y,to_x,to_y,button,duration -
fox.input mouse input.cursor mac {"x":960,"y":540}
fox.input mouse input.screen_size mac {"width":1920,"height":1080}
fox.clipboard clipboard clipboard.write mac,text -
fox.clipboard clipboard clipboard.read mac {"text":"..."}
fox.clipboard clipboard clipboard.clear mac -
fox.clipboard clipboard clipboard.format mac {"formats":["CF_UNICODETEXT"]}
fox.discovery discovery (无命令,应答 UDP 发现) - -
fox.sysinfo sysinfo sysinfo.get mac,item JSON 字符串(系统 / CPU / 内存 / 磁盘 / 网卡)
fox.process process process.list mac,filter,sort,top JSON 字符串(进程数组)
fox.process process process.kill mac,pid,force {"pid":1234,"name":"notepad.exe","killed":true}
fox.timesync timesync timesync.get mac {"unix_time":1790561280,"unix_nano":...,"timezone":"Local","rfc3339":"..."}
fox.timesync timesync timesync.set mac,unix_time,dry_run {"applied":true,"offset_seconds":30,"rfc3339":"..."}
fox.notify notify notify.toast mac,title,message,level,timeout_ms {"shown":true,"timeout_ms":10000}
fox.disk disk disk.list mac JSON 字符串(分区用量与告警)
fox.screenshot screenshot screen.capture mac,display,format,quality,scale JSON 字符串(含 blob_id,经 GET /blob/{id} 下载)
fox.file file file.list mac,path,limit JSON 字符串(条目与统计)
fox.file file file.stat mac,path JSON 字符串(元信息,≤16MB 含 sha256)
fox.file file file.read mac,path,encoding,max_bytes JSON 字符串(≤512KB 内联,超过含 blob_id)
fox.log log log.list mac JSON 字符串(日志文件清单)
fox.log log log.tail mac,file,lines,filter JSON 字符串(尾部行与统计)
fox.log log log.export mac,file JSON 字符串(含 blob_id,经 GET /blob/{id} 下载)

大结果(screen.capture / file.read 超限时 / log.export)不放在返回体里,只回 blob_id 等引用, 内容经 GET /blob/{id} 流式下载(需认证,见第 2 节)。原因:内核读插件 stdout 有单行 1MB 上限。

5.1 设备发现(UDP 专用)

请求:

{"type":"discovery","action":"ping","timestamp":1758500000}

响应:

{"type":"discovery","action":"pong","mac":"00:e0:4c:82:84:54","response_time":0,"timestamp":1758500001,
 "hostname":"DESKTOP-ABC","os":"windows","arch":"amd64","kernel_version":"4.3.0","protocol_version":1,"uptime_seconds":123456}
  • pong 载荷字段:type、action、mac、response_time、timestamp,以及只读的 hostname / os / arch / kernel_version / protocol_version / uptime_seconds(后 6 项为本版新增)。
  • mac 为本机真实物理网卡 MAC(自动排除虚拟网卡);探测失败回退为 00:00:00:00:00:00。
  • 本机不执行任何校时:请求里的 timestamp 仅作对端比对用、被本机忽略,pong 里的 timestamp 是本机应答时刻。发现通道是无副作用的应答通道(UDP 分支不经认证层),不改变任何系统状态;如需校准目标机时钟,请改用经认证的 timesync.set 命令(见第 5 节命令表)。

6. 返回值

{
  "status": "success | error | skipped",
  "message": "人类可读信息",
  "data": { }
}
状态 含义
success 执行成功
error 执行失败,message 含原因(含能力不可用原因)
skipped MAC 不匹配,未执行

7. 错误码

HTTP 层

场景 响应
请求体为空 / JSON 非法 400
请求体超限(HTTP >4KB) 413 请求体过大(上限 4096 字节)
方法不允许 405
未认证 / 令牌错误 401 认证失败:Token 缺失或无效

插件协议层(不外露,仅内核日志)

错误码 含义
-32700 JSON 解析错误
-32601 方法 / 命令不存在
-32602 参数无效(协议层)
-32001 命令参数非法(业务层,内核 schema 校验产出)
-32002 命令不可用(能力缺失)

业务响应示例

情况 响应
缺少必填参数 {"status":"error","message":"参数 mac 非法:缺少必填参数 mac"}
MAC 不匹配 {"status":"skipped","message":"命令已跳过:目标 MAC 与本机不匹配"}
本机 MAC 无法确定 {"status":"error","message":"MAC地址获取失败: 未找到有效的网络接口"}
插件未运行 {"status":"error","message":"..."},需先 fox-agent plugin start

8. 调用示例

# 设置音量 30(命令端点,回环免 Token)
curl -X POST http://localhost:42101/ -H "Content-Type: application/json" 
  -d '{"cmd":"volume.set","mac":"all","value":30}'

# 组合键 Ctrl+Shift+Tab(input.key.tap 属高危命令,即便回环也需带 Token)
curl -X POST http://localhost:42101/ -H "Content-Type: application/json" 
  -H "X-Auth-Token: " 
  -d '{"cmd":"input.key.tap","mac":"all","key":"tab","mods":["ctrl","shift"]}'

# 写入剪贴板(clipboard.write 属高危命令,即便回环也需带 Token)
curl -X POST http://localhost:42101/ -H "Content-Type: application/json" 
  -H "X-Auth-Token: " 
  -d '{"cmd":"clipboard.write","mac":"all","text":"内容"}'

# 非回环:携带 Token
curl -X POST http://192.168.1.10:42101/ 
  -H "Content-Type: application/json" 
  -H "X-Auth-Token: " 
  -d '{"cmd":"power.reboot","mac":"aa:bb:cc:dd:ee:ff"}'

# 查询能力清单(免认证)
curl http://localhost:42101/capabilities

# TCP:每行一条命令
echo '{"cmd":"volume.get","mac":"all"}' | nc 127.0.0.1 42102

# 管理:查看插件清单(管理端点不接受回环免认证,必须带 Token)
curl -H "X-Auth-Token: " http://localhost:42101/admin/plugins

# 管理:内核状态汇总
curl -H "X-Auth-Token: " http://localhost:42101/admin/status

# 管理:命令清单(含命令作用、用法、参数与结果 schema,可当插件文档读)
curl -H "X-Auth-Token: " http://localhost:42101/admin/commands

本机 Web 控制台直接用浏览器打开 http://127.0.0.1:42101/console/ 即可;页面本身免认证,首次进入后把 auth.token 粘进登录框,后续页内管理请求会自动带上该令牌。

9. 集成注意事项

  • 连接数 / 超时:TCP 为长连接,单行上限 4KB;UDP 单包上限 2048 字节,超限请拆包或改用 TCP。
  • 心跳与发现:无插件处理发现请求时内核不回包,调用方应以超时判定「对端不存在」;建议超时 1–2 秒。
  • 签名防重放:nonce 在同一时间窗内只能用一次,重复即拒绝。
  • 时钟:启用 HMAC 时调用方与终端时钟须同步,否则会表现为「签名无效」。
  • 不降级原则:报文一旦出现 sig/ts/nonce,就必须验签通过,不允许「签名无效退回令牌」。
  • 能力先行:对接前先读 /capabilities,据此决定可调用范围;能力不可用时命令会直接失败并给出原因。

文档解决不了的,直接问我们

把现场条件和使用场景说清楚,我们的工程师会给出明确结论,而不是只发一份资料链接。