本文已超過一年。較舊的文章可能包含過時的內容。檢查頁面中的資訊自發布以來是否已變得不正確。

深入探討 NSA/CISA Kubernetes 強化指南

背景

美國國家安全局 (NSA) 和網路安全暨基礎架構安全局 (CISA) 於 2021 年 8 月 3 日發布了 Kubernetes 強化指南。該指南詳細說明了 Kubernetes 環境的威脅,並提供了安全組態指南以最大程度地降低風險。

本部落格的以下章節與 NSA/CISA 指南中的章節相關。任何遺漏的章節都會跳過,因為增加新內容的機會有限。

注意:此部落格文章不能替代閱讀指南。建議先閱讀已發布的指南,再繼續閱讀,因為以下內容是補充性的。

更新,2023 年 11 月

國家安全局 (NSA) 和網路安全暨基礎架構安全局 (CISA) 於 2021 年 8 月發布了 Kubernetes 強化指南的 1.0 版本,並根據業界回饋於 2022 年 3 月更新了該指南 (1.1 版本)。

最新版本的 Kubernetes 強化指南於 2022 年 8 月發布,其中包含更正和澄清。1.2 版本概述了 強化 Kubernetes 叢集的多項建議。

簡介和威脅模型

請注意,NSA/CISA 認為重要的威脅,或本指南的目標受眾,可能與其他 Kubernetes 企業用戶認為重要的威脅不同。對於關心資料、資源盜竊和服務不可用的組織來說,本節仍然有用。

該指南重點介紹了以下三個妥協來源

  • 供應鏈風險
  • 惡意威脅行為者
  • 內部威脅 (管理員、使用者或雲端服務供應商)

威脅模型試圖退後一步,審視不僅存在於 Kubernetes 叢集邊界內的威脅,還包括 Kubernetes 未管理的底層基礎架構和周圍工作負載。

例如,當叢集外部的工作負載共用相同的實體網路時,它可以存取 kubelet 和控制平面元件:etcd、控制器管理器、排程器和 API 伺服器。因此,該指南建議進行網路級隔離,將 Kubernetes 叢集與不需要連線到 Kubernetes 控制平面節點的其他工作負載分開。具體而言,排程器、控制器管理器、etcd 只需要可供 API 伺服器存取即可。從叢集外部與 Kubernetes 的任何互動都可以透過提供對 API 伺服器埠的存取來實現。

這些元件中每一個的埠和協定清單都在 Kubernetes 文件中的 埠和協定中定義。

特別注意:kube-scheduler 和 kube-controller-manager 使用的埠與指南中提到的埠不同

CNCF 雲端原生安全白皮書 + 地圖中的 威脅建模章節提供了從雲端原生角度處理 Kubernetes 威脅建模的另一種觀點。

Kubernetes Pod 安全性

預設情況下,Kubernetes 不保證在叢集中同一節點上執行的 Pod 之間有嚴格的工作負載隔離。但是,該指南提供了幾種技術來增強現有的隔離,並在發生妥協時減少攻擊面。

「非 root」容器和「無 root」容器引擎

與最小權限的基本安全原則相關的幾項最佳實務,即僅提供所需的權限;不多也不少,值得再次審視。

該指南建議在建置時設定非 root 使用者,而不是依賴在 Pod 規格中的執行階段設定 runAsUser。這是一個良好的實務,並提供了一定程度的深度防禦。例如,如果容器映像是使用使用者 10001 建置的,並且 Pod 規格遺漏在其 Deployment 物件中新增 runAsuser 欄位。在這種情況下,有一些值得探索以提高意識的邊緣案例

  1. 如果建置時定義的使用者與 Pod 規格中定義的使用者不同,並且某些檔案因此無法存取,則 Pod 可能無法啟動。
  2. Pod 可能最終會無意中共用使用者 ID。即使在容器逃逸到主機檔案系統成為可能的情況下,使用者 ID 為非零的情況下,這也可能存在問題。一旦攻擊者可以存取主機檔案系統,他們就可以存取由共用相同 UID 的其他不相關 Pod 擁有的所有檔案資源。
  3. Pod 可能最終會與 Kubernetes 未管理的其他節點級進程 (例如用於稽核、漏洞掃描、遙測的節點級守護進程) 共用使用者 ID。威脅與上述類似,主機檔案系統存取權限可以讓攻擊者完全存取這些節點級守護進程,而無需成為節點上的 root 使用者。

