“实际上,agent端指标的白名单和黑名单也是Zabbix培训中的一个重要主题。”
——Kaspars Mednis , 全球培训师负责人,Zabbix SIA
本文整理自Kaspars 在2020Zabbix中国峰会的演讲,ppt获取链接见文末。更多演讲视频可关注官方Bilibili账号主页(ID:Zabbix中国)。
目录
一 为什么需要agent端指标的白名单和黑名单
二 如何保障安全性
三 关于通配符
四 关于功能注释
五 哪个更安全?白名单还是黑名单?
为什么需要agent端指标的白名单和黑名单
首先,第一个问题是为什么?我们为什么需要agent端指标的白名单和黑名单?
实际上,我们都知道,Zabbix agent主要的功能就是采集监控,但也可以从配置文件、日志文件、密码文件或任何其他敏感数据源收集到一些敏感信息。正如大家现在所看到的一个简单示例,通过Zabbix get功能,我们可以对密码文件的内容实现读取。我想现在大家心中都会认为这也太不安全了,对吧?这属于敏感信息。
除此之外,另一个问题是system run[*]命令,system run[*]命令是非常有用、非常强大的命令,它实际上允许你直接在被监视的主机上从Zabbix前端执行任何命令,这也意味着你可以收集很多有用的信息,但这里的关键词是“任何命令”。实际上,有些人可能会使用这些命令执行一些有害代码。正如大家现在所看到的,在第一个示例中,用户将尝试从Web下载一些恶意代码,然后将尝试执行,以期获得根权限或其他权限。或者,在另外一个示例中,用户想要删除一些活动痕迹,试图删除一些日志文件。这些只是几个例子,都可以从前端执行。
我是从命令行使用Zabbix get,因为这样可以更容易的测试。但需要指出的是,如果从前端执行也可以实现同样的效果。当然,通常Zabbix agent是以非特权帐户运行的,这就意味着并不是所有这些命令都会成功。但是如果在windows上运行Zabbix,那么Zabbix的运行位置是windows的本地系统。实际上,在这里,几乎可以运行所有的命令。
如何保障安全性
这就引出了下一个问题,我们如何防止这种情况发生?
1. Enable Remote Commands参数
在Zabbix5.0发布之前,我们在Zabbix agent配置文件中设置了一个选项,称为Enable Remote Commands。如果您将此参数设置为零,则远程命令就会被禁用。因此,有两个选择,要么启用远程命令,要么完全禁用它们。但是,我们并不能完全阻止任何其他项的Key,这些也有潜在的危险,比如文件内容或其他一些Key。
2. 参数“Allow key”和“Deny key”
而Zabbix 5.0的发布,则给了我们更多的选择,我们在Zabbix5中添加了两个新的agent参数“Allow key”和“Deny key”。通过这些agent参数,您可以指定模式,而这些模式实际上是一个通配符表达式。这个模式指定可以在Key名称和参数中。通过使用“Allow key”和“Deny key”,借助通配符,实际上可以创建白名单或黑名单。并且Zabbix agent能够支持无限数量的这样的规则。
注:在这里规则是按照指定的顺序自上而下的执行。一旦监控项的Key与任何Allow或Deny规则匹配,则该项将被允许或拒绝。在此之后,规则检查将停止。
因此,如果您对监控项的Key有两个规则(如一个允许规则和一个拒绝规则),则先出现的规则将生效。另一个将会被忽略。通过这张PPT,我们可以清楚地看到其工作流程。
假设你为某个Deny key定义了一些拒绝规则,而Zabbix只是检查所有规则。所以第一个Allow key与您的模式不匹配,所以Zabbix将转到下一个。
接下来是将会匹配的Deny key。这意味着您的关键字被拒绝,处理停止,反之亦然。如果您设置有Allow key,第一个规则不匹配,但是下一个规则匹配这个Allow key,那么这个项关键字就会被允许。即使下面有一些拒绝规则,这些规则也会被忽略。因此,在创建顺序时一定要非常小心。
例如,假设我们有一个监控项Key,试图执行一个命令[cat /proc/stat],这实际上是一个安全命令,只是从系统中收集一些统计数据,并且你允许它执行。所以你已经定义了,比方说,你定义了三个规则,一个允许规则system run[free] 一个允许规则system run[cat /proc/stat], 以及拒绝规则system run[*],将如何处理?
首先,Zabbix将检查第一个模式,很明显,[cat /proc/stat]不会匹配[free]。如果模式不匹配,则Zabbix将检查第二个模式,该参数实际上是匹配的,Key将被允许。
是的,该Deny Key将被完全忽略。但是作为示例,如果你有任何其他命令,在Allow key中没有指定。那么这些命令将被拒绝。是的,正如我说的那样,这是由于顺序问题产生的一个典型错误。在绿色框中您可以看到正确的顺序,您已经允许了一些操作,可能是使用/var/log/myapp/*或/var/log/mydb/*文件指定了一些通配符,这是可以的。
而在底部,您已经拒绝了对任何其他文件的任何其他操作,是的,所以这意味着agent只能访问位于/var/log/myapp/或/var/log/mydb/中的文件。而底部您可以看到错误的顺序,因此您正在尝试允许一些运行命令,如ipcs -l或free。但是在一开始,您有一个拒绝Deny Key system run[*]运行,通配符被拒绝,实际上这会拒绝任何system run[*]命令,您所有的Allow key规则都不会有任何效果。所以一定要记住,它们从上到下处理和执行的。
关于通配符
让我们来讨论一下通配符,我将向大家介绍一些一般通配符规则,Zabbix使用的是通配符,它能够匹配特定位置上的任意数量的字符,既可以在关键字名称中使用,也可以在参数中使用。稍后我会提到这个。
首先,如果参数在ALLOW KEY或DENY KEY中指定,则必须用方括号括起来。如system.run[*只带左方括号,或vfs.file*.txt]只带右括号,这都是不完整的,都会被认为是错误的句法规则。如果您的Zabbix agent有这样的参数,它就会崩溃,也不会启动。像vfs.file后跟圆点,后跟任意选项,后跟任意参数是正确的句法规则。
模式示例,这里要特别注意,尽管很简单,因为这些只是通配符,但它们确实有点棘手,因为所有vfs.file通配符和参数中的通配符将匹配以vfs.file开头的任何Key和任何参数。大家可以看到,它们将匹配vfs.file.contents[/etc/passwd],但它不会匹配vfs.file.contents。大家可能觉得这没必要大惊小怪,因为没有任何参数的vfs.file内容Key是没用的,是这样吗?但是看看最后一个,看看system.*,它将匹配任何不带参数的system开头的key。因此它将匹配system.cpu.load,因此使用这种语法,您可以允许或拒绝system.cpu.load,但它不会与system.run.[*]命令匹配
system.run[*]命令需要使用语法system.*[*],只有这样system.run[*]命令才会被拒绝。
因此,我强烈建议,当您在创建这样的规则时,查看文档和监控项Key,它们可能有参数,也可能没有参数,创建您的规则,最好进行一定的测试。否则,您可能会得到一些不愿看到的结果,比如您会认为system.通配符是安全的,但实际上这与任何system.run[*]的通配符都不匹配。
下面是一个小示例,您正在拒绝vfs.file.*,如果您试图获取vfs.file内容,就不会起作用。但是,如果您指定一些内容,如您所见,您将获得这些内容。所以这个例子实际上是一个很糟糕的例子。是的,这是配置错误。你认为你拒绝了vfs.file.*监控项Key,但实际上您只是拒绝了没有参数的vfs.file监控项Key,这是无用的。要使其按预期工作,您需要指定方括号和另一个通配符作为参数,只有这样,这些内容才不会被其他人查看。
再举一个例子,比方说你在拒绝system.cpu.load[*],比方说你的组织系统的system.cpu.load是秘密。并且您已经拒绝了system.cpu.load,并且您已经测试了system.cpu.load,平均数据不会被报告。但是如果有人在没有任何参数的情况下执行命令,这实际上是允许的。那么这个人就会拿到结果。是的,因此在此场景中,您还需要阻止带参数和不带参数的命令,您需要指定两行。其中,一行就是上面所说的,另一行是system.cpu.load。否则将授予访问权限。
关于功能注释
我来向大家介绍一些关于这个功能注释的内容。
首先,关于配置,您可能知道,对于自动注册,我们拥有特定的参数,如主机名项、主机元数据项或主机接口项,您还可以在其中指定项关键字。因此,那些Allow或Deny key不会影响这些参数。您可以拒绝某些系统运行命令,但您仍然可以在主机名项中使用它,它依旧可以起作用。接下来,如果客户端配置中不允许使用特定的监控项关键字,则会发生以下情况。
首先,该项将被报告为不受支持的,因此Zabbix不会告诉您该项被拒绝,而只是像任何其他不受支持的监控项一样不受支持。这样就不会给攻击者任何线索。是的,也许有人会攻击你的系统,但他到头来依旧会毫无头绪。它被拒绝了或者只是文件不见了什么的。客户端日志中不会锁定任何内容。是的,所以被拒绝的命令只是静默地删除,没有任何日志条目。即使您将日志级别提高到级别5,我们也可以说仍然没有条目。
正如大家所看到的这样,Zabbix agent支持包含文件。是的,您可以包含在include参数中指定的多个配置文件,不过要非常小心。因为不应该假定包含文件的特定顺序,这意味着包含文件只是以随机顺序包含。
如果您有Allow key或Deny key列表,那么重要的一件事就是记住它们的顺序。如果您不知道包含规则的包含文件的顺序,那么您实际上就无法控制这些规则的执行。所以记住顺序十分重要。
命令行实用程序,所以您当然可以尝试项关键字,也可以从命令行尝试,但是如果它们被拒绝,您实际上都会得到相同的结果。Zabbix agent将只报告不支持的关键字,Zabbix get将显示不支持的未知指标。
如果您尝试使用Zabbix agent打印所有命令,使用-p选项打印(-print (-p)),但是,它也不会显示这些命令,因此它们完全隐藏起来,就像从未存在过一样。
“哪个更安全?白名单还是黑名单?”
最后,我需要向大家提问以下问题,那就是“哪个更安全?白名单还是黑名单?”
假设您有Deny Key,它拒绝了vsf.file.contents[/etc/passwd],您看不到通配符,在这里,所有内容都是以纯文本指定,只需阻止对/etc/passwd 的访问,您就可以从前端从Zabbix get测试此项关键字。是的,大家可以看到,它确实被屏蔽了。所以没有办法获取/etc/passwd ,但真的完全没有办法获取到/etc/passwd 吗?如果您足够聪明,你可以写这个。假设使用Unix 路径并在目录中来回移动,您可以指定这实际上是某个文件,这是/tmp,然后返回,然后转到/etc/zabbix,然后返回,然后转到passwd,然后您将获得文件内容。
因此,这意味着即使您指定了一些拒绝规则,它们也可能不会被破坏,但是可能有一些解决方法可以绕过它们。因此,在这种情况下,白名单会更安全。是的,你可以阻止任何文件内容,只允许几个文件的内容,这当然会更安全。不过我个人不知道如何绕过这个问题,但对于大家而言,任何皆有可能,不是吗?
最后感谢大家的参与和倾听。这是一个简短的关于Zabbix5.0的白名单黑名单的演示。谢谢大家!