Zabbix Security Advisories 模板实战:用 HTTP Agent 与 Jira API 自动采集 Zabbix 自身 CVE 安全通告
Zabbix Security Advisories 模板实战:用 HTTP Agent 与 Jira API 自动采集 Zabbix 自身 CVE 安全通告
导读
本文围绕 community-templates 仓库中的 Zabbix Security Advisories by HTTP Agent 模板 展开,讲解如何让 Zabbix 7.0+ 通过 HTTP Agent 从 Zabbix 官方 Jira 缺陷跟踪系统(support.zabbix.com 的 Jira REST API)抓取安全通告,并借助 LLD(低级别自动发现)将每条 CVE 拆解为独立的采集项。读完本文,你将掌握该模板的完整工作原理、LLD 宏与 JSONPath 映射关系、7 个依赖型采集项的预处理逻辑,以及如何在生产环境快速部署与扩展这套"监控系统自监控"的实战方案。
一、模板定位:让 Zabbix 监控自己的安全通告
该模板是一个精巧的"元监控"示例——Zabbix 用它来拉取并解析 Zabbix 官方自身发布的安全通告。通告数据源并非外部漏洞库,而是 Zabbix 官方的 Jira 缺陷跟踪系统:所有安全缺陷(issuetype 为 Defect (Security) 的 ZBX 项目问题)都会被自动同步进监控系统。
模板核心能力(依据 README):
- 通过 Jira API 抓取 Zabbix 安全通告;
- 使用 LLD 按每条 CVE 动态生成采集项;
- 覆盖工单创建时间、CVE Mitre ID、优先级、解决日期、更新日期、摘要、工单 URL 等关键字段。
从仓库目录结构看,模板针对 Zabbix 7.0+ 版本设计,位于 Applications/Security/template_zabbix_security_advisories/7.0/,由作者 Janne Pikkarainen 维护。
二、整体架构:HTTP Agent 主采集项 + LLD 依赖分解
从 模板定义文件 可以还原出清晰的二级数据流:
- Master item(主采集项):类型
HTTP_AGENT,直接请求 Jira Search API,拉取符合 JQL 条件的安全缺陷列表 JSON,并以TEXT类型原始存储,保留2d历史、不保留趋势(trends: '0')。 - Discovery rule(发现规则):类型
DEPENDENT,依赖主采集项,通过预处理JSONPATH提取$.issues数组作为 LLD 数据源。 - Item prototypes(采集项原型):7 个
DEPENDENT类型采集项,各自从主采集项 JSON 中按工单 key 定位并抽取字段,最终按每条 CVE 实体化。
链路示意:
support.zabbix.com Jira REST API
│ HTTP_AGENT (delay: 1d)
▼
zabbix-jira.securityissues.masteritem (TEXT, 原始 JSON)
│ DEPENDENT + JSONPATH $.issues
▼
Discovery rule: CVEs list (zabbix-jira.cves.masteritem)
│ 通过 LLD 宏 {#CVEID} 等定位每条记录
▼
7 个依赖型采集项原型(created / mitreid / priority / resolutiondate / summary / updated / url)
这种"一次 HTTP 拉取 + 本地依赖解析"的设计避免了为每个字段重复请求远端 API,是 Zabbix 中处理 JSON API 数据的高效范式。
三、快速部署:导入与挂载
该模板部署极其简单,README 明确指出无需任何额外配置:
- 下载模板文件 template_zabbix-jira-security-advisories.yaml;
- 在 Zabbix 前端通过「Data collection → Templates → Import」导入(Zabbix 7.0+ 原生支持 YAML 格式导入);
- 新建主机(可以是任意一台能访问外网的 Zabbix 托管主机),为其链接模板 "Zabbix CVEs";
- 等待一次采集周期(默认更新间隔
1d)后,LLD 会自动发现当前全部未解决/已记录的安全缺陷工单。
导入后模板归属的模板组为 CVEs,模板自身携带 Application: Zabbix CVEs、Application: CVEs、Component: Zabbix 等标签,便于在资产与问题视图中检索。关于模板导入的通用流程,可参考 仓库根 README 中关于下载、导入与挂载模板的说明。
四、LLD 宏与 JSONPath 映射详解
模板定义了 10 个 LLD 宏(README 标注为 11 个,实际 YAML 导出中 lld_macro_paths 定义了 10 条映射,其中 {#CVEURL} 在 README 表格中写作 $.self[],而 YAML 实际路径为 $.self,以 YAML 为准)。完整映射如下:
| LLD 宏 | JSONPath | 含义 |
|---|---|---|
| {#CVECREATED} | $.fields.created |
工单创建时间 |
| {#CVEDESCRIPTION} | $.fields.description |
工单描述(用于提取 CVE Mitre ID) |
| {#CVEID} | $.id |
Jira 工单内部数字 ID(用作采集项 key 后缀) |
| {#CVEPRIORITY} | $.fields.priority.name |
优先级名称 |
| {#CVERESOLUTIONDATE} | $.fields.resolutiondate |
解决日期 |
| {#CVESTATUS} | $.fields.status.name |
状态名称 |
| {#CVESUMMARY} | $.fields.summary |
工单标题/摘要 |
| {#CVETICKET} | $.key |
工单 Key(如 ZBX-XXXX) |
| {#CVEUPDATED} | $.fields.updated |
最后更新时间 |
| {#CVEURL} | $.self |
工单自身 API URL |
这些宏全部来自 Jira Search API v2 返回的 issues[] 数组元素,数组内每个对象即一条 CVE 记录。发现规则预处理使用 JSONPATH 提取 $.issues,再配合 lld_macro_paths 完成逐字段的宏绑定。因为模板完全使用官方公开 API 的字段结构,无需用户手工配置任何宏——这也是 README 强调"11 个 LLD macros,no need to configure them"的原因。
五、主采集项:Jira API 请求细节
主采集项 zabbix-jira.securityissues.masteritem 的关键配置(见 template_zabbix-jira-security-advisories.yaml):
| 配置项 | 值 | 说明 |
|---|---|---|
| type | HTTP_AGENT |
由 Zabbix server/proxy 直接发起 HTTP 请求 |
| key | zabbix-jira.securityissues.masteritem |
所有依赖项的共同数据源 |
| delay | 1d |
每天抓取一次,频率极低、对官方 API 友好 |
| history | 2d |
原始 JSON 保留 2 天 |
| value_type | TEXT |
存储完整 JSON 响应 |
| trends | 0 |
不保留趋势 |
| timeout | 60s |
请求超时上限 |
| url | https://support.zabbix.com/rest/api/2/search |
Jira Server REST API v2 的搜索端点 |
| query_fields | jql: project = ZBX AND issuetype = "Defect (Security)" ORDER BY updated DESC |
只查询 ZBX 项目中"安全缺陷"类型问题,按更新时间倒序 |
| headers | content-type: application/json、accept: application/json |
声明 JSON 请求/响应 |
JQL 是这套模板的"数据过滤器"核心:project = ZBX 限定项目,issuetype = "Defect (Security)" 精准圈定安全通告类问题,ORDER BY updated DESC 保证最新更新的通告排在最前,便于后续人工查看。
六、7 个采集项原型:依赖解析与预处理逻辑
发现规则 "CVEs list"(key zabbix-jira.cves.masteritem)下共定义 7 个采集项原型,全部为 DEPENDENT 类型、value_type: TEXT、不保留趋势,统一依赖主采集项 zabbix-jira.securityissues.masteritem。每个原型通过 JSONPATH 预处理 $[?(@.key=="{#CVEID}")].<字段路径> 实现"按工单 key 定位单条记录":
| 采集项(原型名称) | key | 预处理 JSONPath | 备注 |
|---|---|---|---|
| {#CVETICKET}: Created {#CVECREATED} | zabbix-jira.cves.created.[{#CVEID}] |
$[?(@.key=="{#CVEID}")].fields.created |
额外叠加 JAVASCRIPT 预处理格式化日期 |
| {#CVETICKET}: CVE Mitre ID … | zabbix-jira.cves.mitreid.[{#CVEID}] |
$[?(@.key=="{#CVEID}")].description |
名称/描述中用 regsub 提取 CVE 编号 |
| {#CVETICKET}: Priority {#CVEPRIORITY} | zabbix-jira.cves.priority.[{#CVEID}] |
$[?(@.key=="{#CVEID}")].fields.priority.name |
— |
| {#CVETICKET}: Resolution date {#CVERESOLUTIONDATE} | zabbix-jira.cves.resolutiondate.[{#CVEID}] |
$[?(@.key=="{#CVEID}")].fields.resolutiondate |
— |
| {#CVETICKET}: {#CVESUMMARY} | zabbix-jira.cves.summary.[{#CVEID}] |
$[?(@.key=="{#CVEID}")].fields.summary |
采集项名称直接使用宏动态生成 |
| {#CVETICKET}: Updated {#CVEUPDATED} | zabbix-jira.cves.updated.[{#CVEID}] |
$[?(@.key=="{#CVEID}")].fields.updated |
— |
| {#CVETICKET}: {#CVEURL} | zabbix-jira.cves.url.[{#CVEID}] |
$[?(@.key=="{#CVEID}")].self |
采集工单的 API 自引用 URL |
6.1 日期格式化:JAVASCRIPT 预处理
Created 采集项在 JSONPath 之后叠加了一段 JAVASCRIPT 预处理,将 Jira 返回的 ISO 时间字符串转换为 YYYY-MM-DD 的易读日期:
var dateObject = new Date(value);
var dateString = `${dateObject.getFullYear()}-${('00' + (dateObject.getMonth()+1)).slice(-2)}-${('00' + dateObject.getDate()).slice(-2)}`;
return (dateString)
该脚本利用模板字符串与补零技巧,把 new Date() 解析后的年月日拼成规范格式,属于 Zabbix 预处理阶段"格式化后再入库"的典型用法(updated 与 resolutiondate 字段仍保留原始 ISO 字符串,未做同样处理)。
6.2 CVE Mitre ID 提取:regsub 正则
mitreid 采集项的价值在于从自由文本描述中自动抽取标准 CVE 编号:
- 采集项名称:
{#CVETICKET}: CVE Mitre ID {{#CVEDESCRIPTION}.regsub("(CVE-[0-9]+-[0-9]+)", \1)}; - 采集项描述:
{#CVETICKET}: {{#CVEDESCRIPTION}.regsub("^(CVE.[0-9]+.[0-9]+)", \1)}。
名称与描述分别使用 Zabbix 宏函数 regsub 在 LLD 宏 {#CVEDESCRIPTION} 上做正则提取——名称中严格匹配 CVE-数字-数字 模式,描述中则用 ^ 锚定行首。这样每条 CVE 的 Mitre ID 会直接出现在最新数据与最新问题列表的名称里,便于快速检索。regsub 宏函数在其他模板(如 template_ceph_squid_by_prometheus 中对 {ITEM.NAME} 的用法)中也被广泛用于从动态名称提取关键片段。
6.3 标签(tags)体系
每个采集项原型都挂载了一组标签,典型如:
Created: {#CVECREATED}
Priority: {#CVEPRIORITY}
Status: {#CVESTATUS}
Ticket: {#CVETICKET}
Updated: {#CVEUPDATED}
部分原型(mitreid、summary、url)额外携带 CVE Mitre ID、Resolution date、URL 标签。这些标签让每条 CVE 的元数据成为可被 Zabbix 标签过滤体系(如问题视图、仪表盘过滤)利用的结构化信息。
七、触发器说明与告警扩展思路
按 README 的明确说明:该模板不包含任何触发器。也就是说,它默认只负责"采集与呈现"安全通告数据,不产生告警。
如果你希望在生产环境实现"新 CVE 通告出现即告警",可以从源码结构推断出几种自行扩展的方式:
- 基于
zabbix-jira.cves.created.[{#CVEID}]采集项,用last()与当前时间比较(nodata()之外),或利用{ITEM.VALUE}匹配最近一天创建的通告; - 基于
{#CVESTATUS}/{#CVEPRIORITY}标签做过滤,仅对高优先级未解决通告触发; - 利用采集项携带的
{#CVETICKET}、{#CVEURL}在触发器消息中拼接工单链接与描述,实现"通告到达即通知"的安全运营闭环。
八、自带仪表盘:按优先级与工单分组浏览
模板还附带一个名为 "Zabbix CVEs" 的仪表盘(见 YAML 中的 dashboards 段),采用 itemnavigator(最新数据导航)组件,按 Priority(优先级)与 Ticket(工单)两个标签维度分组展示。导入模板并挂载到主机后,即可在仪表盘直接按优先级查看全部已发现的 CVE 通告条目,无需自建图表。
九、适用前提与注意事项
- 版本要求:模板声明适用于 Zabbix 7.0+(YAML 导出头
version: '7.0'),低版本需使用对应格式的模板; - 网络可达性:主采集项需要能访问
support.zabbix.com的 Jira REST API,请确保 Zabbix server/proxy 的外网出口策略允许; - 采集频率:默认
1d一次、60s超时,对官方 API 负担极小;如需更实时地感知通告,可适当缩短 delay,但请自行评估对官方接口的访问频度; - 原始数据保留:主采集项历史仅保留
2d,若需要更长时间回溯原始 JSON,可调大 history; - 数据字段依赖:所有 LLD 宏与采集项均绑定 Jira API 返回结构,若官方接口字段发生变化,需要同步调整
lld_macro_paths与预处理路径; - 只读监控:模板只做拉取与解析,不向 Jira 写入任何数据,安全风险极低。
十、总结
Zabbix Security Advisories 模板以"HTTP Agent 主采集项 + LLD 依赖分解 + JSONPath/regsub/JavaScript 预处理"的组合,仅用约 287 行 YAML 就实现了一个完整、自洽的 CVE 通告监控系统:每天一次拉取官方 Jira 安全缺陷列表,自动发现每条通告,并将其创建时间、Mitre ID、优先级、解决日期、摘要、更新时间和工单链接拆分为独立采集项,同时以标签与仪表盘完成可视化。它既是开箱即用的安全通告监控方案,也是学习 Zabbix 7.0 HTTP Agent 与 LLD JSON 解析的最佳参考实现。