但是,這些情況都不會像以 root 身分執行的容器能夠以主機上的 root 使用者身分逃逸那樣產生嚴重的影響,這可能會讓攻擊者完全控制工作節點,進而允許橫向移動到其他工作節點或控制平面節點。

Kubernetes 1.22 引入了一個 alpha 功能,該功能透過使用者命名空間專門減少了以 root 使用者身分執行的控制平面元件對非 root 使用者的影響。

對使用者命名空間/無 root 模式的該 (alpha 階段) 支援適用於以下容器運行時

某些發行版支援以無 root 模式執行,例如以下

不可變容器檔案系統

NSA/CISA Kubernetes 強化指南重點介紹了一個經常被忽略的功能 readOnlyRootFileSystem,在 附錄 B 中提供了一個工作範例。此範例限制了容器在執行階段的執行和篡改。然後可以使用 tmpfs 卷掛載將任何讀/寫活動限制在少數目錄中。

但是,某些在執行階段修改容器檔案系統的應用程式 (例如在容器啟動時展開 WAR 或 JAR 檔案) 在啟用此功能時可能會遇到問題。為避免此問題,請考慮在可能的情況下盡量減少在執行階段對檔案系統的變更。

建置安全容器映像

Kubernetes 強化指南還建議在部署時執行掃描器作為準入控制器,以防止易受攻擊或組態錯誤的 Pod 在叢集中執行。從理論上講,這聽起來像是一個好方法,但在實踐中實施之前,需要考慮幾個注意事項

  • 根據網路頻寬、可用資源和選擇的掃描器,掃描映像的漏洞可能需要不確定的時間量。這可能會導致 Pod 啟動時間變慢或不可預測,這可能會導致應用程式服務尖峰負載時出現不可用峰值。
  • 如果允許或拒絕 Pod 啟動的策略是使用不正確或不完整的資料制定的,則可能會導致多個誤報或誤判結果,例如以下情況
    • 在容器映像內部,openssl 套件被偵測為易受攻擊。但是,該應用程式是用 Golang 撰寫的,並使用 Go crypto 套件進行 TLS。因此,此漏洞不在程式碼執行路徑中,因此如果保持未修復狀態,則影響最小。
    • 在 Debian 基礎映像的 openssl 套件中偵測到漏洞。但是,上游 Debian 社群認為這是輕微影響漏洞,因此不會發布此漏洞的修補程式。此映像的所有者現在陷入了無法修復的漏洞,以及不允許映像運行的叢集,因為預先定義的策略沒有考慮漏洞的修復程式是否可用
    • Golang 應用程式建置在 distroless 映像之上,但它是使用易受攻擊的 標準程式庫的 Golang 版本編譯的。掃描器無法看到 golang 版本,只能看到 OS 級套件。因此,儘管映像包含基於易受攻擊的 golang 建置的應用程式二進位檔案,但它仍允許 Pod 在叢集中運行。

為了清楚起見,依賴漏洞掃描器絕對是一個好主意,但策略定義應足夠靈活以允許

  • 透過標籤建立映像或漏洞的例外清單
  • 根據漏洞的影響使用風險評分覆寫嚴重性
  • 在建置時應用相同的策略,以在易受攻擊的映像部署到 Kubernetes 叢集之前捕獲它們

如果叢集在氣隙環境中運行,並且掃描器需要網際網路存取才能更新漏洞資料庫,則可能也需要特殊注意事項,例如離線漏洞資料庫擷取。

Pod 安全策略

自 Kubernetes v1.21 以來,PodSecurityPolicy API 和相關功能已棄用,但本節中的某些指南在未來幾年內仍然適用,直到叢集運營商將其叢集升級到較新的 Kubernetes 版本。

Kubernetes 專案正在開發 PodSecurityPolicy 的替代品。Kubernetes v1.22 包含一個名為 Pod 安全準入 的 alpha 功能,旨在允許強制執行 Pod 之間的最低隔離級別。

Pod 安全準入的內建隔離級別源自 Pod 安全標準,Pod 安全標準是 指南第 10 頁表 I 中提到的所有元件的超集。

有關從 PodSecurityPolicy 遷移到 Pod 安全準入功能的資訊,請參閱 從 PodSecurityPolicy 遷移到內建 Pod 安全準入控制器

指南中提到的一個重要行為在 Pod 安全策略及其替代品之間保持不變,即強制執行它們中的任何一個都不會影響已在運行的 Pod。對於 PodSecurityPolicy 和 Pod 安全準入,強制執行都發生在 Pod 建立階段。

