Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions .flocks/plugins/skills/sangfor-edr-use/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,22 @@ description: 用于处理深信服 EDR(终端检测与响应)相关任务,

# 深信服 EDR Use

## First
## First

### 登录态处理规则

当用户需要打开深信服 EDR 页面,或需要通过 Web2CLI 抓取 EDR 页面请求时,必须按下面顺序处理登录态,不要一开始就要求用户提供账密:

1. 先调用 `sangfor_edr_auth` 的 `action=status_auth_state` 或 `action=validate_auth_state`,检查 `~/.flocks/browser/sangfor-edr/auth-state.json` 是否存在且可用。
2. 如果登录态可用,直接复用该 state,继续打开 EDR 页面或执行 Web2CLI 抓取流程。
3. 如果 state 不存在或已失效,但本地已经保存了 EDR 地址、用户名和密码,调用 `sangfor_edr_auth` 的 `action=ensure_auth_state` 自动刷新登录态。
4. 如果没有可用 state,也没有保存账密配置,再引导用户选择:
- 提供 EDR 访问地址、用户名和密码,自动登录并保存账密配置,后续 state 失效时可直接自动刷新;
- 不提供账密,走浏览器手动登录流程。打开 EDR 页面后由用户在可视化浏览器中完成登录,登录成功后保存完整浏览器登录态(包括 cookies、localStorage 等)。

无论采用哪种方式,只要获得可用登录态,就继续原有浏览器 / Web2CLI 流程:加载登录态、打开目标 EDR 页面、按需注入 Web2CLI hook、执行页面操作并导出捕获到的请求。后续再次打开页面时,仍必须先校验 `auth-state.json`;若登录态失效且已保存账密,则自动重新走 CDP 登录并刷新 state。

若自动登录过程中出现验证码识别失败、MFA 校验、页面选择器变化、未检测到登录成功或有效 `sessionid` 等情况,立即回退到原有浏览器手动登录流程。

> ⚠️ **EDR 没有开放 API**,所有操作必须通过浏览器(CDP 直连)完成。

Expand Down Expand Up @@ -81,4 +96,4 @@ powershell -Command "& '<FLOCKS_VENV>\Scripts\python.exe' '<FLOCKS_PLUGINS>\skil
- ✅ 正确:`<FLOCKS_VENV>/bin/python`(Unix)或 `<FLOCKS_VENV>\Scripts\python.exe`(Windows)
- ❌ 禁止:`python script.py` / `python3 script.py`(直接调用 PATH 中的 Python)

**原因**:Flocks 虚拟环境包含了所有项目依赖,系统 Python 可能缺少必要的包。完整跨平台示例见上一节"执行示例"。
**原因**:Flocks 虚拟环境包含了所有项目依赖,系统 Python 可能缺少必要的包。完整跨平台示例见上一节"执行示例"。
43 changes: 32 additions & 11 deletions .flocks/plugins/skills/sangfor-edr-use/references/cdp-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,14 @@ google-chrome --remote-debugging-port=9222
chromium --remote-debugging-port=9222
```

### 3. 登录 EDR
确保用户在 Chrome 中已登录 EDR(如需 MFA,完成认证)。
### 3. 登录 EDR
登录态必须先检查再分流,不要一开始就要求用户提供账密:

1. 调用 `sangfor_edr_auth`,`action=status_auth_state`,确认固定 state 是否存在、是否可用,以及是否已有可自动刷新的账密配置。
2. 如果返回的 `validation.valid` 为 `true`,直接复用已保存 state。
3. 如果 state 不存在或失效,但 `can_auto_refresh` 为 `true`,调用 `sangfor_edr_auth`,`action=ensure_auth_state`,通过 browser daemon / CDP 驱动真实 EDR 登录页自动登录。验证码图片在浏览器会话中获取,OCR 识别后填入页面;登录成功后保存浏览器 state。
4. 如果没有可用 state,也没有保存账密配置,再询问用户:提供 EDR 地址、用户名、密码后自动登录并保存,或不提供账密改走手动登录。
5. 用户不提供账密、自动登录失败、MFA/验证码/OCR/DOM 选择器异常时,由用户在 Chrome 中手动登录 EDR(如需 MFA,完成认证),登录成功后保存浏览器 state。

---

Expand All @@ -64,13 +70,27 @@ flocks browser --doctor
flocks browser --setup
```

### Step 3:用户打开目标页面
用户在 Chrome 中打开:
```
{EDR_URL}/ui/#/index
```

