Kubernetes API 伺服器繞過風險
Kubernetes API 伺服器是外部方(使用者與服務)與叢集互動的主要進入點。
作為此角色的一部分,API 伺服器具有多項關鍵的內建安全性控制,例如稽核日誌與許可控制器。然而,有些方法可以修改叢集的組態或內容,以繞過這些控制。
本頁面描述可以繞過 Kubernetes API 伺服器內建安全性控制的方式,以便叢集操作員與安全性架構師可以確保適當地限制這些繞過。
靜態 Pod
每個節點上的 kubelet 會載入並直接管理儲存在指定目錄中或從特定 URL 擷取的任何資訊清單,作為叢集中的 靜態 Pod。API 伺服器不管理這些靜態 Pod。具有此位置寫入權限的攻擊者可以修改從該來源載入的靜態 Pod 組態,或可以引入新的靜態 Pod。
靜態 Pod 無法存取 Kubernetes API 中的其他物件。例如,您無法設定靜態 Pod 從叢集掛載密鑰。然而,這些 Pod 可以採取其他安全性敏感動作,例如使用來自底層節點的 hostPath
掛載。
預設情況下,kubelet 會建立鏡像 Pod,以便靜態 Pod 在 Kubernetes API 中可見。然而,如果攻擊者在建立 Pod 時使用無效的命名空間名稱,則它將在 Kubernetes API 中不可見,並且只能由有權存取受影響主機的工具發現。
如果靜態 Pod 未通過許可控制,則 kubelet 將不會向 API 伺服器註冊 Pod。然而,Pod 仍在節點上執行。如需更多資訊,請參閱 kubeadm issue #1541。
緩解措施
- 僅在節點需要時才啟用 kubelet 靜態 Pod 資訊清單功能。
- 如果節點使用靜態 Pod 功能,請將對靜態 Pod 資訊清單目錄或 URL 的檔案系統存取權限制於需要存取權的使用者。
- 限制對 kubelet 組態參數與檔案的存取,以防止攻擊者設定靜態 Pod 路徑或 URL。
- 定期稽核並集中報告對託管靜態 Pod 資訊清單與 kubelet 組態檔的目錄或 Web 儲存位置的所有存取。
kubelet API
kubelet 提供 HTTP API,通常在叢集工作節點上的 TCP 連接埠 10250 上公開。API 也可能在控制平面節點上公開,具體取決於使用的 Kubernetes 發行版本。直接存取 API 允許揭露關於節點上執行的 Pod、來自這些 Pod 的日誌,以及在節點上執行的每個容器中執行命令的資訊。
當 Kubernetes 叢集使用者具有對 Node
物件子資源的 RBAC 存取權時,該存取權充當與 kubelet API 互動的授權。確切的存取權取決於已授予哪個子資源存取權,如 kubelet 授權 中詳述。
直接存取 kubelet API 不受許可控制,也不會由 Kubernetes 稽核日誌記錄。具有對此 API 直接存取權的攻擊者可能能夠繞過偵測或阻止特定動作的控制。
kubelet API 可以設定為以多種方式驗證請求。預設情況下,kubelet 組態允許匿名存取。大多數 Kubernetes 提供者將預設值變更為使用 webhook 與憑證驗證。這讓控制平面可以確保呼叫者被授權存取 nodes
API 資源或子資源。預設匿名存取不會使用控制平面進行此判斷。
緩解措施
- 使用諸如 RBAC 之類的機制限制對
nodes
API 物件子資源的存取。僅在需要時才授予此存取權,例如由監控服務。 - 限制對 kubelet 連接埠的存取。僅允許指定的與信任的 IP 位址範圍存取該連接埠。
- 確保 kubelet 身分驗證 設定為 webhook 或憑證模式。
- 確保未在叢集上啟用未經身分驗證的「唯讀」Kubelet 連接埠。
etcd API
Kubernetes 叢集使用 etcd 作為資料儲存區。etcd
服務在 TCP 連接埠 2379 上監聽。唯一需要存取的用戶端是 Kubernetes API 伺服器以及您使用的任何備份工具。直接存取此 API 允許揭露或修改叢集中持有的任何資料。
對 etcd API 的存取通常由用戶端憑證身分驗證管理。由 etcd 信任的憑證授權單位發出的任何憑證都允許完全存取儲存在 etcd 內部的資料。
直接存取 etcd 不受 Kubernetes 許可控制,也不會由 Kubernetes 稽核日誌記錄。具有對 API 伺服器的 etcd 用戶端憑證私密金鑰讀取權限(或可以建立新的信任用戶端憑證)的攻擊者可以透過存取叢集密鑰或修改存取規則來獲得叢集管理員權限。即使沒有提升其 Kubernetes RBAC 權限,可以修改 etcd 的攻擊者也可以檢索任何 API 物件或在叢集內建立新的工作負載。
許多 Kubernetes 提供者設定 etcd 以使用相互 TLS(用戶端與伺服器都驗證彼此的憑證以進行身分驗證)。etcd API 的授權沒有廣泛接受的實作,儘管該功能存在。由於沒有授權模型,因此任何具有對 etcd 用戶端存取權的憑證都可用於獲得對 etcd 的完全存取權。通常,僅用於健康狀態檢查的 etcd 用戶端憑證也可以授予完全讀取與寫入存取權。
緩解措施
- 確保 etcd 信任的憑證授權單位僅用於驗證該服務身分的用途。
- 控制對 etcd 伺服器憑證的私密金鑰,以及對 API 伺服器的用戶端憑證與金鑰的存取。
- 考慮在網路層級限制對 etcd 連接埠的存取,僅允許來自指定與信任的 IP 位址範圍的存取。
容器執行期 Socket
在 Kubernetes 叢集中的每個節點上,與容器互動的存取權是由容器執行期(或多個執行期,如果您設定了多個)所控制。通常,容器執行期會公開一個 kubelet 可以存取的 Unix socket。攻擊者若能存取此 socket,便可以啟動新的容器或與正在執行的容器互動。
在叢集層級,此存取的影響取決於在受入侵節點上執行的容器是否可以存取 Secrets 或其他機密資料,而攻擊者可能會利用這些資料將權限提升到其他工作節點或控制平面元件。
緩解措施
- 請務必嚴格控制對容器執行期 socket 的檔案系統存取權。在可能的情況下,請將此存取權限制為
root
使用者。 - 使用諸如 Linux 核心命名空間之類的機制,將 kubelet 與節點上執行的其他元件隔離。
- 請務必限制或禁止使用包含容器執行期 socket 的
hostPath
掛載,無論是直接包含還是透過掛載父目錄的方式。此外,hostPath
掛載必須設定為唯讀,以降低攻擊者繞過目錄限制的風險。 - 限制使用者對節點的存取權,尤其要限制超級使用者對節點的存取權。