強化容器引擎

某些容器工作負載不如其他工作負載受信任,但可能需要在同一個叢集中運行。在這些情況下,在專用節點上運行它們,其中包括提供更嚴格 Pod 隔離邊界的強化容器運行時,可以作為有用的安全控制。

Kubernetes 支援一個名為 RuntimeClass 的 API,該 API 在 Kubernetes v1.20 時處於穩定/GA (因此預設啟用) 階段。RuntimeClass 允許您確保需要強隔離的 Pod 排程到可以提供強隔離的節點上。

您可以與 RuntimeClass 結合使用的一些協力廠商專案包括

正如這裡和指南中所討論的,Kubernetes 內部和周圍存在許多功能和工具,可以增強 Pod 之間的隔離邊界。根據相關威脅和風險態勢,您應該在它們之間選擇,而不是嘗試應用所有建議。話雖如此,叢集級隔離,即在專用叢集中運行工作負載,仍然是最嚴格的工作負載隔離機制,儘管此處和指南中提到了改進。

網路隔離和強化

Kubernetes 網路可能很棘手,本節重點介紹如何保護和強化相關組態。該指南將以下內容確定為主要重點

  • 使用 NetworkPolicies 在資源之間建立隔離,
  • 保護控制平面
  • 加密流量和敏感資料

網路策略

可以使用網路外掛程式建立網路策略。為了讓使用者更輕鬆地建立和視覺化,Cilium 支援 Web GUI 工具。該 Web GUI 讓您可以建立 Kubernetes NetworkPolicies (通用 API,但仍然需要相容的 CNI 外掛程式) 和/或 Cilium 網路策略 (CiliumClusterwideNetworkPolicy 和 CiliumNetworkPolicy,僅適用於使用 Cilium CNI 外掛程式的叢集)。您可以使用這些 API 來限制 Pod 之間的網路流量,從而最大程度地減少攻擊媒介。

另一個值得探索的場景是外部 IP 的使用。某些服務在組態錯誤時可能會建立隨機外部 IP。攻擊者可以利用此組態錯誤並輕鬆攔截流量。此漏洞已在 CVE-2020-8554 中報告。使用 externalip-webhook 可以透過阻止服務使用隨機外部 IP 來減輕此漏洞。externalip-webhook 僅允許建立不需要外部 IP 或其外部 IP 在管理員指定的範圍內的服務。

CVE-2020-8554 - 所有版本的 Kubernetes API 伺服器都允許能夠建立 ClusterIP 服務並設定 spec.externalIPs 欄位的攻擊者攔截到該 IP 位址的流量。此外,能夠修補 LoadBalancer 服務的 status (這被認為是特權操作,通常不應授予使用者) 的攻擊者可以將 status.loadBalancer.ingress.ip 設定為類似的效果。

資源策略

除了組態 ResourceQuotas 和限制之外,還應考慮限制給定 Pod 可以使用的進程 ID (PID) 數量,並為節點級使用保留一些 PID,以避免資源耗盡。有關應用這些限制的更多詳細資訊,請參閱 進程 ID 限制和保留

控制平面強化

在下一節中,指南涵蓋了控制平面強化。值得注意的是,從 Kubernetes 1.20 開始,已刪除 API 伺服器的不安全埠。

Etcd

一般來說,應將 etcd 伺服器組態為僅信任分配給 API 伺服器的憑證。它限制了攻擊面,並防止惡意攻擊者獲得對叢集的存取權限。為 etcd 使用單獨的 CA 可能是有益的,因為預設情況下它信任根 CA 頒發的所有憑證。

Kubeconfig 檔案

除了直接指定令牌和憑證外,.kubeconfig 還支援使用授權提供者外掛程式動態檢索臨時令牌。請注意 kubeconfig 檔案中惡意 shell 程式碼執行的可能性。一旦攻擊者獲得對叢集的存取權限,他們就可以竊取 ssh 金鑰/密碼或其他內容。

密碼

Kubernetes 密碼是以 Kubernetes API 物件形式管理密碼的原生方式。但是,在某些情況下,例如希望為所有應用程式密碼提供單一事實來源,無論它們是否在 Kubernetes 上運行,密碼都可以與 Kubernetes 鬆散耦合地管理,並由 Pod 透過 side-car 或 init-container 使用,並盡可能少地使用 Kubernetes Secrets API。

外部密碼提供者csi-secrets-store 是 Kubernetes Secrets 的一些替代方案

日誌稽核

