osmedeus 事件工作流实战:Event 触发器与事件生成系统完整指南 📅 发布时间:2026/9/17 13:34:03 👁 浏览次数: osmedeus 事件工作流实战Event 触发器与事件生成系统完整指南【免费下载链接】osmedeusA Modern Orchestration Engine for Security项目地址: https://gitcode.com/GitHub_Trending/os/osmedeusosmedeus 内置了一套完整的事件驱动Event-Driven工作流系统让安全扫描任务之间可以通过「事件」而非人工串联进行自动联动。本文以仓库中test/testdata/workflows/events/目录下的官方示例为主线系统讲解事件发射Emitter、事件接收Receiver与触发器Trigger的完整用法包括generate_event/generate_event_from_file两个事件函数、过滤与去重触发器配置以及背后的源码实现机制。读完本文你将能够在自己的 osmedeus 工作流中独立编写扫描 A 产出事件 → 自动触发扫描 B的自动化链路并掌握事件系统的可靠性设计服务端失败自动降级到数据库队列与 Webhook。事件系统概览Emitter 与 Receiver在 osmedeus 中事件系统由两类角色构成Emitter事件发射器工作流在执行过程中通过内置函数向事件系统发布事件。典型场景是子域名枚举完成、漏洞扫描发现高危项、爬虫抓取到新 URL 等。Receiver事件接收器通过triggers配置监听特定topic的工作流。当事件到达且匹配触发条件时osmedeus 的 Event Receiver 会自动拉起对应工作流执行。事件从产生到触发的完整链路如下工作流中的 function 步骤调用generate_event(...)或generate_event_from_file(...)事件经由SendEventWithFallback发送分布式模式下优先走 Redis Pub/Sub否则尝试发送到本地 Server发送失败时降级为数据库队列并同时推送到已配置的 WebhookEvent Receiver 收到事件后将其与已注册工作流的触发器进行 topic 匹配匹配成功后再执行过滤器filters与去重dedupe逻辑通过全部校验后对应工作流被自动触发执行。仓库目录test/testdata/workflows/events/下共提供了 5 个示例工作流覆盖事件系统的全部核心场景分类文件说明Emitterssimple-emitter.yaml基础事件发射演示generate_event与generate_event_from_fileEmittersvuln-emitter.yaml模拟漏洞扫描器发射结构化漏洞发现事件Receiverssimple-receiver.yaml基础事件触发监听 discovery 事件Receiversfiltered-receiver.yaml高级过滤包含严重级别校验与 Webhook 通知Receiversdedupe-receiver.yaml事件去重防止重复处理事件函数详解事件函数在internal/functions/event_functions.go中实现通过 goja JS 运行时暴露给工作流调用。generate_event(workspace, topic, source, data_type, data)发射单条事件可携带结构化数据。五个参数含义如下参数说明workspace事件所属工作空间通常传入{{TargetSpace}}模板变量topic事件主题如discovery.asset、scan.findingReceiver 据此匹配source事件来源标识如扫描器名称my-scannerdata_type数据类型如subdomain、vulnerabilitydata事件数据可以是字符串也可以是 JS 对象结构化 JSON- type: function function: | generate_event({{TargetSpace}}, discovery.asset, my-scanner, subdomain, api.example.com)从源码看internal/functions/event_functions.go该函数有几点重要行为必填校验workspace、topic、source、data_type四个字段缺一不可缺失时记录 Warn 日志并返回false上下文自动填充runIDRunID与workflowNameWorkflowName会从运行时上下文自动读取无需手动传入从工作流执行时sourceType标记为run通过osmedeus eval等独立场景执行为eval无 run 上下文时会生成 8 位短 UUID 作为 runID可靠性设计底层调用notify.SendEventWithFallback即使服务端暂不可用事件也会进入数据库队列等待后续处理因此函数最终仍然返回true。generate_event_from_file(workspace, topic, source, data_type, file_path)逐行读取文件并为每一行发射一条事件返回发射的事件条数。适合把枚举结果文件批量转成事件流。- type: function functions: - generate_event_from_file({{TargetSpace}}, discovery.asset, my-scanner, subdomain, {{Output}}/subdomains.txt)从源码看internal/functions/event_functions.go该函数会跳过空白行每行作为事件data发射一条文件不存在或读取失败时返回 0。返回值为成功发射的条数可配合set_var保存并在后续步骤中引用示例中即用get_var(count)打印发射数量。Emitter 工作流实战基础发射器simple-emitter.yamlsimple-emitter.yaml 演示了三种典型发射方式1. 单条事件发射——先用 bash 步骤构造资产文件再对单个目标发射一条事件- name: discover-assets type: bash command: | echo api.{{target}} {{Output}}/assets.txt echo www.{{target}} {{Output}}/assets.txt echo mail.{{target}} {{Output}}/assets.txt - name: emit-single-event type: function functions: - generate_event({{TargetSpace}}, discovery.asset, simple-emitter, subdomain, new.{{target}})2. 批量事件发射——读取文件逐行发射并用返回值打印统计信息- name: emit-events-from-file type: function functions: - set_var(count, generate_event_from_file({{TargetSpace}}, discovery.asset, simple-emitter, subdomain, {{Output}}/assets.txt)) - print_green(Emitted get_var(count) events from file)3. 结构化事件发射——data 参数传入 JS 对象形成结构化 JSON 事件- name: emit-structured-event type: function function: | generate_event({{TargetSpace}}, discovery.complete, simple-emitter, summary, { target: {{target}}, asset_count: 3, status: completed })注意该示例中步骤间混合使用了functions列表与function单条两种写法均为合法语法。漏洞扫描模拟器vuln-emitter.yamlvuln-emitter.yaml 模拟了一个真实的漏洞扫描器发射scan.finding主题的结构化事件事件数据中携带url、severity、template_id、confirmed、matched_at、description等字段- name: emit-critical-finding type: function function: | generate_event({{TargetSpace}}, scan.finding, vuln-scanner, vulnerability, { url: https://{{target}}/admin, severity: critical, template_id: exposed-admin-panel, confirmed: true, matched_at: /admin, description: Admin panel exposed without authentication }) post_run: - print_red(CRITICAL: Exposed admin panel found)该示例同时演示了post_run钩子的用法事件发射后立即在发射端输出彩色告警。它分别发射 critical / high / low 三个级别的 finding并最终发射一条scan.complete汇总事件——这为下文filtered-receiver的仅对 high/critical 告警、对 completed 事件统计校验提供了绝佳的联调对象。Receiver 与 Trigger 配置Receiver 的核心是工作流顶层的triggers配置块。触发器结构定义在 internal/core/trigger.go事件配置EventConfig支持以下字段字段说明topic监听的事件主题如discovery.asset支持 glob 通配*、test*、*.new、assets.*.createdfiltersJS 表达式过滤器列表如event.data.severity high全部通过才触发filter_functions可调用内置工具函数的 JS 过滤器如contains(event.data.url, /api/)dedupe_key去重键模板如{{event.data.url}}可用{{event.source}}等组成复合键dedupe_window去重窗口时长如5s、1m、5m、1h窗口内重复事件被忽略基础事件触发triggers: - name: on-new-asset on: event event: topic: discovery.asset enabled: true监听discovery.asset主题的所有事件。topic 匹配逻辑见 internal/core/trigger.gotopic 为空则匹配一切事件含通配符时使用path.Match做 glob 匹配否则精确匹配。过滤事件触发triggers: - name: on-high-severity on: event event: topic: scan.finding filters: - event.data.severity high - event.data.confirmed true enabled: true过滤器是 JS 表达式可访问事件对象event含event.topic、event.source、event.data_type、event.data.*等。所有过滤器必须全部求值为真触发器才会命中。这使得只对确认过的高危漏洞告警这类精细控制成为可能。去重事件触发triggers: - name: on-url-dedupe on: event event: topic: crawler.url dedupe_key: {{event.data.url}} dedupe_window: 5m enabled: truededupe_key是一个模板字符串事件到达后会渲染该模板作为唯一键在dedupe_window窗口内如 5 分钟相同键的事件会被丢弃。从源码看internal/core/trigger.go去重生效的前提是dedupe_key非空且dedupe_window解析为大于 0 的时长time.ParseDuration解析支持5s、1m、1h等 Go 时长格式。Receiver 工作流实战基础接收器simple-receiver.yamlsimple-receiver.yaml 注册了两个触发器一个事件触发器on-new-asset监听discovery.asset主题并附加来源与类型过滤一个被禁用的手动触发器manual-triggerenabled: false演示了触发器可随时开关triggers: - name: on-new-asset on: event event: topic: discovery.asset filters: - event.source simple-emitter - event.data_type subdomain enabled: true - name: manual-trigger on: manual enabled: false触发后工作流将{{target}}写入{{Output}}/processed-assets.txt完成资产落地处理。过滤接收器filtered-receiver.yamlfiltered-receiver.yaml 是高级过滤的完整示例两个触发器分别处理漏洞告警与扫描汇总triggers: - name: on-high-severity-finding on: event event: topic: scan.finding filters: - event.data.severity high || event.data.severity critical - event.data.confirmed true enabled: true - name: on-scan-complete on: event event: topic: scan.complete filters: - event.data.finding_count 0 enabled: true注意过滤器支持||逻辑或与数值比较等完整 JS 语法。触发后该工作流会调用notify_webhook(High severity finding detected: {{target}})发送外部通知构成扫描发现高危 → 自动告警的闭环。与vuln-emitter.yaml联调时low 级别的 finding 会被第一个触发器正确过滤掉severity low不满足high || critical。去重接收器dedupe-receiver.yamldedupe-receiver.yaml 演示了两种去重键的写法单字段键与复合键triggers: - name: on-new-url-dedupe on: event event: topic: crawler.url filters: - event.data_type url dedupe_key: {{event.data.url}} dedupe_window: 5m enabled: true - name: on-asset-composite-dedupe on: event event: topic: discovery.asset dedupe_key: {{event.source}}-{{event.data.value}} dedupe_window: 1h enabled: trueon-asset-composite-dedupe用{{event.source}}-{{event.data.value}}组合成复合去重键实现同一来源 同一资产维度上的去重——即使不同来源发射了相同资产也不会被误判为重复。这在多个扫描器可能产出重叠结果的真实场景中非常实用。运行与联调命令行方式# 运行发射器生成事件 osmedeus run -m simple-emitter -t example.com # 运行接收器处理事件若已注册到调度器会自动被事件触发 osmedeus run -m simple-receiver -t example.com-m指定 module 名称-t指定目标。完整联调路径为先启动/注册接收器工作流事件接收器随调度器默认启用再运行发射器观察接收器是否被自动拉起。官方事件接收器文档 docs/api/event-receiver.mdx 指出事件接收相关端点仅在事件接收器启用时可用默认随 scheduler 启用。API 方式除工作流内部发射外事件系统还暴露了 HTTP API实现见 pkg/server/handlers/event_receiver.go可用于外部系统注入事件查询事件接收器状态curl http://localhost:8002/osm/api/event-receiver/status \ -H Authorization: Bearer $TOKEN列出已注册的事件触发工作流curl http://localhost:8002/osm/api/event-receiver/workflows \ -H Authorization: Bearer $TOKEN通过 API 发射事件curl -X POST http://localhost:8002/osm/api/events/emit \ -H Authorization: Bearer $TOKEN \ -H Content-Type: application/json \ -d { topic: discovery.asset, source: external-scanner, data_type: subdomain, data: {value: api.example.com} }EmitEventRequest结构pkg/server/handlers/event_receiver.go支持topic必填、name、source、data、data_type字段事件source_type会被标记为api。这让 CI/CD、外部扫描器甚至定时任务都能无缝接入 osmedeus 的事件生态。源码级可靠性机制事件函数最终都汇入notify.SendEventWithFallbackinternal/notify/server_event.go其核心设计是多级降级事件不丢分布式模式Redis 已配置优先通过 Redis Pub/Sub 发布事件SendEventViaRedis成功后仍会同步发送结构化 WebhookRedis 失败则继续走 HTTP 链路本地 Server 直连通过ServerEventClient.SendEvent发送到本机 Server 的事件接收器数据库队列兜底服务端不可达时事件写入数据库队列等待后续补发Webhook 通知事件同时推送到配置的 Webhook 端点。这套链路解释了为何generate_event在服务端不可用时仍返回true——事件并未丢失而是进入了持久化队列。在单机部署下Emitter 与 Receiver 通过本地 Server 完成解耦在分布式部署下则通过 Redis 实现跨节点的事件广播是 osmedeus 多云/多节点扫描编排的基础设施。小结事件系统把 osmedeus 从手工串 workflow升级为事件驱动自动编排发射端用generate_event/generate_event_from_file把扫描中间产物子域名、URL、漏洞发现、扫描汇总转成结构化事件流接收端用triggersevent配置按 topic 订阅事件配合filters做精细筛选、dedupe_keydedupe_window防重复处理可靠性事件经 Redis / HTTP / 数据库队列 / Webhook 多级降级通道送达服务端短暂不可用不会造成事件丢失开放性除工作流内部发射外HTTP API/osm/api/events/emit允许任何外部系统注入事件。建议按test/testdata/workflows/events/目录的 5 个示例逐步实践先用simple-emittersimple-receiver打通链路再加入filtered-receiver的过滤逻辑与vuln-emitter联调最后用dedupe-receiver验证去重效果即可完整掌握 osmedeus 事件驱动编排的核心能力。【免费下载链接】osmedeusA Modern Orchestration Engine for Security项目地址: https://gitcode.com/GitHub_Trending/os/osmedeus创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考