限制 agent 检查

概述

您可以控制 Zabbix agent 或 agent 2 在执行监控项检查、远程命令或脚本时允许或禁止使用哪些监控项键值。

为此,请使用以下 agent 配置参数定义允许/拒绝规则:

  • AllowKey=<pattern>
  • DenyKey=<pattern>
  • AllowKeyRegexp=<pattern>
  • DenyKeyRegexp=<pattern>

<pattern> 必须包含单个监控项键值。
对于 AllowKey 和 DenyKey,<pattern> 支持通配符(*)。 通配符可匹配其所在位置的任意数量的任意字符,并可用于匹配监控项键值或参数(例如 vfs.file.*[*])。
对于 AllowKeyRegexp 和 DenyKeyRegexp,<pattern> 支持正则表达式。 正则表达式模式可用于匹配监控项键值及其参数字符串。 另请参阅正确的转义示例。
请注意,Zabbix agent 和 Zabbix agent 2 可能支持不同的正则表达式语法。

与其他 agent 配置参数不同,您可以指定任意数量的 AllowKey、DenyKey、AllowKeyRegexp 或 DenyKeyRegexp 参数。

重要说明

  • 使用 AllowKey 或 AllowKeyRegexp 仅允许所需的监控项,并将 DenyKey 或 DenyKeyRegexp 作为最后一条规则拒绝所有其他监控项。 这比仅依赖拒绝规则更安全,因为新版 Zabbix agent 可能会引入未被您的 DenyKey 或 DenyKeyRegexp 规则覆盖的监控项键。

  • 允许规则应尽可能具体:在 AllowKey 规则中使用确切的监控项键,而不是通配符 (*);在 AllowKeyRegexp 规则中使用最具体的正则表达式模式。

  • 如果使用 DenyKey 或 DenyKeyRegexp,应拒绝整个监控项键,而不是特定的文件或命令。 针对特定参数的规则可能被绕过;例如,路径遍历 (vfs.file.contents["../../../../etc/passwd"]) 可以读取某个文件,即使规则原本 intended to block 该文件的直接路径。 有关详细信息,请参阅保护允许/拒绝规则。

  • 默认情况下,所有 system.run 监控项都会被拒绝(即使 DenyKey 和 DenyKeyRegexp 为空),相当于将 DenyKey=system.run[*] 设置为最后一条规则。 因此,您可以允许特定的 system.run 监控项,而无需显式拒绝其他 system.run 监控项。 此隐式拒绝仅适用于 system.run;对于所有其他键,除非后面跟有拒绝规则,否则允许规则不会生效。

  • AllowKey、DenyKey、AllowKeyRegexp 和 DenyKeyRegexp 配置不会影响 agent 参数 HostnameItem、HostMetadataItem 或 HostInterfaceItem。

  • 被拒绝的监控项会变为不支持,但不会显示其被拒绝的任何提示;它们看起来与不存在的监控项键相同。例如:

    • Zabbix agent --print (-p) 命令行参数不会显示被拒绝的监控项键。
    • 对于被拒绝的监控项键,Zabbix agent --test (-t) 命令行参数将返回 Unsupported item key.。
    • 启用日志记录时 (LogRemoteCommands=1),Zabbix agent 日志文件不会记录被拒绝的远程命令。

Allow/deny 规则顺序

您可以指定无限数量的 AllowKey、DenyKey、AllowKeyRegexp 或 DenyKeyRegexp 规则,但它们的顺序很重要。

  • 规则会从上到下逐一评估。
  • 当某个监控项键匹配某条规则时,该监控项要么被允许,要么被拒绝,并且规则评估会停止。

例如,在评估 vfs.file.contents[/etc/passwd] 时,规则处理如下:

AllowKey=vfs.file.contents[/tmp/app.log]    # 监控项键模式不匹配,agent 继续处理下一条规则。
AllowKey=vfs.file.contents[/etc/passwd]     # 监控项键模式匹配;agent 允许该监控项检查并停止规则评估。
DenyKey=vfs.file.*[*]                       # agent 忽略该规则,因为评估已停止。