### Step 4:执行抓取脚本
### Step 3:准备登录态
优先检查固定 state 文件:
```
~/.flocks/browser/sangfor-edr/auth-state.json
```

推荐先调用工具做状态检查:

- `action=status_auth_state`:返回 `auth_state_exists`、`validation.valid`、`can_auto_refresh` 等非敏感状态。
- `validation.valid=true`:直接继续 Step 4。
- `validation.valid=false` 且 `can_auto_refresh=true`:调用 `action=ensure_auth_state` 自动打开真实登录页、识别验证码、填入账密并保存新的 state。
- `validation.valid=false` 且 `can_auto_refresh=false`:再询问用户是提供账密自动登录并保存,还是手动登录。
- 用户拒绝提供账密或自动登录失败:提示用户在 Chrome 中手动登录,登录成功后执行 `flocks browser state save ~/.flocks/browser/sangfor-edr/auth-state.json`。

### Step 4:打开目标页面
用户或工具在 Chrome 中打开:
```
{EDR_URL}/ui/#/index
```

### Step 5:执行抓取脚本

**工具脚本路径**(位于 skill references 目录):
```
Expand Down Expand Up @@ -175,7 +195,8 @@ print(text_result["result"]["result"]["value"])
| `Target.getTargets` 返回空 | 浏览器未开启 remote debugging | 用户执行 `chrome.exe --remote-debugging-port=9222` |
| EDR tab 未找到 | 页面未打开或 URL 不匹配 | 确保 Chrome 中打开了 EDR 首页 |
| 页面数据为空 | EDR 内容在跨域 iframe 中 | 用 CDP direct 方式 attach 到 EDR tab,在正确 frame context 执行 JS |
| 页面显示登录框 | 会话已失效 | 告知用户重新登录 EDR |
| 页面显示登录框 | 会话已失效 | 若已保存账密,调用 `sangfor_edr_auth` 自动刷新 state;否则提示用户手动登录 EDR |
| 自动登录失败 | 验证码识别失败、MFA、页面选择器变化或登录成功检测失败 | 回退到浏览器手动登录,登录后保存 state |

---

Expand Down Expand Up @@ -204,4 +225,4 @@ powershell -Command "& '<FLOCKS_VENV>\Scripts\python.exe' '<FLOCKS_PLUGINS>\skil
```bash
# macOS / Linux
"<FLOCKS_VENV>/bin/python" "<FLOCKS_PLUGINS>/skills/sangfor-edr-use/references/fetch_edr_system_state.py" --url "https://edr.example.com/"
```
```
130 changes: 109 additions & 21 deletions .flocks/plugins/skills/skyeye-sensor-use/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,98 @@ description: 使用天眼 SkyEye Sensor 传感器侧精简 CLI 查询告警列
> 对后台任务 / 定时任务,或系统不支持可视化,使用 `browser-use` 的 `cdp-headless` 模式。

State 文件路径:`~/.flocks/browser/skyeye-sensor/auth-state.json`(固定,全局唯一)。
自动登录配置路径:`~/.flocks/browser/skyeye-sensor/auth-config.json`(只保存 base_url、state 路径和 secret 引用;密码写入 Flocks secret)。

## 跨平台执行约定(必须遵守)

`scripts/skyeye_sensor_auth.py` 和 `scripts/skyeye_sensor_cli.py` 都是 **skill-relative** 路径。执行任何脚本前,必须先把当前工作目录切到 `skill_load` 输出中的 **Base directory**,不要假设当前 shell 已经在 skill 目录,也不要拼未加引号的绝对路径。

推荐方式:

- 如果工具支持 `workdir` 参数,直接把 `workdir` 设为 `skill_load` 输出的 Base directory,再运行 `uv run python scripts/...`。
- 如果只能写 shell 命令,先进入 Base directory,再运行脚本。
- 跨平台示例优先使用 `--base-url`、`--auth-state` 等 CLI 参数,少用 shell 环境变量前缀。
- Windows PowerShell 设置环境变量必须用 `$env:NAME = 'value'`;不要用 POSIX 的 `NAME=value command`。
- macOS/Linux shell 可以用 `NAME=value command` 或 `export NAME=value`。
- 路径含空格时必须整体加引号。Windows 下优先用 `Set-Location -LiteralPath '<skill-dir>'`,macOS/Linux 下优先用 `cd "$SKILL_DIR"`。
- 不要在 `glob` / 文件工具的 `path` 参数里写 `$env:USERPROFILE`、`$HOME` 这类 shell 变量;这些参数通常不会做 shell 展开。需要用户目录时,用 `~/.flocks/...` 或先在 shell 里展开后再传入。

