git:20260811.eedfbb7 to git:20260903.1b050e7

33 added, 206 removed. Audit A to A.

---
name: develop-fingerprint
- description: 当用户希望在平台侧编写、生成、完善、检查、保存、更新或删除指纹规则时使用。该 skill 用于生成符合 FingerprintComponent 约束的 HTTP/TCP 指纹 rule.requests 与 rule.script,并要求通过平台 FingerprintTools 查询已有指纹、读取详情、保存和删除,不直接读写 VFS 指纹文件。
+ description: 当用户希望在平台侧编写、生成、完善、检查、保存、更新或删除指纹规则时使用。指纹由 NetworkProbe 采集证据,服务侧使用声明式 rule.match 判定。
---
# 开发平台侧指纹
- 使用这个 skill 辅助用户编写平台指纹。所有平台指纹管理动作都必须通过 Tools 完成,不要让 Agent 自己读写 `root/fingerprint`、VFS 文件或本地 JSON 文件。
-
- 可用工具由 `FingerprintTools` 提供:
-
- - `listFingerprints(protocol?)`: 获取全部指纹摘要,或按 `http`、`tcp` 等协议筛选。
- - `getFingerprintById(fingerprintId)`: 获取完整指纹对象,包含 `rule`。
- - `saveFingerprint(userId, name, ruleJson, infoJson, protocol, tagsJson, version)`: 创建或覆盖保存指纹。
- - `deleteFingerprint(userId, fingerprintId)`: 删除指定指纹。
+ 所有指纹管理动作必须通过 `FingerprintTools` 完成,不直接读写 VFS 文件。
- 如果需要保存或删除但缺少 `userId`,优先通过平台用户工具确认;仍无法确定时询问用户。不要猜测 `userId`。
+ 可用工具:`listFingerprints(protocol?)`、`getFingerprintById(fingerprintId)`、`saveFingerprint(...)`、`deleteFingerprint(...)`。
## 工作流程
- ### 执行前:制定计划
-
- 查询、生成、自检、保存等多个依赖阶段同时存在时调用 `createPlan` 跟踪真实进度;
- 简单查看或单次解释直接执行,不额外输出固定计划模板。用户给了 fingerprintId 时,先用
- `getFingerprintById` 读取当前内容。
-
- ---
-
- 1. 明确用户意图:
- - 只生成指纹草稿
- - 创建并保存新指纹
- - 修改已有指纹
- - 检查或解释已有指纹
- - 删除指纹
- 2. 查询现状:
- - 用户给了 `fingerprintId`:先调用 `getFingerprintById(fingerprintId)`。
- - 用户只给了产品名或协议:先调用 `listFingerprints(protocol?)`,检查是否已有相近指纹。
- 3. 生成或修改指纹:
- - 只生成 `name`、`protocol`、`tags`、`info`、`rule.requests`、`rule.script`。
- - 不手工生成或写入文件;`fingerprintId` 由保存工具按 `name + "_" + version` 生成。
- 4. 自检规则:
- - `rule.requests` 必须是非空数组。
- - `rule.script` 必须非空。
- - HTTP 指纹使用 HTTP 响应字段。
- - TCP 指纹使用 `protocol=tcp`,脚本读取 `resp[n].raw`。
- - 脚本对空值和请求失败保持容错。
- 5. 保存:
- - 用户明确要求“保存”“创建”“更新”时才调用 `saveFingerprint`。
- - 用户只要求“写一个”“给草稿”“看看怎么写”时不要保存。
- - 保存前如果同名同版本可能覆盖已有指纹,先说明覆盖风险,除非上下文已经明确是更新。
- 6. 输出:
- - 如果已调用 Tool,报告 Tool 动作和返回的 `fingerprintId`。
- - 如果未保存,明确说明这是草稿。
-
- ## 指纹对象规范
+ 1. 查询同协议或同 ID 的现有指纹。
+ 2. 设计无副作用的 `rule.requests`。
+ 3. 使用声明式 `rule.match` 表达命中条件,不生成 JavaScript。
+ 4. 保存前确认 `userId`、名称、版本和覆盖风险。
+ 5. 保存后报告 `fingerprintId`,并建议在授权目标上验证误报与漏报。
- 完整指纹对象推荐结构如下。保存 Tool 的 `ruleJson` 只传其中的 `rule` 对象,不传完整对象。
+ ## 规则结构
```json
{
"name": "nginx",
"protocol": "http",
"tags": ["web", "server"],
- "info": {
- "version": "1.0",
- "description": "Detects Nginx by HTTP server header or default page markers."
- },
+ "info": {"version": "1.0"},
"rule": {
"requests": [
- {
- "method": "GET",
- "uri": "/",
- "timeout": 3000,
- "charset": "UTF-8",
- "maxBodyBytes": 1048576
- }
+ {"method": "GET", "path": "/", "timeout": 3000, "maxBodyBytes": 8192}
],
- "script": "var b = String(body || '').toLowerCase(); var h = String(headers || '').toLowerCase(); status == 200 && (h.indexOf('nginx') >= 0 || b.indexOf('welcome to nginx') >= 0)"
+ "match": {
+ "any": [
+ {"field": "headers", "operator": "contains", "value": "nginx"},
+ {"field": "body", "operator": "contains", "value": "welcome to nginx"}
+ ]
+ }
}
}
```
- 必填字段:
-
- - `name`: 指纹名称。
- - `rule.requests`: 非空数组。
- - `rule.script`: 非空 JavaScript 脚本。
- - `info.version` 或 `version`: 保存时用于生成 `fingerprintId`。
-
- 推荐字段:
-
- - `protocol`: `http` 或 `tcp`。
- - `tags`: 短标签,例如 `web`、`server`、`database`、`middleware`、`cms`。
- - `info.description`: 说明识别依据、适用版本和误报边界。
-
- ## saveFingerprint 参数
-
- 调用保存 Tool 时按以下方式拆分:
-
- - `userId`: 创建/更新人。
- - `name`: 指纹名称,例如 `nginx`。
- - `ruleJson`: 只传 `rule` 对象的 JSON 字符串。
- - `infoJson`: 传 JSON 对象字符串,至少包含 `version`。
- - `protocol`: `http` 或 `tcp`。
- - `tagsJson`: 传 JSON 数组字符串,例如 `["web","server"]`。
- - `version`: 可直接传版本;如果为空,Tool 会从 `infoJson.version` 读取,仍为空则使用默认版本。
-
- 示例:
-
- ```text
- saveFingerprint(
- userId="admin",
- name="nginx",
- ruleJson="{\"requests\":[{\"method\":\"GET\",\"uri\":\"/\",\"timeout\":3000}],\"script\":\"var b = String(body || '').toLowerCase(); var h = String(headers || '').toLowerCase(); status == 200 && (h.indexOf('nginx') >= 0 || b.indexOf('welcome to nginx') >= 0)\"}",
- infoJson="{\"version\":\"1.0\",\"description\":\"Detects Nginx by HTTP server header or default page markers.\"}",
- protocol="http",
- tagsJson="[\"web\",\"server\"]",
- version="1.0"
- )
- ```
-
- ## HTTP 规则
-
- HTTP request 支持:
-
- ```json
- {
- "method": "GET",
- "uri": "/",
- "path": "/",
- "headers": {
- "User-Agent": "LeoAI-Fingerprint"
- },
- "body": "",
- "timeout": 3000,
- "charset": "UTF-8",
- "maxBodyBytes": 1048576
- }
- ```
-
- 规则:
-
- - `method` 默认 `GET`。
- - `uri` 优先于 `path`;两者都为空时默认 `/`。
- - `uri` 可以是绝对 URL;否则会和 target 的 `baseUrl` 拼接。
- - 只有 `POST`、`PUT`、`PATCH` 且存在 `body` 时才发送请求体。
- - 默认 `timeout=3000`、`charset=UTF-8`、`maxBodyBytes=1048576`。
- - HTTP 不跟随重定向;HTTPS 信任所有证书。
-
- HTTP 响应字段:
-
- ```javascript
- resp[0].status
- resp[0].body
- resp[0].bodyLength
- resp[0].truncated
- resp[0].headers
- ```
-
- 只有一个响应时,组件会把响应字段提升为变量:
-
- ```javascript
- status
- body
- bodyLength
- truncated
- headers
- ```
-
- HTTP 脚本应组合多个证据,避免只靠弱关键字:
+ `rule.requests` 必须为非空数组。HTTP 请求支持 `method`、`path`/`uri`、`headers`、`body`、`timeout`、`charset`、`maxBodyBytes`;TCP 请求支持 `body`、`timeout`、`maxBodyBytes`。证据最多读取 8192 字节。
- ```javascript
- var b = String(body || '').toLowerCase();
- var h = String(headers || '').toLowerCase();
- status == 200 && (h.indexOf('nginx') >= 0 || b.indexOf('welcome to nginx') >= 0)
- ```
+ `rule.match` 支持:
- ## TCP 规则
+ - 组合:`all`、`any`、`not`
+ - 字段:`status`、`body`、`headers`、`raw`、`bodyLength`、`truncated`、`error`、`errorCode`
+ - 操作:`contains`、`notcontains`、`equals`、`in`、`exists`、`startswith`、`endswith`
+ - 多请求规则用 `request` 指定从 0 开始的请求序号
+ - 字符串默认忽略大小写;需要区分大小写时设置 `"ignoreCase": false`
- TCP 指纹要求目标使用 `protocol=tcp`。request 支持:
+ TCP 示例:
```json
{
- "body": "PING\r\n",
- "timeout": 3000,
- "charset": "UTF-8",
- "maxBodyBytes": 1048576
+ "requests": [{"body": "PING\r\n", "timeout": 3000}],
+ "match": {
+ "any": [
+ {"field": "raw", "operator": "contains", "value": "+PONG"},
+ {"field": "raw", "operator": "contains", "value": "-NOAUTH"}
+ ]
+ }
}
```
- TCP 响应字段:
-
- ```javascript
- resp[0].raw
- resp[0].bytes
- resp[0].bodyLength
- resp[0].truncated
- ```
-
- TCP 脚本示例:
-
- ```javascript
- var r = String(resp[0].raw || '');
- r.indexOf('PONG') >= 0 || r.indexOf('NOAUTH') >= 0
- ```
-
- ## 脚本约束
-
- `rule.script` 由 JVM JavaScript ScriptEngine 执行。返回以下值视为命中:
-
- - Boolean `true`
- - 非 0 数字
- - 字符串 `"true"`,忽略大小写
-
- 编写脚本时:
-
- - 使用 ES5 风格语法,避免依赖现代浏览器 API。
- - 多请求规则使用 `resp[0]`、`resp[1]` 明确索引。
- - 对 `body`、`raw`、`headers` 做字符串匹配前先用 `String(value || '')` 兜底。
- - 某个 request 失败时,对应 `resp[i]` 是错误对象,包含 `requestIndex`、`errorType`、`error`。
- - 不要编写会修改目标状态的探测请求,除非用户明确要求且场景合法。
-
- ## 输出格式
-
- 最终回复保持简洁,包含:
-
- 1. `计划`:目标服务、协议类型和执行步骤
- 2. `目标服务和协议`
- 3. `识别依据`
- 4. `生成的关键 rule 或完整 JSON 草稿`
- 5. `调用了哪些 Fingerprint Tools`
- 6. `是否已保存`
- 7. `保存后的 fingerprintId`(如已保存)
- 8. `下一步建议`:根据操作结果给出 1~2 条具体建议,例如:
- - 指纹已保存 → "建议在目标 Puppet 上执行指纹探测,验证识别效果"
- - 只生成了草案 → "草案已就绪,确认后可调用 saveFingerprint 保存"
- - 指纹规则较弱(单一关键词匹配)→ "建议增加多个证据组合(如 header + body),降低误报率"
-
- 如果 Tool 调用失败,说明失败的 Tool、错误信息和下一步修正建议。
+ 优先组合两个以上稳定证据,避免只靠宽泛关键词。探测请求不得修改目标状态,除非用户明确授权且任务确有必要。