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

深入瞭解 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 使用者。

在以下容器執行時中,對使用者名稱空間/無根模式的alpha 階段支援可用:

一些發行版支援以無根模式執行,例如以下:

不可變容器檔案系統

NSA/CISA Kubernetes 安全強化指南強調了一個經常被忽視的功能 `readOnlyRootFileSystem`,並在附錄 B 中提供了一個工作示例。此示例限制了容器在執行時的執行和篡改。任何讀/寫活動都可以透過使用 `tmpfs` 卷掛載來限制到少數幾個目錄。

但是,一些在執行時修改容器檔案系統的應用程式(例如在容器啟動時解壓 WAR 或 JAR 檔案)在啟用此功能時可能會遇到問題。為了避免此問題,請考慮在可能的情況下,在執行時對檔案系統進行最小的更改。

構建安全的容器映象

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

  • 根據網路頻寬、可用資源和所選掃描器,掃描映象漏洞所需的時間可能不確定。這可能導致 Pod 啟動時間變慢或不可預測,從而在應用程式達到高峰負載時導致不可用性峰值。
  • 如果用於允許或拒絕 Pod 啟動的策略是使用不正確或不完整的資料制定的,可能會導致以下幾種誤報或漏報結果:
    • 在容器映象中,`openssl` 包被檢測為存在漏洞。但是,應用程式是用 Golang 編寫的,並使用 Go 的 `crypto` 包進行 TLS。因此,此漏洞不在程式碼執行路徑中,因此即使未修復,影響也最小。
    • Debian 基礎映象中的 `openssl` 包被檢測到存在漏洞。然而,上游 Debian 社群認為這是一個影響較小的漏洞,因此沒有釋出此漏洞的補丁。該映象的所有者現在陷入了一個無法修復的漏洞和一個不允許映象執行的叢集,因為預定義的策略沒有考慮漏洞的修復是否可用。
    • 一個 Golang 應用程式構建在 distroless 映象之上,但它使用一個存在漏洞的 標準庫 的 Golang 版本進行編譯。掃描器無法檢視 Golang 版本,只能檢視作業系統級別的包。因此,即使映象包含一個基於存在漏洞的 Golang 構建的應用程式二進位制檔案,它也允許 Pod 在叢集中執行。

需要明確的是,依賴漏洞掃描器絕對是個好主意,但策略定義應足夠靈活以允許:

  • 透過標籤建立映象或漏洞的例外列表
  • 根據漏洞的影響,用風險評分覆蓋嚴重性
  • 在構建時應用相同的策略,以便在易受攻擊的映象部署到 Kubernetes 叢集之前發現它們的可修復漏洞

如果叢集在氣隙環境中執行且掃描器需要網際網路訪問才能更新漏洞資料庫,則可能還需要考慮特殊因素,例如離線漏洞資料庫獲取。

Pod 安全策略

自 Kubernetes v1.21 起,PodSecurityPolicy API 及相關功能已被棄用,但本節中的某些指南在未來幾年內仍將適用,直到叢集操作員將其叢集升級到較新的 Kubernetes 版本。

Kubernetes 專案正在開發 PodSecurityPolicy 的替代方案。Kubernetes v1.22 包含一個名為 Pod 安全准入 的 Alpha 功能,旨在強制 Pod 之間達到最低限度的隔離。

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

關於從 PodSecurityPolicy 遷移到 Pod 安全准入功能的資訊可在從 PodSecurityPolicy 遷移到內建 PodSecurity 准入控制器中找到。

指南中提到的一個重要行為,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 伺服器的證書。這限制了攻擊面,並防止惡意攻擊者獲取對叢集的訪問許可權。使用單獨的 CA 對 etcd 可能會有益,因為它預設信任根 CA 頒發的所有證書。

Kubeconfig 檔案

除了直接指定令牌和證書外,`kubeconfig` 還支援使用身份驗證提供程式外掛動態檢索臨時令牌。請注意 `kubeconfig` 檔案中惡意 shell 程式碼執行的可能性。一旦攻擊者獲得叢集訪問許可權,他們就可以竊取 ssh 金鑰/秘密或更多資訊。

Secrets

Kubernetes Secrets 是將秘密作為 Kubernetes API 物件進行管理的本機方式。但是,在某些情況下,例如希望為所有應用程式秘密擁有單一真相來源,無論它們是否在 Kubernetes 上執行,秘密都可以與 Kubernetes 鬆散耦合地進行管理,並透過 Sidecar 或 Init 容器(最小化使用 Kubernetes Secrets API)供 Pod 使用。

外部秘密提供程式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) 對本部落格文章的貢獻。