Windows PowerShell 模板:

```powershell
Set-Location -LiteralPath '<skill-load 输出的 Base directory>'
uv run python scripts/skyeye_sensor_auth.py --base-url 'https://<skyeye-sensor-domain>' validate
uv run python scripts/skyeye_sensor_cli.py --base-url 'https://<skyeye-sensor-domain>' alarm list --days 7
```

macOS/Linux 模板:

```bash
cd "<skill-load 输出的 Base directory>"
uv run python scripts/skyeye_sensor_auth.py --base-url 'https://<skyeye-sensor-domain>' validate
uv run python scripts/skyeye_sensor_cli.py --base-url 'https://<skyeye-sensor-domain>' alarm list --days 7
```

### 首次登录 / Session 过期重新登录

打开 SkyEye Sensor 页面或执行 CLI 前,必须按下面顺序处理登录态,不要一开始就要求用户提供账密:

1. 先检查 `auth-state.json` 是否可用。
2. 如果 state 可用,直接复用登录态继续打开页面或执行 CLI 获取数据。
3. 如果 state 不存在或失效,但本地已有可用于自动登录的配置,先在 skill Base directory 中执行自动刷新:`uv run python scripts/skyeye_sensor_auth.py ensure`。
4. 如果没有可用 state,也没有保存账密配置,再引导用户选择:
- 提供 SkyEye Sensor 地址、用户名、密码,自动登录并保存账密配置,后续 state 失效时可直接自动刷新;
- 不提供账密,走浏览器手动登录流程。
5. 只有自动登录失败、验证码 OCR / MFA / 登录页 DOM 变化 / 登录成功检测失败,或用户拒绝提供账密时,才回退手动登录。

只读查看本地是否具备自动刷新条件(需在 skill Base directory 中执行):

```bash
flocks browser --doctor
uv run python scripts/skyeye_sensor_auth.py status
```

如果 `flocks browser --doctor` 提示浏览器已运行,但 daemon 或 active browser connection 不可用,必须直接提示用户
检查 state 是否可用(需在 skill Base directory 中执行)

```text
browser: not connected — 请确保 Chrome / Chromium / Edge 已打开,然后访问对应浏览器的 inspect 页面(例如 chrome://inspect/#remote-debugging 或 edge://inspect/#remote-debugging)并勾选 Allow remote debugging
```bash
uv run python scripts/skyeye_sensor_auth.py --base-url https://<skyeye-sensor-domain> validate
```

然后等待用户进一步指示,不要直接操作
如果 `validate` 返回 `valid: true`,继续后续页面操作或 CLI 查询;如果返回 `auth_state_not_found`、`auth_state_expired_or_login_page` 或 `auth_state_load_failed`,再看 `status` 中 `can_auto_refresh` 是否为 `true`

当用户确认已开启 remote debugging 后:
有已保存账密配置时自动刷新(需在 skill Base directory 中执行):

```bash
uv run python scripts/skyeye_sensor_auth.py ensure
```

自动刷新成功后继续执行原页面或 CLI 操作;失败才进入下方用户选择流程。

```bash
flocks browser --doctor
```

如果 `flocks browser --doctor` 提示浏览器已运行,但 daemon 或 active browser connection 不可用,先执行 `flocks browser --setup` 触发 attach,不要先要求用户重复勾选 Allow remote debugging。

1. 执行 `flocks browser --setup` 触发交互式 attach,不要用短超时包装该命令。
2. 再运行 `flocks browser --doctor` 做只读确认。
3. 如果还失败,先执行 `flocks browser --reload` 清理旧 daemon,再重新执行 `flocks browser --setup`,避免因为残留 daemon 造成干扰。
4. 只有随后 `--doctor` 通过后,才继续后面的登录或页面操作。
3. 如果 `--setup` 或 `--doctor` 明确提示 remote debugging 未启用,再提示用户打开 inspect 页面(例如 `chrome://inspect/#remote-debugging` 或 `edge://inspect/#remote-debugging`)并勾选 Allow remote debugging。
4. 如果还失败,先执行 `flocks browser --reload` 清理旧 daemon,再重新执行 `flocks browser --setup`,避免因为残留 daemon 造成干扰。
5. 只有随后 `--doctor` 通过后,才继续后面的登录或页面操作。

打开登录页并等待用户手动完成登录(含短信验证码 / MFA 等):
当必须询问用户时,说明两种选择并尊重用户偏好:

- 提供账密并保存:调用 `scripts/skyeye_sensor_auth.py`,通过 browser daemon / CDP 驱动真实登录页自动登录。脚本会优先从登录页验证码图片元素动态获取图片、OCR 识别、填入页面、保存 state,并把用户名/密码写入 Flocks secret,把基础配置保存到 `~/.flocks/browser/skyeye-sensor/auth-config.json`。后续 `auth-state.json` 失效时,可在 skill Base directory 中直接执行 `uv run python scripts/skyeye_sensor_auth.py ensure`。
- 不提供账密:沿用原有浏览器登录流程。打开登录页后由用户手动完成登录(含短信验证码 / MFA 等),登录成功后保存 state。

手动登录时,打开登录页并等待用户完成登录:

```bash
flocks browser -c '
tid = new_tab("https://<skyeye-sensor-domain>/login", activate=True)
wait_for_load()
print(tid)
print(page_info())
import json
print(json.dumps(page_info(), ensure_ascii=True))
'
```

Expand All @@ -66,6 +128,32 @@ print(page_info())
flocks browser state save ~/.flocks/browser/skyeye-sensor/auth-state.json
```

提供账密并保存时,执行自动登录:

```bash
uv run python scripts/skyeye_sensor_auth.py --base-url https://<skyeye-sensor-domain> ensure --username '<username>' --password '<password>'
```

下次 `auth-state.json` 失效且本地保存过账密配置时,可直接执行:

```bash
uv run python scripts/skyeye_sensor_auth.py ensure
```

也可以在查询命令前直接带账密或使用已保存账密刷新登录态:

```bash
uv run python scripts/skyeye_sensor_cli.py \
--base-url https://<skyeye-sensor-domain> \
--username '<username>' \
--password '<password>' \
alarm count

uv run python scripts/skyeye_sensor_cli.py --auto-login alarm list
```

如果验证码 OCR、MFA、登录页 DOM 变化或登录成功检测失败,回退到上面的手动登录流程。

### CLI 认证失败时的恢复流程

当 CLI 出现以下任一情况,优先判定为认证问题(**不要立刻要求用户重新登录**):
Expand All @@ -82,13 +170,15 @@ flocks browser state load ~/.flocks/browser/skyeye-sensor/auth-state.json --url

# 2) 读取当前页面状态
flocks browser -c '
print(page_info())
import json
print(json.dumps(page_info(), ensure_ascii=True))
'
```

```bash
# 3) 根据结果决策
URL=$(flocks browser -c '
import json
info = page_info()
print(info.get("url", ""))
' | tail -n 1)
Expand All @@ -112,10 +202,11 @@ CLI 在 skill 内:

执行命令时:

1. 优先使用 `uv run python scripts/skyeye_sensor_cli.py ...`
2. 认证优先使用浏览器导出的 `auth-state.json`
1. 必须先进入 `skill_load` 输出的 Base directory,或把命令工具的 `workdir` 设置为该目录。
2. 优先使用 `uv run python scripts/skyeye_sensor_cli.py ...`
3. 认证优先使用浏览器导出的 `auth-state.json`

认证环境变量
可选认证环境变量

- `SKYEYE_SENSOR_BASE_URL=https://<skyeye-sensor-domain>`
- `SKYEYE_SENSOR_AUTH_STATE=~/.flocks/browser/skyeye-sensor/auth-state.json`
Expand All @@ -124,7 +215,7 @@ CLI 在 skill 内:

## 常用命令

如果已经通过 `export` 设置好环境变量
如果已经通过环境变量或 CLI 参数设置好认证信息

```bash
# 默认输出 JSON
Expand All @@ -139,13 +230,10 @@ uv run python scripts/skyeye_sensor_cli.py alarm list --days 7 --hazard-level "3
uv run python scripts/skyeye_sensor_cli.py alarm list --days 7 --table
```

带认证的完整单行格式(无需提前 export,适合直接执行):
带认证的完整单行格式(无需提前 export,适合 Windows/macOS/Linux 直接执行):

```bash
SKYEYE_SENSOR_BASE_URL=https://<skyeye-sensor-domain> \
SKYEYE_SENSOR_AUTH_STATE=~/.flocks/browser/skyeye-sensor/auth-state.json \
uv run python scripts/skyeye_sensor_cli.py \
alarm list --days 7 --hazard-level "3,2" --json
uv run python scripts/skyeye_sensor_cli.py --base-url https://<skyeye-sensor-domain> --auth-state ~/.flocks/browser/skyeye-sensor/auth-state.json alarm list --days 7 --hazard-level "3,2"
```