以下规则顺序将拒绝该监控项检查:

DenyKey=vfs.file.*[*]                       # 监控项键模式匹配;agent 拒绝该监控项检查并停止规则评估。
AllowKey=vfs.file.contents[/etc/passwd]     # agent 忽略该规则,因为评估已停止。
AllowKey=vfs.file.contents[/tmp/app.log]    # agent 忽略该规则,因为评估已停止。

示例

以下示例展示了 AllowKey、DenyKey、AllowKeyRegexp 和 DenyKeyRegexp 的常见配置模式。

允许特定的检查和命令

仅允许两个 vfs.file 监控项检查和两个 system.run 命令:

使用 AllowKey 和 DenyKey:

AllowKey=vfs.file.contents[/tmp/app.log]
AllowKey=vfs.file.size[/tmp/app.log]
AllowKey=system.run[/usr/bin/uptime]
AllowKey=system.run[/usr/bin/df -h /]
DenyKey=vfs.file.*[*]

使用 AllowKeyRegexp 和 DenyKeyRegexp:

AllowKeyRegexp=^vfs\.file\.(contents|size)\[/tmp/app\.log\]$
AllowKeyRegexp=^system\.run\[/usr/bin/(uptime|df -h /)\]$
DenyKeyRegexp=^vfs\.file\..*\[[\s\S]*\]$

无需设置 DenyKey=system.run[*],因为默认情况下会拒绝所有其他 system.run 命令(请参阅重要说明)。

允许执行脚本

允许 Zabbix agent 通过所有可用方法在主机上执行脚本:

  • 可在前端或通过 API 执行的全局脚本(此方法始终使用 system.run[myscript.sh] 键)
  • 来自动作操作的远程命令(此方法始终使用 system.run[myscript.sh,nowait] 键)
  • 带有脚本的 system.run Zabbix agent 监控项,例如:
    • system.run[myscript.sh]
    • system.run[myscript.sh,wait]
    • system.run[myscript.sh,nowait]
AllowKey=system.run[myscript.sh,*]

或

AllowKeyRegexp=(?s)^system\.run\[myscript\.sh,.*\]$

要控制 wait/nowait 参数,必须设置不同的规则。 例如,可以仅允许 system.run[myscript.sh,wait] 监控项,从而排除其他方法:

AllowKey=system.run[myscript.sh,wait]

或

AllowKeyRegexp=^system\.run\[myscript\.sh,wait\]$
保护允许/拒绝规则

以下示例展示了如何保护权限过于宽松的 AllowKey/AllowKeyRegexp 或 DenyKey/DenyKeyRegexp 规则。

请考虑以下规则:

使用 AllowKey 和 DenyKey:

AllowKey=system.run["C:\Program^ Files\Zabbix^ Agent^ 2\scripts\test.bat*"]
DenyKey=vfs.file.*
DenyKey=system.cpu.load[*]

使用 AllowKeyRegexp 和 DenyKeyRegexp:

AllowKeyRegexp=^system\.run\["C:\\Program\sFiles\\Zabbix\sAgent\s2\\scripts\\test\.bat.*"\]$
DenyKeyRegexp=^vfs\.file\..*$
DenyKeyRegexp=^system\.cpu\.load\[.*\]$

在 Windows 上,对于 AllowKey 或 DenyKey,必须使用插入符号(^)转义路径中的空格;对于 AllowKeyRegexp 或 DenyKeyRegexp,必须使用 \s 转义空格。

这些规则包含通配符(*),可能会被滥用:

  • test.bat 脚本可以使用任意参数执行,包括非预期参数。
  • vfs.file.* 模式匹配不带参数的监控项键;但是,所有 vfs.file 监控项都需要参数。
  • system.cpu.load[*] 模式仅匹配带参数的监控项键;但是,system.cpu.load 监控项不需要参数。

