Prometheus 是一个复杂的系统,有许多组件,并与其他系统有许多集成。它可以部署在各种可信和不可信的环境中。
本页介绍 Prometheus 的一般安全假设以及某些配置可能启用的攻击向量。
与任何复杂的系统一样,几乎可以肯定的是,一定会有漏洞被发现,其中一些与安全有关。如果您发现了安全漏洞,请私下向相关版本库 MAINTAINERS 中列出的维护者报告,并抄送 prometheus-team@googlegroups.com。我们将尽快修复问题,并与您协调发布日期。您可以选择是否希望您的努力得到公开承认,以及是否希望被提及姓名。
安全扫描仪用户特别注意:请注意所生成的报告。大多数扫描仪都是通用的,会产生很多误报。发送给我们的报告越来越多,而我们需要花费大量的精力来处理所有报告,并按照您的期望谨慎回复。这个问题在 Go 和 NPM 依赖性扫描程序中尤为严重。
为了节约我们的时间,请不要提交原始报告。相反,请在提交报告时附上分析报告,概述哪些具体结果适用于我们以及原因。
Prometheus 由志愿者而非公司负责维护。因此,安全问题的修复是在尽最大努力的基础上进行的。我们力争在 7 天内发布以下产品的安全修复程序: Prometheus、Alertmanager、Node Exporter、Blackbox Exporter 和 Pushgateway。
假设不受信任的用户可以访问 Prometheus HTTP 端点和日志。他们可以访问数据库中包含的所有时间序列信息,以及各种运行/调试信息。
我们还假定,只有受信任的用户才有能力更改命令行、配置文件、规则文件以及 Prometheus 和其他组件运行环境的其他方面。
Prometheus 扫描哪些目标、扫描频率以及其他设置完全由配置文件决定。管理员可以决定使用来自服务发现系统的信息,再加上重新标记,就可以将部分控制权授予任何可以修改该服务发现系统中数据的人。
抓取的目标可能由不受信任的用户运行。默认情况下,目标不应公开模拟其他目标的数据。honor_labels 选项可以取消这种保护,某些重贴标签设置也可以取消这种保护。
从 Prometheus 2.0 开始,--web.enable-admin-api 标志可控制对管理 HTTP API 的访问,其中包括删除时间序列等功能。默认情况下禁用。如果启用,则可在 /api/*/admin/ 路径下访问管理和更改功能。web.enable-lifecycle 标志可控制 Prometheus 的 HTTP 重载和关闭。默认情况下也是禁用的。如果启用,则可在 /-/reload 和 /-/quit 路径下访问。
在 Prometheus 1.x 中,/-/reload 和在/api/v1/series 上使用 DELETE 可被任何可访问 HTTP API 的人访问。/-/quit 端点默认为禁用,但可以使用 -web.enable-remote-shutdown 标志启用。
远程读取功能允许任何有 HTTP 访问权限的人向远程读取端点发送查询。例如,如果 PromQL 查询最终直接针对关系数据库运行,那么任何有能力向 Prometheus 发送查询(如通过 Grafana)的人都可以针对该数据库运行任意 SQL。
任何可以访问 Alertmanager HTTP 端点的用户都可以访问其数据。他们可以创建和解决警报。他们可以创建、修改和删除静音。
通知发送到哪里由配置文件决定。在某些模板设置下,通知可能会发送到警报定义的目的地。例如,如果通知使用警报标签作为目标电子邮件地址,那么任何可以向警报管理器发送警报的人都可以向任何电子邮件地址发送通知。如果警报定义的目标是一个可模板化的秘密字段,那么任何可以访问 Prometheus 或 Alertmanager 的人都可以查看这些秘密。
任何可模板化的秘密字段都是用于上述用例中的路由通知。使用模板文件功能将秘密从配置文件中分离出来的方式并非如此。任何能在 Alertmanager 配置文件中配置接收器的人都有可能泄露存储在模板文件中的秘密。例如,在大型设置中,每个团队可能都有一个他们完全控制的警报管理器配置文件片段,然后将其合并为完整的最终配置文件。
任何可以访问 Pushgateway HTTP 端点的用户都可以创建、修改和删除其中包含的度量指标。由于 Pushgateway 通常是在启用 honor_labels 的情况下抓取的,这意味着任何能访问 Pushgateway 的人都能在 Prometheus 中创建任何时间序列。
--web.enable-admin-api 标志可控制对管理HTTP API的访问,其中包括清除所有现有度量组等功能。默认情况下禁用。如果启用,则可在 /api/*/admin/ 路径下访问管理功能。
Exporter 一般只与一个配置实例对话,并预设一组命令/请求,这些命令/请求无法通过 HTTP 端点扩展。
还有一些输出程序,如 SNMP 和 Blackbox Exporter,其目标来自 URL 参数。因此,任何有 HTTP 访问权限的人都可以让这些 Exporter 向任意端点发送请求。由于它们也支持客户端身份验证,这可能会导致 HTTP Basic Auth 密码或 SNMP 社区字符串等机密泄露。Challenge-response 验证机制(如 TLS)不受此影响。
客户端库旨在包含在用户的应用程序中。
如果使用客户库提供的 HTTP 处理程序,那么到达该处理程序的恶意请求除了会导致额外负载和抓取失败外,应该不会造成其他问题。
Prometheus 和大多数 Exporter 都支持 TLS。包括通过 TLS 客户端证书验证客户端。有关配置 Prometheus 的详细信息,请点击此处。
Go 项目共享基于 Go crypto/tls 库的相同 TLS 库。我们默认 TLS 1.2 为最低版本。我们在这方面的政策是基于 Qualys SSL 实验室的建议,即我们努力通过默认配置和正确提供的证书达到 "A" 级,同时尽可能贴近 Go 的上游默认设置。达到这一等级可在完美的安全性和可用性之间取得平衡。
TLS 将在未来添加到 Java Exporter 中。
如果你有特殊的 TLS 需求,如不同的密码套件或较旧的 TLS 版本,只要密码未在 crypto/tls 库中标记为不安全,你就可以调整最低 TLS 版本和密码。如果这仍然不适合您,那么当前的 TLS 设置允许您在服务器和具有更多特殊要求的反向代理之间构建一个安全通道。
还支持 HTTP Basic Authentication。基本身份验证(Basic Authentication)可以在没有 TLS 的情况下使用,但这样用户名和密码就会在网络上以明文形式暴露。
在服务器端,基本身份验证密码使用 bcrypt 算法存储为哈希值。选择符合安全标准的轮数是你的责任。轮数越多,暴力破解越复杂,CPU 功耗越高,验证请求的时间越长。
什么是轮数?
在密码破解的上下文中,“pick the number of rounds”轮数通常指的是加密算法中应用的迭代次数或密钥扩展的轮数。在很多现代加密算法中,特别是在对称加密算法(如AES)或密钥派生函数(如PBKDF2, bcrypt等)中,数据会被多次、反复地以相同的方式处理,以增加加密的复杂性和安全性。每一轮处理都可能涉及替换、置换、异或等运算,并可能结合不同的密钥或子密钥。
轮数(rounds)是这些重复处理步骤的数量。选择更多的轮数通常会使得加密算法更加安全,因为它增加了暴力破解所需的计算时间。然而,更多的轮数也可能意味着加密和解密过程需要更长的时间,从而可能影响性能。
Prometheus 的各种组件都支持客户端验证和加密。如果提供 TLS 客户端支持,通常还有一个称为 insecure_skip_verify 的选项,可以跳过 SSL 验证。
由于管理和更改端点旨在通过 cURL 等简单工具进行访问,因此没有内置 CSRF 保护,否则会破坏此类使用案例。因此,在使用反向代理时,您可能希望阻止此类路径,以防止 CSRF。
对于非突变端点,您可能希望在反向代理中设置 CORS 标头(如 Access-Control-Allow-Origin),以防止 XSS。
如果您编写的 PromQL 查询包含来自不受信任用户的输入(例如控制台模板的 URL 参数或您自己创建的内容),而这些用户并不打算运行任意 PromQL 查询,请确保对任何不受信任的输入进行适当转义,以防止注入攻击。例如,如果 <user_input> 为"} 或 some_metric{zzz=",up{job="<user_input>"} 将变成 up{job=""} 或 some_metric{zzz=""}。
使用 Grafana 的用户请注意,仪表盘权限不是数据源权限,因此不会限制用户在代理模式下运行任意查询的能力。
非机密信息或字段可通过 HTTP API 和/或日志获取。
在 Prometheus 中,从服务发现中获取的元数据不视为机密。在整个 Prometheus 系统中,度量指标不被视为机密。
配置文件中包含秘密的字段(在文档中明确标记为秘密)不会在日志中或通过 HTTP API 暴露。秘密不应放在其他配置字段中,因为组件通常会通过 HTTP 端点公开其配置。用户有责任保护磁盘上的文件不被意外读写。
依赖项使用的其他来源的秘密(例如 EC2 服务发现使用的 AWS_SECRET_KEY 环境变量)可能会由于我们无法控制的代码或由于恰好暴露其存储位置的功能而最终暴露。
对于超负荷或昂贵的查询,有一些缓解措施。但是,如果提供过多或过高的查询/度量,组件就会崩溃。与恶意行为相比,组件被可信用户意外删除的可能性更大。
用户有责任确保为组件提供足够的资源,包括 CPU、RAM、磁盘空间、IOPS、文件描述符和带宽。
建议对所有组件进行故障监控,并在故障发生时自动重新启动。
本文档考虑的是由原始源代码构建的普通二进制文件。如果您修改 Prometheus 源代码,或在自己的代码中使用 Prometheus 内部组件(官方客户端库 API 之外),则此处提供的信息不适用。
Prometheus 的构建管道运行在第三方供应商上,Prometheus 开发团队的许多成员和这些供应商的员工都可以访问这些供应商。如果您担心二进制文件的确切来源,建议您自行构建,而不要依赖项目提供的预构建二进制文件。
Prometheus-Community 组织下的软件源由第三方维护者提供支持。
如果您在 Prometheus-Community 组织中发现安全漏洞,请私下向相关软件源的 MAINTAINERS 中列出的维护者报告,并通过 CC prometheus-team@googlegroups.com。
该组织下的某些版本库的安全模型可能与本文档中介绍的不同。在这种情况下,请参考这些版本库的文档。
2018 年,CNCF 赞助了 cure53 的外部安全审计,审计时间为 2018 年 4 月至 2018 年 6 月。详情请阅读审计最终报告。
2020 年,CNCF 赞助 cure53 对 Node Exporter 进行第二次审计。
2023 年,CNCF 赞助 Chainguard 对 Prometheus 进行软件供应链安全评估。