## 查询策略
Expand Down Expand Up @@ -250,7 +338,7 @@ uv run python scripts/skyeye_sensor_cli.py alarm count --days 7 --hazard-level "

## 重要提醒

- **Session 管理**:详见[零、登录认证](#零登录认证)。任务开始前先确认 `auth-state.json` 存在;CLI 认证失败时先走恢复流程,不要立刻要求用户重新登录。
- **Session 管理**:详见[零、登录认证](#零登录认证)。任务开始前先用 `skyeye_sensor_auth.py validate` 确认 `auth-state.json` 可用;CLI 认证失败时先走恢复流程,不要立刻要求用户重新登录。
- **禁止连续失败循环**:同一命令最多重试 2 次;认证恢复流程只走一次,仍失败则提示用户手动重新登录。
- **以下错误属于需要用户干预的基础设施问题,立即停止所有重试,直接告知用户处理**:
- `ERR_CERT_AUTHORITY_INVALID`:站点证书不被本机信任,使用--ignore-https-errors 或 请求用户处理。
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
# SkyEye Sensor 查询参考

CLI 路径:`./.flocks/skills/skyeye-sensor-data-fetch/scripts/skyeye_sensor_cli.py`
CLI 路径:`scripts/skyeye_sensor_cli.py`(相对于 `skill_load` 输出的 Base directory)

建议在 `./.flocks/skills/skyeye-sensor-data-fetch/scripts` 目录执行,并通过环境变量提供认证信息:
执行前必须先进入 `skill_load` 输出的 Base directory,或把命令工具的 `workdir` 设置为该目录。不要假设当前工作目录在 skill 目录,也不要拼未加引号的绝对路径。

Windows PowerShell:

```powershell
Set-Location -LiteralPath '<skill-load 输出的 Base directory>'
uv run python scripts/skyeye_sensor_auth.py --base-url 'https://<skyeye-sensor-domain>' validate
```

macOS / Linux:

```bash
export SKYEYE_SENSOR_BASE_URL="https://<skyeye-sensor-domain>"
export SKYEYE_SENSOR_AUTH_STATE="$HOME/.flocks/browser/skyeye-sensor/auth-state.json"
cd "<skill-load 输出的 Base directory>"
uv run python scripts/skyeye_sensor_auth.py --base-url 'https://<skyeye-sensor-domain>' validate
```

备选认证方式(无 state 文件时):
Expand All @@ -23,13 +32,13 @@ export SKYEYE_SENSOR_AUTH_STATE="$HOME/.flocks/browser/skyeye-sensor/auth-state.

```bash
# 告警明细
uv run python skyeye_sensor_cli.py alarm list --days 7 --page 1 --page-size 10
uv run python scripts/skyeye_sensor_cli.py alarm list --days 7 --page 1 --page-size 10

# 按条件过滤
uv run python skyeye_sensor_cli.py alarm list --hours 6 --sip "1.1.1.1"
uv run python scripts/skyeye_sensor_cli.py alarm list --hours 6 --sip "1.1.1.1"

# 告警统计
uv run python skyeye_sensor_cli.py alarm count --days 1 --sip "1.1.1.1"
uv run python scripts/skyeye_sensor_cli.py alarm count --days 1 --sip "1.1.1.1"
```

## 适用范围
Expand Down Expand Up @@ -98,19 +107,19 @@ uv run python skyeye_sensor_cli.py alarm count --days 1 --sip "1.1.1.1"

```bash
# 最近 7 天,某源 IP 的告警
uv run python skyeye_sensor_cli.py alarm list --days 7 --sip "1.1.1.1"
uv run python scripts/skyeye_sensor_cli.py alarm list --days 7 --sip "1.1.1.1"

# 最近 24 小时,高危 + 严重告警
uv run python skyeye_sensor_cli.py alarm list --hours 24 --hazard-level "3,2"
uv run python scripts/skyeye_sensor_cli.py alarm list --hours 24 --hazard-level "3,2"

# 指定威胁类型 + 主机状态
uv run python skyeye_sensor_cli.py alarm list \
uv run python scripts/skyeye_sensor_cli.py alarm list \
--days 7 \
--threat-type "2,3" \
--host-state "0,1,2,-1"

# 只统计数量
uv run python skyeye_sensor_cli.py alarm count --days 1 --sip "1.1.1.1"
uv run python scripts/skyeye_sensor_cli.py alarm count --days 1 --sip "1.1.1.1"
```

---
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
click>=8.0.0
requests>=2.28.0
rich>=13.0.0
ddddocr>=1.6.1
Loading