kboykov/wazuh-1password

GitHub: kboykov/wazuh-1password

将 1Password Events API 的审计事件、登录尝试和条目使用数据集成到 Wazuh SIEM 的生产就绪方案,包含轮询脚本、解码器和 35 条预构建检测规则。

Stars: 0 | Forks: 0

# Wazuh — 1Password Events API 集成 一个生产就绪的集成方案,用于将 [1Password Events API](https://developer.1password.com/docs/events-api/) 中的审计事件、登录尝试和条目使用事件拉取到 Wazuh 中,以实现实时告警、关联分析和取证调查。 ## 工作原理 ``` 1Password Events API │ │ POST /api/v2/{auditevents,signinattempts,itemusages} │ Bearer JWT · cursor-based pagination ▼ onepassword_events.py (runs every minute via Wazuh wodle command) │ │ Appends newline-delimited JSON to: │ /var/ossec/logs/onepassword/onepassword-events.json ▼ Wazuh localfile (json format) │ │ Matches prematch: "op_integration":"1password" ▼ 100-onepassword_decoders.xml (JSON_Decoder → extracts all fields) │ ▼ 100-onepassword_rules.xml (35 rules across 3 event types) │ ▼ Wazuh alerts / dashboards / SOAR ``` 该脚本每分钟运行一次,获取自上次游标以来的新页面数据,并将每行一个 JSON 对象写入日志文件。首次运行时,它会回填过去 24 小时(可配置)的数据。状态(每个端点的 API 游标)在两次运行之间以原子方式持久化,因此在重启期间不会丢失或重复任何事件。 由于 Wazuh 保留了诸如 `action`、`type`、`category` 和 `timestamp` 等字段名,该脚本会自动添加 `op_*` 别名(`op_action`、`op_type`、`op_category`、`op_event_timestamp`)并展平嵌套对象,以便规则能够匹配简单的顶层字段名。 ## 仓库内容 | 文件 | 用途 | |---|---| | `onepassword_events.py` | 轮询脚本 — 获取事件并写入 Wazuh 日志文件 | | `onepassword-events.env` | 环境配置(token、URL、调优参数) | | `ossec_config.xml` | Wazuh `ossec.conf` 配置片段 — wodle 命令 + localfile 配置段 | | `100-onepassword_decoders.xml` | Wazuh 解码器 — 识别并解析 1Password 事件的 JSON | | `100-onepassword_rules.xml` | Wazuh 规则 — 包含覆盖所有三种事件类型的 35 条规则 | ## 前置条件 - Wazuh manager 4.x(在 4.7 版本上测试) - Wazuh manager 主机上的 Python 3.8+(仅使用标准库 — 无需额外安装包) - 1Password Business 或 Enterprise 账户 - 具有所需功能范围(`auditevents`、`signinattempts`、`itemusages`)的 1Password Events API token - 如果您想通过 GitHub Actions 进行派生/部署,需要 `gh` CLI 或等效工具 ### 生成 1Password Events API token 1. 在 `.1password.com`(EU 租户为 `.eu`)登录您的 1Password 账户。 2. 转到 **Integrations → Directory → Events API**。 3. 点击 **Add Integration**,为其命名,并选择所有三种事件类型。 4. 复制 bearer token — 此令牌仅显示一次。 ## 安装说明 ### 1. 部署轮询脚本 ``` sudo cp onepassword_events.py /var/ossec/integrations/ sudo chown root:wazuh /var/ossec/integrations/onepassword_events.py sudo chmod 750 /var/ossec/integrations/onepassword_events.py ``` ### 2. 部署环境文件 ``` sudo cp onepassword-events.env /var/ossec/etc/onepassword-events.env sudo chown root:wazuh /var/ossec/etc/onepassword-events.env sudo chmod 640 /var/ossec/etc/onepassword-events.env ``` 编辑文件并设置您的 token 和基础 URL: ``` sudo nano /var/ossec/etc/onepassword-events.env ``` ``` ONEPASSWORD_EVENTS_TOKEN="eyJhbGc..." # paste your JWT here ONEPASSWORD_EVENTS_BASE_URL="https://events.1password.eu" # or .com for US ``` ### 3. 部署解码器和规则 ``` sudo cp 100-onepassword_decoders.xml /var/ossec/etc/decoders/ sudo cp 100-onepassword_rules.xml /var/ossec/etc/rules/ sudo chown root:wazuh /var/ossec/etc/decoders/100-onepassword_decoders.xml sudo chown root:wazuh /var/ossec/etc/rules/100-onepassword_rules.xml sudo chmod 640 /var/ossec/etc/decoders/100-onepassword_decoders.xml sudo chmod 640 /var/ossec/etc/rules/100-onepassword_rules.xml ``` ### 4. 添加 Wazuh 配置片段 将 `ossec_config.xml` 的内容添加到 `/var/ossec/etc/ossec.conf` 的 `` 块中: ``` no onepassword-events /var/ossec/integrations/onepassword_events.py 1m yes yes 60 json /var/ossec/logs/onepassword/onepassword-events.json ``` ### 5. 验证并重启 ``` sudo /var/ossec/bin/wazuh-logtest # optional — test decoder/rules manually sudo /var/ossec/bin/ossec-control restart ``` ### 6. 确认 ``` # 检查脚本是否正在运行并写入事件 sudo tail -f /var/ossec/logs/onepassword/onepassword-events.json | python3 -m json.tool # 检查状态(每个 endpoint 的 cursors) sudo cat /var/ossec/queue/onepassword/onepassword-events-state.json # 检查 Wazuh 是否正在生成 alerts sudo tail -f /var/ossec/logs/alerts/alerts.json | grep 1password ``` ## 配置参考 所有设置均通过环境变量控制,这些变量可以放置在 `/var/ossec/etc/onepassword-events.env` 环境文件中,或直接在进程环境中设置。 | 变量 | 默认值 | 描述 | |---|---|---| | `ONEPASSWORD_EVENTS_TOKEN` | _(必填)_ | 来自 1Password Events API 集成页面的 Bearer JWT | | `ONEPASSWORD_EVENTS_TOKEN_FILE` | — | 包含该 token 的文件路径(上述变量的替代方案) | | `ONEPASSWORD_EVENTS_BASE_URL` | `https://events.1password.eu` | API 基础 URL。EU 租户:`events.1password.eu`。US 租户:`events.1password.com` | | `ONEPASSWORD_ENV_FILE` | `/var/ossec/etc/onepassword-events.env` | 启动时加载的环境文件路径 | | `ONEPASSWORD_STATE_FILE` | `/var/ossec/queue/onepassword/onepassword-events-state.json` | 在两次运行之间持久化 API 游标的路径 | | `ONEPASSWORD_OUTPUT_FILE` | `/var/ossec/logs/onepassword/onepassword-events.json` | 供 Wazuh 读取的 JSON 日志文件路径 | | `ONEPASSWORD_BACKFILL_HOURS` | `24` | 首次运行(无现有游标)时要回填的小时数。最小 1,最大 720。 | | `ONEPASSWORD_LIMIT` | `500` | 每个 API 页面的事件数。最小 1,最大 1000。 | | `ONEPASSWORD_MAX_PAGES_PER_ENDPOINT` | `10` | 每次调用每个端点获取的最大页数。用于限制运行时间。 | | `ONEPASSWORD_HTTP_TIMEOUT` | `60` | HTTP 请求超时时间(以秒为单位)。 | | `ONEPASSWORD_SLEEP_BETWEEN_PAGES` | `0.25` | 分页请求之间的休眠时间(出于速率限制礼节)。 | | `ONEPASSWORD_ENABLE_AUDIT_EVENTS` | `yes` | 设置为 `no` 可禁用审计事件端点。 | | `ONEPASSWORD_ENABLE_SIGNIN_ATTEMPTS` | `yes` | 设置为 `no` 可禁用登录尝试端点。 | | `ONEPASSWORD_ENABLE_ITEM_USAGES` | `yes` | 设置为 `no` 可禁用条目使用端点。 | | `ONEPASSWORD_RUN_INTROSPECTION` | `yes` | 在轮询之前验证 token 并发现有权限的端点。如果您遇到自省速率限制,请禁用此选项。 | | `ONEPASSWORD_DEBUG` | `no` | 将每个 HTTP 请求和页面结果记录到 stderr。 | ## 解码字段参考 解码器从每个事件中提取所有 JSON 字段。规则中使用的关键字段: | 字段 | 来源 | 示例 | |---|---|---| | `op_integration` | 由脚本添加 | `1password` | | `op_event_type` | 由脚本添加 | `audit_events`、`sign_in_attempts`、`item_usages` | | `op_ingested_at` | 由脚本添加 | `2026-05-09T22:02:56Z` | | `op_action` | `action` 的别名 | `ssotknv`、`patch`、`delete`、`secure-copy` | | `op_object_type` | `object_type` 的别名 | `ssotkn`、`items`、`user`、`satoken` | | `op_category` | `category` 的别名 | `success`、`firewall_failed`、`mfa_failed` | | `op_type` | `type` 的别名 | `country_blocked`、`totp_bad`、`credentials_ok` | | `op_event_timestamp` | `timestamp` 的别名 | `2026-05-09T04:42:41Z` | | `op_uuid` | `uuid` 的别名 | `UNTSAALFEWVMF4PVTOIZVQYOM5` | | `op_actor_email` | 从 `actor_details.email` 展平 | `user@example.com` | | `op_actor_name` | 从 `actor_details.name` 展平 | `Jane Smith` | | `op_user_email` | 从 `user.email` 展平 | `user@example.com` | | `op_target_user_email` | 从 `target_user.email` 展平 | `user@example.com` | | `op_client_ip` | 从 `client.ip_address` 展平 | `203.0.113.10` | | `op_session_ip` | 从 `session.ip` 展平 | `203.0.113.10` | 嵌套对象(`client`、`user`、`target_user`、`actor_details`、`session`、`location`)也会以其原始嵌套形式保留。Wazuh 的 JSON 解码器会使用点表示法(例如 `client.ip_address`、`target_user.email`)公开它们,关联规则会利用这些表示法进行 `` 分组。 ## 规则覆盖范围 ### 基本规则 | 规则 ID | 级别 | 触发条件 | 描述 | |---|---|---|---| | 120000 | 4 | `op_integration = 1password` | 任何 1Password Events API 事件 | | 120001 | 3 | `op_event_type = audit_events` | 接收到审计事件 | | 120002 | 3 | `op_event_type = sign_in_attempts` | 接收到登录尝试事件 | | 120003 | 3 | `op_event_type = item_usages` | 接收到条目使用事件 | ### 登录尝试 | 规则 ID | 级别 | 触发条件 | 描述 | |---|---|---|---| | 120010 | 3 | `op_category = success` | 成功登录 | | 120011 | 7 | `op_category ∈ {credentials_failed, mfa_failed, sso_failed, modern_version_failed}` | 登录尝试失败 | | 120012 | 9 | `op_category = firewall_failed` | 登录被防火墙策略阻止 | | 120013 | 8 | `op_type ∈ 地理/IP 拦截值` AND category ≠ firewall_reported_success | 登录被地理/IP 访问策略阻止 | | 120014 | 8 | `op_type ∈ MFA 失败/禁用值` | 与 MFA 相关的登录失败 | | 120015 | 8 | `op_type ∈ SSO 失败值` | 与 SSO 相关的登录事件 | | 120016 | 7 | `op_type ∈ 凭据/密钥失败值` | 凭据或密钥登录失败 | | 120017 | 7 | `op_type ∈ {modern_version_missing, modern_version_old}` | 客户端版本过时或缺失 | | 120018 | 5 | `op_category = firewall_reported_success` | 成功的登录匹配了防火墙规则(报告模式) | **每条规则匹配的 op_type 值:** - **120013**(地理/IP 拦截):`ip_blocked`、`country_blocked`、`continent_blocked`、`anonymous_blocked`、`all_blocked` - **120014**(MFA):`mfa_missing`、`totp_bad`、`totp_timeout`、`totp_disabled`、`u2f_bad`、`u2f_timeout`、`u2f_disabled`、`duo_bad`、`duo_timeout`、`duo_disabled`、`duo_native_bad` - **120015**(SSO):`sso_user_mismatch`、`non_sso_user`、`service_account_sso_denied`、`federated` - **120016**(凭据):`password_secret_bad`、`platform_secret_bad`、`platform_secret_disabled`、`platform_secret_proxy`、`code_bad`、`code_timeout`、`code_disabled` ### 审计事件 | 规则 ID | 级别 | 触发条件 | 描述 | |---|---|---|---| | 120020 | 10 | `op_action ∈ 高风险集合` | 高风险管理操作(禁用 MFA/SSO/Duo、防火墙更改、撤销 token、批量设备解除授权、删除、清除) | | 120021 | 10 | `op_object_type ∈ {sa, satoken}` + 特定操作 | 服务账户或服务账户 token 已更改 | | 120022 | 9 | `op_object_type = sso` + SSO 配置操作 | SSO 配置已更改 | | 120023 | 9 | `op_object_type ∈ {user, account}` + 安全操作 | 用户安全设置或生命周期已更改 | | 120024 | 8 | `op_object_type ∈ {group, gm, gva, uva}` + 访问操作 | 组或保险库访问权限已更改 | | 120025 | 9 | `op_object_type ∈ 保险库/条目类型` + `op_action ∈ {delete, purge, export, share, delshare, sendpkg}` | 敏感保险库或条目操作 | | 120026 | 8 | `op_object_type = invite` + 配置操作 | 邀请或配置活动 | | 120027 | 9 | `op_object_type = report` + `op_action ∈ {view, export}` | 报告已查看或导出 | | 120028 | 10 | `op_action = unknown` | 未知审计操作 | | 120029 | 10 | `op_object_type ∈ {satoken, ssotkn, device, ec, cred, vault}` + 非常规操作 | 敏感对象操作(token、设备、凭据、保险库密钥、电子邮件更改) | | 120030 | 3 | `op_action ∈ {ssotknv, ssotknr}` 作用于 `ssotkn` | SSO token 已验证或轮换(常规) | | 120031 | 3 | `op_action = dlgsess` 作用于 `dlgdsess` | 会话已委派(常规 SSO 事件) | | 120032 | 5 | `op_object_type ∈ 保险库/条目类型` + `op_action = patch` | 保险库条目已修改 | | 120033 | 9 | `op_action ∈ {vrfydmn, uvrfydmn, dvrfydmn}` | 已验证域名的添加、更新或移除 | | 120034 | 6 | `op_action ∈ {trvlaway, trvlback}` | 旅行模式已启用或禁用 | **规则 120020(高风险)匹配的操作:** `disblmfa`、`disblduo`、`disblsso`、`updatfw`、`trevoke`、`delete`、`purge`、`dealldev` **规则 120023(用户/账户安全)匹配的操作:** `enblmfa`、`disblmfa`、`updatmfa`、`enblduo`、`disblduo`、`updatduo`、`changemp`、`changesk`、`changeks`、`beginr`、`completr`、`cancelr`、`activate`、`reauth`、`suspend`、`delete`、`reactive` ### 条目使用事件 | 规则 ID | 级别 | 触发条件 | 描述 | |---|---|---|---| | 120040 | 5 | `op_action = fill` | 条目用于自动填充 | | 120041 | 7 | `op_action ∈ {reveal, secure-copy}` | 密钥已查看或安全复制 | | 120042 | 9 | `op_action = export` | 条目已导出 | | 120043 | 8 | `op_action = share` | 条目已外部共享 | | 120044 | 4 | `op_action ∈ {server-create, server-fetch, server-update, enter-item-edit-mode, select-sso-provider, other}` | 常规条目使用活动 | ### 关联和频率规则 | 规则 ID | 级别 | 条件 | 描述 | |---|---|---|---| | 120060 | 10 | 规则 120011 在 5 分钟内触发 ≥5 次,同一个 `target_user.email` | 同一用户的多次登录失败 — 疑似暴力破解 | | 120061 | 10 | 规则 120011 在 5 分钟内触发 ≥10 次,同一个 `client.ip_address` | 同一 IP 的多次登录失败 — 疑似暴力破解 | | 120062 | 10 | 规则 120041 在 10 分钟内触发 ≥5 次,同一个 `user.email` | 同一用户多次查看或复制密钥 | | 120063 | 11 | 规则 120042 在 10 分钟内触发 ≥3 次,同一个 `user.email` | 同一用户多次导出条目 | | 120064 | 11 | 规则 120020 在 10 分钟内触发 ≥3 次 | 短时间内的多次高风险管理操作 | ## 日志和状态文件位置 | 路径 | 描述 | |---|---| | `/var/ossec/integrations/onepassword_events.py` | 轮询脚本 | | `/var/ossec/etc/onepassword-events.env` | 配置(包含 token — 请限制访问权限) | | `/var/ossec/logs/onepassword/onepassword-events.json` | 供 Wazuh 读取的实时 JSON 日志文件 | | `/var/ossec/queue/onepassword/onepassword-events-state.json` | 持久化的 API 游标(每个端点一个) | ## 故障排除 **没有事件出现** 1. 确认脚本能够正常运行并干净退出: sudo -u wazuh /var/ossec/integrations/onepassword_events.py echo $? # 应该为 0 2. 启用调试日志记录:在环境文件中添加 `ONEPASSWORD_DEBUG=yes` 并重新运行。 3. 检查输出文件是否正在写入: sudo wc -l /var/ossec/logs/onepassword/onepassword-events.json **HTTP 401 Unauthorized** - 验证 token 设置正确且尚未过期。 - 确保该 token 已被授予所需的功能范围(`auditevents`、`signinattempts`、`itemusages`)。 - 确认 `ONEPASSWORD_EVENTS_BASE_URL` 与您的租户区域匹配(`.eu` 与 `.com`)。 **事件出现在归档中但未出现在告警中** - 无论是否触发规则,Wazuh 都会归档所有已解码的事件。 - 如果事件进入了 `archives.json` 但未进入 `alerts.json`,说明解码器在工作,但没有规则匹配。请使用 `wazuh-logtest` 来准确追踪匹配了哪条规则(如果有的话)。 - 检查解码器和规则文件是否位于正确的目录中,以及 Wazuh manager 在部署后是否已重启。 **状态文件损坏 / 事件正在被重新获取** - 脚本会自动将损坏的状态文件移至一旁,并从回填窗口重新开始。 - 要有意重置某个端点的状态,请从状态文件中删除 `endpoints.` 键,或者直接删除该文件。 **存储在文件中的 Token(适用于 secrets 管理器)** 设置 `ONEPASSWORD_EVENTS_TOKEN_FILE=/run/secrets/op_token` 并确保文件可被 `wazuh` 用户读取。如果两者都设置了,`ONEPASSWORD_EVENTS_TOKEN` 优先。 ## 安全说明 - 环境文件包含 API bearer token。权限设置为 `640`(属主 `root`,属组 `wazuh`),因此只有 Wazuh 进程可以读取它。 - 脚本通过 wodle `command` 块以 `wazuh` 用户(而非 root)身份运行。 - 输出日志文件和状态文件目录使用 `750` 权限创建。 - API token 永远不会写入输出日志或状态文件中。 ## 许可证 MIT License — 详见 [LICENSE](LICENSE)。
标签:1Password, AMSI绕过, API集成, JSON解析, PB级数据处理, URL发现, Wazuh, 可观测性, 告警关联, 威胁检测, 安全事件, 安全检测, 安全运维, 审计日志, 密码管理器, 数字取证, 日志采集, 自动化脚本, 身份验证监控, 逆向工具