安全模型
注意在我们深入下面的技术细节之前,我们想强调,Prometheus 作为监控系统,收集并提供其监控系统的信息。因此,Prometheus 组件提供的 HTTP 端点不应暴露给公共可访问网络,例如互联网(除非您清楚自己在做什么并已采取适当措施)。这包括(但不限于)已埋点二进制文件的/metrics端点、服务器组件的各种 API 端点以及用 Go 实现的服务器组件的/pprof端点。此外,通过向这些端点发送请求,很容易使服务器过载并最终导致拒绝服务(DoS)。
Prometheus 是一个复杂的系统,包含许多组件并与许多其他系统集成。它可以在各种受信任和不受信任的环境中部署。
本页描述了 Prometheus 的一般安全假设以及某些配置可能启用的攻击向量。
与任何复杂系统一样,几乎可以肯定会发现错误,其中一些与安全相关。
对于已经公开披露(例如通过公共 CVE)且需要不仅仅是依赖版本升级才能修复的 安全漏洞,请提交一份 漏洞报告 ,包含所有相关细节,除非已经提交。
如果您发现尚未公开披露的 安全漏洞,请私下报告给相关仓库 MAINTAINERS 中列出的维护者,并抄送 [email protected] 。我们将尽快修复该问题并与您协调发布日期。您可以选择是否希望公开感谢您的努力,以及是否希望提及您的姓名。
大多数依赖版本更新都是自动处理的。但是,如果 安全漏洞 修复仅需要更新依赖版本,而我们的自动化系统遗漏了,请随时直接提交更新。
自动化安全扫描器
致安全扫描器用户:请注意您生成的报告。大多数扫描器都是通用的,会产生大量误报。我们收到的报告越来越多,处理所有这些报告并进行您期望的仔细回复需要大量工作。这个问题在 Go 和 NPM 依赖扫描器方面尤为严重。
为了节省我们宝贵的时间,请不要提交未经处理的原始报告。相反,请附带一份分析,说明哪些特定结果适用于我们以及原因。
此外,请注意,作为开源项目,我们通常无法访问商业扫描工具,并且发现其输出往往具有误导性或完全错误。对于 Go 代码,如果您的报告无法通过对您认为受影响版本的 源代码 运行开源工具 govulncheck (而非二进制文件,因为二进制文件无法进行完整分析)进行重现,那么我们请求您再三核实您的发现(包括该代码是否确实可从 Prometheus 代码库中访问)。
Prometheus 由志愿者维护,而非公司。因此,安全问题的修复是尽力而为。我们力求在 7 天内为 Prometheus、Alertmanager、Node Exporter、Blackbox Exporter 和 Pushgateway 发布安全补丁。
Prometheus
据推测,不受信任的用户可以访问 Prometheus HTTP 端点和日志。他们可以访问数据库中包含的所有时间序列信息,以及各种操作/调试信息。
另据推测,只有受信任的用户才能更改 Prometheus 和其他组件的命令行、配置文件、规则文件以及运行时环境的其他方面。
Prometheus 抓取哪些目标、抓取频率以及其他设置完全通过配置文件确定。管理员可能会决定使用来自服务发现系统的信息,这与重新标记结合起来,可能会将部分控制权授予任何能够修改该服务发现系统中数据的人。
抓取的目标可能由不受信任的用户运行。默认情况下,目标不应能够暴露冒充其他目标的数据。honor_labels 选项会移除此保护,某些重新标记设置也可能如此。
从 Prometheus 2.0 开始,--web.enable-admin-api 标志控制对管理 HTTP API 的访问,该 API 包括删除时间序列等功能。此功能默认禁用。如果启用,管理和变更功能将可通过 /api/*/admin/ 路径访问。--web.enable-lifecycle 标志控制 Prometheus 的 HTTP 重新加载和关机。此功能也默认禁用。如果启用,它们将可通过 /-/reload 和 /-/quit 路径访问。
在 Prometheus 1.x 中,任何可以访问 HTTP API 的用户都可以访问 /-/reload 和对 /api/v1/series 使用 DELETE 操作。/-/quit 端点默认禁用,但可以通过 -web.enable-remote-shutdown 标志启用。
远程读取功能允许任何具有 HTTP 访问权限的用户向远程读取端点发送查询。例如,如果 PromQL 查询最终直接针对关系数据库运行,那么任何能够向 Prometheus 发送查询(例如通过 Grafana)的人都可以在该数据库上运行任意 SQL。
Alertmanager
任何可以访问 Alertmanager HTTP 端点的用户都可以访问其数据。他们可以创建和解决告警。他们可以创建、修改和删除静默。
通知发送到何处由配置文件决定。在某些模板设置中,通知可能会发送到告警定义的目的地。例如,如果通知使用告警标签作为目标电子邮件地址,则任何可以向 Alertmanager 发送告警的人都可以向任何电子邮件地址发送通知。如果告警定义的目标是可模板化的秘密字段,则任何可以访问 Prometheus 或 Alertmanager 的人都可以查看这些秘密。
任何可模板化的秘密字段都旨在用于上述用例中的通知路由。它们并非旨在作为通过模板文件功能将秘密与配置文件分离的方法。存储在模板文件中的任何秘密都可能被能够配置 Alertmanager 配置文件中接收器的人窃取。例如,在大型设置中,每个团队可能拥有一个完全由他们控制的 Alertmanager 配置文件片段,然后这些片段会合并到最终的完整配置文件中。
Pushgateway
任何可以访问 Pushgateway HTTP 端点的用户都可以创建、修改和删除其中包含的指标。由于 Pushgateway 通常在启用 honor_labels 的情况下被抓取,这意味着任何可以访问 Pushgateway 的人都可以创建 Prometheus 中的任何时间序列。
--web.enable-admin-api 标志控制对管理 HTTP API 的访问,该 API 包括清除所有现有指标组等功能。此功能默认禁用。如果启用,管理功能将可通过 /api/*/admin/ 路径访问。
导出器
导出器通常只与一个配置实例进行通信,使用预设的命令/请求集,这些命令/请求不能通过其 HTTP 端点进行扩展。
还有一些导出器,例如 SNMP 和 Blackbox 导出器,它们从 URL 参数获取目标。因此,任何可以访问这些导出器 HTTP 端点的人都可以使它们向任意端点发送请求。由于它们还支持客户端认证,这可能导致 HTTP 基本认证密码或 SNMP 团体字符串等秘密泄露。TLS 等挑战-响应认证机制不受此影响。
客户端库
客户端库旨在包含在用户的应用程序中。
如果使用客户端库提供的 HTTP 处理程序,恶意请求到达该处理程序时,不应导致超出额外负载和抓取失败所带来的问题。
认证、授权和加密
Prometheus 和大多数导出器都支持 TLS,包括通过 TLS 客户端证书进行客户端认证。有关配置 Prometheus 的详细信息请参见 此处。
Go 项目共享相同的 TLS 库,该库基于 Go 的 crypto/tls 库。我们默认将 TLS 1.2 作为最低版本。我们对此的政策基于 Qualys SSL Labs 的建议,我们努力在默认配置和正确提供的证书下达到 'A' 级,同时尽可能地遵守上游 Go 的默认设置。达到该等级在完美安全性和可用性之间取得了平衡。
未来,TLS 将添加到 Java 导出器中。
如果您有特殊的 TLS 需求,例如不同的密码套件或较旧的 TLS 版本,您可以调整最低 TLS 版本和密码,只要该密码在 crypto/tls 库中未标记为不安全 。如果这仍然不符合您的要求,当前的 TLS 设置允许您在服务器和具有更多特殊要求的反向代理之间构建一个安全的隧道。
也支持 HTTP 基本认证。基本认证可以在没有 TLS 的情况下使用,但那样会在网络上以明文形式暴露用户名和密码。
在服务器端,基本认证密码使用 bcrypt 算法以哈希形式存储。您有责任选择符合您安全标准的轮数。更多的轮数会使暴力破解变得更加复杂,但代价是消耗更多的 CPU 资源和更长的请求认证时间。
各种 Prometheus 组件都支持客户端认证和加密。如果提供 TLS 客户端支持,通常还有一个名为 insecure_skip_verify 的选项,用于跳过 SSL 验证。
API 安全
由于管理和变更端点旨在通过 cURL 等简单工具访问,因此没有内置的 CSRF 保护,因为这会破坏此类用例。因此,在使用反向代理时,您可能希望阻止此类路径以防止 CSRF。
对于非变更端点,您可能希望在反向代理中设置 CORS 头 ,例如 Access-Control-Allow-Origin,以防止 XSS 。
如果您正在编写包含来自不受信任用户(例如控制台模板的 URL 参数或您自己构建的内容)输入的 PromQL 查询,而这些用户不应该能够运行任意 PromQL 查询,请确保对任何不受信任的输入进行适当转义,以防止注入攻击。例如,如果 <user_input> 是 "} or some_metric{zzz=",则 up{job="<user_input>"} 将变为 up{job=""} or some_metric{zzz=""}。
对于使用 Grafana 的用户,请注意 仪表盘权限并非数据源权限 ,因此不会限制用户在代理模式下运行任意查询的能力。
秘密
非秘密信息或字段可能通过 HTTP API 和/或日志可用。
在 Prometheus 中,从服务发现检索到的元数据不被视为秘密。在整个 Prometheus 系统中,指标不被视为秘密。
配置文件中包含秘密的字段(在文档中明确标记为秘密)不会在日志或通过 HTTP API 暴露。不应将秘密放置在其他配置字段中,因为组件通过其 HTTP 端点暴露其配置是很常见的。用户有责任保护磁盘上的文件免受未经授权的读取和写入。
依赖项使用的其他来源的秘密(例如,EC2 服务发现使用的 AWS_SECRET_KEY 环境变量)可能会因我们无法控制的代码或因恰好暴露存储位置的功能而泄露。
拒绝服务
对于过载或昂贵查询,我们已经采取了一些缓解措施。然而,如果提供了过多或过于昂贵的查询/指标,组件仍然会崩溃。组件更有可能被受信任的用户意外关闭,而不是恶意行为。
用户有责任确保为组件提供足够的资源,包括 CPU、RAM、磁盘空间、IOPS、文件描述符和带宽。
建议监控所有组件是否出现故障,并在故障时自动重启它们。
库
本文档考虑的是从标准源代码构建的普通二进制文件。如果您修改 Prometheus 源代码,或在您自己的代码中使用 Prometheus 内部机制(超出官方客户端库 API),则此处提供的信息不适用。
构建过程
Prometheus 的构建管道在第三方提供商上运行,Prometheus 开发团队的许多成员以及这些提供商的员工都可以访问。如果您担心二进制文件的确切来源,建议您自行构建,而不是依赖项目提供的预构建二进制文件。
Prometheus 社区
在 Prometheus 社区 组织下的仓库由第三方维护者支持。
如果您在 Prometheus 社区 组织中发现 安全漏洞,请私下报告给相关仓库 MAINTAINERS 中列出的维护者,并抄送 [email protected] 。
该组织下的某些仓库可能具有与本文档中介绍的不同安全模型。在这种情况下,请参阅这些仓库的文档。
外部审计
-
2018年,CNCF 赞助了 cure53 进行的外部安全审计,该审计从2018年4月持续到2018年6月。欲了解更多详情,请阅读审计的最终报告。
-
2020年,CNCF 赞助了 cure53 对 Node Exporter 进行的第二次审计。
-
2023年,CNCF 赞助了 Chainguard 对 Prometheus 进行的软件供应链安全评估。