要保护这些规则,请明确仅允许使用特定参数执行 test.bat,并拒绝正确的监控项键模式;例如:

使用 AllowKey 和 DenyKey:

AllowKey=system.run["C:\Program^ Files\Zabbix^ Agent^ 2\scripts\test.bat status"]
AllowKey=system.run["C:\Program^ Files\Zabbix^ Agent^ 2\scripts\test.bat version"]
DenyKey=vfs.file.*[*]
DenyKey=system.cpu.load
DenyKey=system.cpu.load[*]

使用 AllowKeyRegexp 和 DenyKeyRegexp:

AllowKeyRegexp=^system\.run\["C:\\Program\sFiles\\Zabbix\sAgent\s2\\scripts\\test\.bat (status|version)"\]$
DenyKeyRegexp=^vfs\.file\..+\[[\s\S]*\]$
DenyKeyRegexp=^system\.cpu\.load(\[.*\])?$

您可以运行以下命令测试这些规则,这些命令将返回 ZBX_NOTSUPPORTED。

cd "C:\Program Files\Zabbix Agent 2"
zabbix_agent2.exe -t system.run["C:\Program^ Files\Zabbix^ Agent^ 2\scripts\test.bat debug"]
zabbix_agent2.exe -t vfs.file.size["C:\ProgramData\MyApp\config.ini"]
zabbix_agent2.exe -t vfs.file.contents["C:\Windows\System32\drivers\etc\hosts"]
zabbix_agent2.exe -t system.cpu.load
zabbix_agent2.exe -t system.cpu.load[all,avg1]
模式示例

以下表格展示了如何匹配监控项键模式:

  • 只有满足 Matches 列中的所有条件时,键才会匹配该模式。
  • 参数必须完全包含在方括号中(例如,vfs.file.contents[* 和 vfs.file.contents*utf8] 是无效模式)。
  • 这些示例仅用于说明模式匹配;实际监控项需要参数。

建议使用 AllowKey 或 AllowKeyRegexp,仅显式允许访问所需的文件和命令;使用 DenyKey 或 DenyKeyRegexp 拒绝整个监控项键(请参阅重要说明)。

使用基于通配符的规则:

模式 匹配条件 示例
* 带参数或不带参数的任意键
vfs.file.* 键以 vfs.file. 开头
不带参数
匹配:
vfs.file.size
vfs.file.contents

不匹配:
vfs.file.contents[]
vfs.file.size[/var/log/app.log]
vfs.*.contents 键以 vfs. 开头
键以 .contents 结尾
无参数
匹配:
vfs..contents
vfs.file.contents
vfs.mount.point.file.contents

不匹配:
vfs.contents
vfs.file.contents[]
vfs.file.*[*] 键以 vfs.file. 开头
任意参数或空参数
匹配
vfs.file.get.custom[]
vfs.file.size[/var/log/app.log, utf8]

不匹配:
vfs.file.get.custom
vfs.file.contents 键为 vfs.file.contents
无参数
匹配:
vfs.file.contents

不匹配:
vfs.file.contents[/etc/passwd]
vfs.file.contents[] 键为 vfs.file.contents[]
空参数
匹配:
vfs.file.contents[]

不匹配:
vfs.file.contents
vfs.file.contents[*] 键为 vfs.file.contents
任意参数或空参数
匹配:
vfs.file.contents[/path/to/file]

不匹配:
vfs.file.contents
vfs.file.contents[/etc/passwd,*] 键为 vfs.file.contents
第一个参数为 /etc/passwd
后续参数可以是任意参数、空参数或无参数
匹配:
vfs.file.contents[/etc/passwd,]
vfs.file.contents[/etc/passwd,utf8]
vfs.file.contents[/etc/passwd]

