安全模型

注意在深入探討以下技術細節之前,我們想強調的是,Prometheus 作為一個監控系統,負責收集和提供其監控系統的資訊。因此,不應將 Prometheus 元件提供的 HTTP 端點暴露給公共網路(如網際網路,除非您清楚自己在做什麼並採取了適當的措施)。這包括(但不限於)已插樁二進位制檔案的 /metrics 端點、伺服器元件的各種 API 端點,以及用 Go 實現的伺服器元件的 /pprof 端點。此外,透過對這些端點發起請求,很容易使伺服器過載並最終導致拒絕服務(DoS)。

Prometheus 是一個複雜的系統,擁有許多元件以及與其他系統的諸多整合。它可以部署在各種受信任和不受信任的環境中。

本頁描述了 Prometheus 的一般安全假設,以及某些配置可能引入的攻擊向量。

與任何複雜系統一樣,幾乎可以肯定會發現漏洞,其中一些可能與安全相關。

對於已經公開披露(例如透過公開的 CVE)且修復方案不僅僅是升級依賴版本的 安全漏洞,請提交一份包含所有相關細節的 Bug 報告 ,除非已經有人提交過。

如果您發現了一個尚未公開披露的 安全漏洞,請私下報告給相關倉庫的 MAINTAINERS 中列出的維護者,並抄送 [email protected] 。我們將盡快修復該問題並與您協調發布日期。您可以選擇是否公開表彰您的努力以及是否署名。

大多數依賴版本更新都是自動處理的。但是,如果 安全漏洞 的修復只需要更新依賴版本,而我們的自動化工具遺漏了,歡迎直接提交更新。

自動化安全掃描器

安全掃描器使用者的特別提示:請謹慎對待生成的報告。大多數掃描器都是通用的,會產生大量的誤報。我們收到的報告越來越多,需要花費大量的工作來逐一審查並給予您所期望的認真回覆。在使用 Go 和 NPM 依賴掃描器時,這個問題尤其嚴重。

出於對我們和我們時間的尊重,我們懇請您不要直接提交原始報告。相反,請在提交時附帶一份分析,說明哪些具體結果適用於我們以及原因。

此外請注意,作為一個開源專案,我們通常無法使用商業掃描工具,並且發現它們的輸出往往具有誤導性,甚至是完全錯誤的。對於 Go 程式碼,如果您的報告在針對您認為受影響版本的 原始碼(而非二進位制檔案,因為後者無法進行完整分析)執行開源的 govulncheck  工具時無法復現,那麼我們請求您反覆核實您的發現(包括該程式碼在 Prometheus 程式碼庫中是否實際可達)。

Prometheus 是由志願者維護的,而不是由公司維護。因此,安全問題的修復是盡力而為。我們爭取在 7 天內為以下專案釋出安全修復:Prometheus、Alertmanager、Node Exporter、Blackbox Exporter 和 Pushgateway。

Prometheus

我們假設不受信任的使用者可以訪問 Prometheus HTTP 端點和日誌。他們可以訪問資料庫中包含的所有時間序列資訊,以及各種運維/除錯資訊。

我們還假設只有受信任的使用者才有能力更改命令列、配置檔案、規則檔案以及 Prometheus 和其他元件執行環境的其他方面。

Prometheus 抓取哪些目標、抓取頻率以及其他設定完全由配置檔案決定。管理員可能會決定使用來自服務發現系統的資訊,結合重寫標籤(relabeling),這可能會將部分控制權轉交給任何能夠修改該服務發現系統中資料的人。

被抓取的目標可能由不受信任的使用者執行。預設情況下,目標不應該能夠透過暴露資料來冒充另一個目標。honor_labels 選項會取消這種保護,某些重寫標籤(relabeling)設定也是如此。

自 Prometheus 2.0 起,--web.enable-admin-api 標誌用於控制對管理 HTTP 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 傳送告警的人都可以向任何電子郵件地址傳送通知。如果由告警定義的目的地是一個可套用模板的敏感資訊(secret)欄位,那麼任何能夠訪問 Prometheus 或 Alertmanager 的人都可以檢視這些敏感資訊。

任何可套用模板的敏感資訊欄位在上述用例中僅用於路由通知。它們不應該用作透過模板檔案功能將敏感資訊從配置檔案中分離出來的一種方式。儲存在模板檔案中的任何敏感資訊都可能被任何能夠配置 Alertmanager 配置檔案中接收器(receiver)的人竊取。例如,在大型部署中,每個團隊可能擁有一個他們完全控制的 alertmanager 配置檔案片段,這些片段隨後被合併為最終的完整配置檔案。

Pushgateway

