安全模型

注意在深入研究下面的技术细节之前,我们想强调 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 抓取哪些目标、抓取的频率以及其他设置完全由配置文件决定。管理员可以决定使用服务发现系统中的信息,而服务发现系统结合重写规则可能会将部分控制权授予任何能够修改该服务发现系统中的数据的人。

抓取的 targets 可能由不受信任的用户运行。默认情况下,一个 target 不应能够暴露模仿另一个 target 的数据。honor_labels 选项会移除此保护,某些重写规则设置也可能如此。

从 Prometheus 2.0 开始,--web.enable-admin-api 标志控制对管理 HTTP API 的访问,该 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

任何有权访问 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 community strings。挑战-响应认证机制(如 TLS)不受此影响。

客户端库

客户端库旨在包含在用户的应用程序中。

如果使用客户端库提供的 HTTP 处理程序,那么到达该处理程序的恶意请求不应导致除额外负载和抓取失败之外的其他问题。

身份验证、授权和加密

Prometheus 和大多数导出器支持 TLS。包括通过 TLS 客户端证书进行客户端身份验证。有关配置 Prometheus 的详细信息,请参见此处

Go 项目共享相同的 TLS 库,该库基于 Go 的crypto/tls 库。我们将 TLS 1.2 作为最低版本。我们关于此的策略基于Qualys SSL Labs 的建议,力求在默认配置和正确提供的证书下达到“A”级,同时尽可能遵循上游 Go 的默认设置。达到该等级可以平衡完美的安全性和可用性。

未来将在 Java 导出器中添加 TLS。

如果您有特殊的 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、内存、磁盘空间、IOPS、文件描述符和带宽。

建议监控所有组件的故障,并使其在发生故障时自动重新启动。

本文档考虑的是从标准源代码构建的普通二进制文件。如果您修改 Prometheus 源代码,或在自己的代码中使用 Prometheus 内部组件(超出官方客户端库 API),则此处提供的信息不适用。

构建过程

Prometheus 的构建管道在第三方提供商上运行,许多 Prometheus 开发团队成员和这些提供商的员工都可以访问。如果您担心二进制文件的确切来源,建议您自行构建,而不是依赖项目提供的预构建二进制文件。

Prometheus-Community

Prometheus-Community  组织下的存储库由第三方维护者支持。

如果您在Prometheus-Community 组织中发现安全漏洞,请私下报告给相关存储库的 MAINTAINERS 中列出的维护者,并将[email protected] 抄送。

该组织下的某些存储库可能具有与本文档不同的安全模型。在这种情况下,请参阅这些存储库的文档。

外部审计

本页内容