不匹配:
vfs.file.contents[]
vfs.file.contents[*passwd*] 键为 vfs.file.contents
恰好一个参数,且包含 passwd
匹配:
vfs.file.contents[/etc/passwd]
不匹配:
vfs.file.contents[/etc/passwd,]
vfs.file.contents[/etc/passwd,utf8]
vfs.file.contents[*passwd*,*] 键为 vfs.file.contents
第一个参数包含 passwd
第二个参数可以是任意参数或空参数
匹配:
vfs.file.contents[/etc/passwd,]
vfs.file.contents[/etc/passwd,utf8]
vfs.file.contents[/etc/passwd]

不匹配:
vfs.file.contents[/tmp/test]
vfs.file.contents[/etc/passwd,utf8] 键为 vfs.file.contents
第一个参数为 /etc/passwd
第二个参数为 utf8
匹配:
vfs.file.contents[/etc/passwd,utf8]

不匹配:
vfs.file.contents[/etc/passwd,]
vfs.file.contents[/etc/passwd,utf16]

使用基于正则表达式的规则:

模式 匹配条件 示例
^[\s\S]*$ 带参数或不带参数的任意键
^vfs\.file\.[^\[]*$ 键以 vfs.file. 开头
不带参数
匹配:
vfs.file.size
vfs.file.contents

不匹配:
vfs.file.contents[]
vfs.file.size[/var/log/app.log]
^vfs\..*\.contents$ 键以 vfs. 开头
键以 .contents 结尾
无参数
匹配:
vfs..contents
vfs.mount.point.file.contents

不匹配:
vfs.contents
vfs.file.contents[]
^vfs\.file\..*\[[\s\S]*\]$ 键以 vfs.file. 开头
任意参数或空参数
匹配
vfs.file.get.custom[]
vfs.file.size[/var/log/app.log, utf8]

不匹配:
vfs.file.get.custom
^vfs\.file\.contents$ 键为 vfs.file.contents
无参数
匹配:
vfs.file.contents

不匹配:
vfs.file.contents[/etc/passwd]
^vfs\.file\.contents\[\]$ 键为 vfs.file.contents[]
空参数
匹配:
vfs.file.contents[]

不匹配:
vfs.file.contents
^vfs\.file\.contents\[[\s\S]*\]$ 键为 vfs.file.contents
任意参数或空参数
匹配:
vfs.file.contents[/path/to/file]

不匹配:
vfs.file.contents
^vfs\.file\.contents\[/etc/passwd,[\s\S]*\]$ 键为 vfs.file.contents
第一个参数为 /etc/passwd
第二个参数可以是任意参数或空参数
匹配:
vfs.file.contents[/etc/passwd,]
vfs.file.contents[/etc/passwd,utf8]

不匹配:
vfs.file.contents[]
vfs.file.contents[/etc/passwd]
^vfs\.file\.contents\[[\s\S]*passwd[\s\S]*\]$ 键为 vfs.file.contents
参数可以是任意值,但至少有一个参数包含 passwd
匹配:
vfs.file.contents[/etc/passwd]
vfs.file.contents[/etc/passwd,]
vfs.file.contents[/etc/passwd,utf8]
^vfs\.file\.contents\[[^,]*passwd[^,]*,[\s\S]*\]$ 键为 vfs.file.contents
第一个参数包含 passwd
第二个参数可以是任意参数或空参数
匹配:
vfs.file.contents[/etc/passwd,]
vfs.file.contents[/etc/passwd,utf8]

不匹配:
vfs.file.contents[/etc/passwd]
vfs.file.contents[/tmp/test]
^vfs\.file\.contents\[/etc/passwd,(utf8|windows-1252)\]$ 键为 vfs.file.contents
第一个参数为 /etc/passwd
第二个参数为 utf8 或 windows-1252
匹配:
vfs.file.contents[/etc/passwd,utf8]
vfs.file.contents[/etc/passwd,windows-1252]

不匹配:
vfs.file.contents[/etc/passwd,]
vfs.file.contents[/etc/passwd,utf16]