任何可以訪問 Pushgateway HTTP 端點的使用者都可以建立、修改和刪除其中包含的指標。由於抓取 Pushgateway 時通常會啟用 honor_labels,這意味著任何可以訪問 Pushgateway 的人都可以在 Prometheus 中建立任何時間序列。

--web.enable-admin-api 標誌用於控制對管理 HTTP API 的訪問,其中包括清除所有現有指標組等功能。該功能預設停用。如果啟用,管理功能將可以透過 /api/*/admin/ 路徑進行訪問。

Exporter

Exporter 通常只使用預設的一組命令/請求與一個配置好的例項進行通訊,這無法透過其 HTTP 端點進行擴充套件。

還有一些 Exporter(例如 SNMP 和 Blackbox Exporter)從 URL 引數中獲取目標。因此,任何擁有這些 Exporter HTTP 訪問許可權的人都可以讓它們向任意端點發送請求。由於它們還支援客戶端認證,這可能會導致敏感資訊洩露,例如 HTTP 基本認證密碼或 SNMP 團體字。諸如 TLS 這樣的挑戰-應答認證機制不受此影響。

客戶端庫

客戶端庫旨在包含在使用者的應用程式中。

如果使用客戶端庫提供的 HTTP 處理器,到達該處理器的惡意請求除了導致額外負載和抓取失敗之外,不應造成其他問題。

認證、授權和加密

Prometheus 和大多數 Exporter 都支援 TLS。包括透過 TLS 客戶端證書進行客戶端認證。配置 Prometheus 的詳細資訊在 這裡

這些 Go 專案共享相同的 TLS 庫,該庫基於 Go 的 crypto/tls  庫。我們預設將 TLS 1.2 作為最低版本。我們在這方面的策略基於 Qualys SSL Labs  的建議,我們力求在預設配置和正確提供證書的情況下達到“A”級,同時儘可能貼合上遊 Go 的預設設定。達到該級別可以在完美的安全性和可用性之間取得平衡。

未來將為 Java Exporter 新增 TLS 支援。

如果您有特殊的 TLS 需求(例如不同的密碼套件或更舊的 TLS 版本),只要該密碼在 crypto/tls  庫中沒有被標記為不安全 ,您就可以調整最低 TLS 版本和密碼。如果這仍然不能滿足您的需求,當前的 TLS 設定允許您在伺服器與具有更特殊要求的反向代理之間建立安全隧道。

同時也支援 HTTP 基本認證(Basic Authentication)。基本認證可以在沒有 TLS 的情況下使用,但隨後會在網路上以明文形式暴露使用者名稱和密碼。

在伺服器端,基本認證的密碼使用 bcrypt  演算法以雜湊形式儲存。您有責任選擇符合您安全標準的計算輪數(rounds)。更多的輪數會使暴力破解變得更困難,但代價是消耗更多的 CPU 算力和更長的請求認證時間。

各種 Prometheus 元件都支援客戶端認證和加密。如果提供了 TLS 客戶端支援,通常還會有一個名為 insecure_skip_verify 的選項,用於跳過 SSL 驗證。

API 安全

由於管理和變更端點旨在透過 cURL 等簡單工具進行訪問,因此沒有內建的 CSRF  防護,因為這會破壞此類用例。因此,當使用反向代理時,您可能希望遮蔽這些路徑以防止 CSRF。

對於非變更端點,您可能希望在反向代理中設定 CORS 響應頭 ,例如 Access-Control-Allow-Origin,以防止 XSS 

如果您正在編寫包含不受信任使用者輸入的 PromQL 查詢(例如控制檯模板的 URL 引數,或者您自己構建的系統),而這些使用者本不應該能夠執行任意 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、檔案描述符和頻寬。

建議監控所有元件的故障情況,並在故障時讓它們自動重啟。

本文件僅考慮從官方原始碼構建的純淨(vanilla)二進位制檔案。如果您修改了 Prometheus 原始碼,或者在您自己的程式碼中使用了 Prometheus 內部實現(超出官方客戶端庫 API),那麼此處提供的資訊將不適用。

構建過程

Prometheus 的構建流水線在第三方服務商上執行,許多 Prometheus 開發團隊成員以及這些服務商的員工都可以訪問該流水線。如果您擔心二進位制檔案的確切來源,建議您自己進行構建,而不是依賴專案提供的預構建二進位制檔案。

Prometheus-Community

Prometheus-Community  組織下的倉庫由第三方維護者支援。

如果您在 Prometheus-Community  組織中發現了 安全漏洞,請私下報告給相關倉庫的 MAINTAINERS 中列出的維護者,並抄送 [email protected] 

該組織下的某些倉庫可能具有與本文件中介紹的不同的安全模型。在這種情況下,請參考這些倉庫的文件。

外部審計

本頁內容