NSA/CISA 指南強調基於日誌的監控和警報。重點包括在主機級、應用程式級和雲端級進行日誌記錄。在生產環境中運行 Kubernetes 時,務必了解誰負責以及誰負責每個日誌記錄層。

Kubernetes API 稽核

一個值得更多關注的領域是究竟應該警報或記錄什麼。該文件在 附錄 L:稽核策略中概述了一個範例策略,該策略記錄所有 RequestResponse,包括元資料和請求/回應主體。雖然對示範很有用,但對於生產環境來說可能不切實際。

每個組織都需要評估自己的威脅模型,並建立補充或有助於排除事件回應故障的稽核策略。考慮一下某人將如何攻擊您的組織,以及哪些稽核追蹤可以識別它。在官方 稽核日誌記錄文件中查看更多用於調整稽核日誌的進階選項。務必調整您的稽核日誌,使其僅包含符合您的威脅模型的事件。記錄 metadata 級別所有內容的最小稽核策略也可以是一個良好的起點。

也可以使用 kind 按照這些 說明測試稽核日誌記錄組態。

串流日誌和稽核

日誌記錄對於威脅和異常偵測非常重要。正如文件概述的那樣,最佳實務是盡可能接近即時地掃描和警報日誌,並在發生妥協時保護日誌免受篡改。務必反思各種日誌記錄級別,並識別關鍵領域,例如 API 端點。

Kubernetes API 稽核日誌記錄可以串流到 webhook,並且在 附錄 N:Webhook 組態中提供了一個範例。使用 webhook 可能是一種將日誌儲存在叢集外部和/或集中所有稽核日誌的方法。一旦日誌集中管理,請尋求根據關鍵事件啟用警報。另請確保您了解正常活動的基準是什麼。

警報識別

雖然該指南強調了通知的重要性,但沒有一個全面的事件清單可以從中發出警報。警報要求因您自己的要求和威脅模型而異。範例包括以下事件

  • Pod 的 securityContext 變更
  • 對準入控制器組態的更新
  • 存取特定檔案/URL

其他日誌記錄資源

升級和應用程式安全實務

Kubernetes 每年發布三次,因此升級相關的辛勞對於運行生產叢集的人來說是一個常見問題。除此之外,運營商必須定期升級底層節點的作業系統和運行中的應用程式。這是確保持續支援並降低錯誤或漏洞可能性的最佳實務。

Kubernetes 支援最新的三個穩定版本。雖然每個 Kubernetes 版本在發布之前都經過大量測試,但有些團隊在經過一段時間之前不願意運行最新的穩定版本。無論您運行哪個版本,都要確保頻繁或自動進行修補程式升級。更多資訊可以在 版本偏差 策略頁面中找到。

在考慮如何管理節點作業系統升級時,請考慮臨時節點。能夠銷毀和新增節點可讓您的團隊更快地回應節點問題。此外,擁有能夠容忍節點不穩定的部署 (以及鼓勵頻繁部署的文化) 可以簡化叢集升級。

此外,值得重申指南中的內容,即可以對各種系統元件執行定期漏洞掃描和滲透測試,以主動尋找不安全的組態和漏洞。

尋找發布與安全資訊

若要尋找最新的 Kubernetes 支援版本,請參閱 https://k8s.io/releases,其中包含次要版本。最好隨時更新您的次要版本修補程式。

如果您正在執行託管的 Kubernetes 產品,請尋找其發布文件並找到其各種安全管道。

訂閱 Kubernetes Announce 郵件列表。Kubernetes Announce 郵件列表可搜尋諸如「安全公告」等詞彙。只要您知道要警示的關鍵字,就可以設定警示和電子郵件通知。

結論

總之,很高興看到安全從業人員公開分享如此詳細的指南。本指南進一步突顯 Kubernetes 走向主流,以及保護 Kubernetes 叢集和在 Kubernetes 上執行的應用程式容器,仍然需要從業人員的關注和重視。在本指南發布後僅幾週,就出現了一個開源工具 kubescape,用於根據本指南驗證叢集。

這個工具可以作為檢查叢集目前狀態的良好起點,之後您可以使用本部落格文章和指南中的資訊來評估可以在哪些方面進行改進。

最後,值得重申的是,本指南中的並非所有控制措施都對所有從業人員都有意義。了解哪些控制措施重要的最佳方法是依賴您自己的 Kubernetes 環境的威脅模型。

特別感謝 Rory McCune (@raesene) 為本部落格文章提供的意見