歡迎光臨
每天分享高質量文章

Kubernetes集群組件的安全

 

在《保護Kubernetes for Cloud Native Applications》系列的前一篇文章中,我們討論了在保護部署Kubernetes集群的基礎設施時需要考慮的因素。這一次,我們將註意力轉移到集群本身。

Kubernetes是一個複雜的系統,上圖顯示了構成一個集群的許多不同的組成部分。為了保持集群的整體完整性,需要仔細保護每一個組件中。
在本文中,我們無法涵蓋集群級安全性的各個方面,但我們的標的是解決更重要的主題。正如我們稍後將看到的,可以從更廣泛的社區獲得幫助,包括Kubernetes集群的最佳實踐安全性,以及衡量對最佳實踐的遵守情況的工具。

 

集群安裝

 

我們應該首先簡要觀察一下可以用來安裝集群組件的許多不同工具。
從安全角度來看,Kubernetes集群組件的某些預設配置引數是次優的,需要正確設置以確保安全集群。 除非您選擇托管的Kubernetes集群(例如Giant Swarm提供的集群),代表您管理整個集群,否則許多不同的集群安裝工具會加劇這個問題,每個工具都會有一些微妙的不同配置。雖然大多數安裝程式都提供了合理的預設設置,但我們絕不應該認為它們在安全性方面有所支持,我們的標的應該是確保我們選擇使用哪種安裝程式機制,並將其配置為匹配我們的要求。
讓我們來看一下控制平面安全性的一些重要方面。

 

API Server

 

API服務器是群集中所有通信的中心,它位於應用了大部分群集安全配置的API服務器上。API服務器是群集控制平面的唯一組件,它能夠直接與群集的狀態儲存進行交互。操作集群,其他控制平面組件以及有時集群工作負載的用戶都使用服務器的基於HTTP的REST API與集群交互。
由於其在集群控制中的關鍵作用,因此就安全性而言,仔細管理對API服務器的訪問至關重要。如果某人或某些人獲得了對API的未經請求的訪問權限,他們就有可能獲得各種敏感信息,並獲得對集群本身的控制權。因此,客戶端對Kubernetes API的訪問應該進行加密,驗證和授權。
使用TLS進行安全通訊
為防止中間人攻擊,應使用TLS對每個客戶端和API服務器之間的通信進行加密。為此,需要使用私鑰和X.509證書配置API服務器。
一般來說,發API服務器證書的根證書頒發機構(CA)的X.509證書必須可供在TLS握手期間需要向API服務器進行身份驗證的任何客戶端使用,這導致我們遇到群集的證書頒發機構的問題。正如我們稍後將看到的,客戶端可以通過多種方式對API服務器進行身份驗證,其中一種方法是通過X.509證書。 如果採用這種客戶端身份驗證方法,在大多數情況下(至少對於群集組件)可能都是如此,每個集群組件都應該獲得自己的證書,建立集群範圍的PKI功能很有意義。
有許多方法可以為集群實現PKI功能,沒有說一種方法比另一種更好。它可以手動配置,可以由您選擇的安裝程式配置,或通過其他方式配置。實際上,可以將集群配置為具有自己的內置CA,該CA可以發出證書以響應通過API服務器提交的證書簽名請求。在Giant Swarm,我們使用名為cert-operator的運算子與Hashicorp的Vault[1]一起使用。
雖然我們的主題是與API服務器進行安全通信,但請務必禁用其不安全的端口(在Kubernetes 1.13之前),該端口通過普通HTTP(–insecure-port = 0)提供API!
身份驗證,授權和準入控制
現在讓我們將註意力轉移到控制哪些客戶端可以對集群中的哪些資源執行哪些操作。我們在這裡不會詳細介紹,總的來說,這是下一篇文章的主題。 重要的是確保控制平面的組件配置為提供底層訪問控制。

當API請求落在API服務器上時,它會執行一系列檢查以確定是否為請求提供服務,如果它確實為請求提供服務,則是根據定義的策略驗證是為請求提供服務還是改變資源物件,執行鏈如上圖所示。
Kubernetes支持許多不同的身份驗證方案,這些方案幾乎總是在集群外部實現,包括X.509證書,基本身份驗證,bearer令牌,用於通過可信身份提供商進行身份驗證的OpenID Connect(OIDC)等。使用API服務器上的相關配置選項可以啟用多種方案,因此請務必為計劃使用的身份驗證方案提供這些選項。例如,X.509客戶端證書身份驗證需要包含一個或多個CA證書( -client-ca-file)檔案路徑。需要記住的一點是,預設情況下,任何未通過其中一種身份驗證方案驗證的API請求都會被視為匿名請求。雖然匿名請求獲得的訪問權限可能受到授權的限制,但如果不需要,則應完全關閉它們(–anonymous-auth = false)。
驗證請求後,API服務器會根據授權策略考慮請求。同樣,授權樣式是一個配置選項(–authorization-mode),至少應該從預設值AlwaysAllow進行更改。理想情況下,授權樣式串列應包括RBAC和Node,前者用於啟用RBAC API以進行細粒度訪問控制,後者用於授權kubelet API請求(見下文)。
一旦API請求經過身份驗證和授權,資源物件在使用admission controller持久儲存到集群的狀態資料庫之前可能會經過驗證或改變。建議使用最少的admission controller,除非有充分的理由,否則不應從串列中刪除。 額外的安全相關的admission controllers值得考慮:
  • DenyEscalatingExec:如果必須允許您的Pod以增強的權限運行(例如使用主機的IPC/PID命名空間),則此admission controller將阻止用戶在Pod的特權容器中執行命令。

  • PodSecurityPolicy:為所有創建的Pod提供應用各種安全機制的方法。我們將在本系列的下一篇文章中對此進行進一步討論,但是現在確保啟用此admission controller非常重要,否則我們的安全策略將無法應用。

  • NodeRestriction:用於管理kubelet必須的集群資源的訪問權限,下麵將詳細介紹。

  • ImagePolicyWebhook:允許為Pod的容器定義的鏡像,通過外部“鏡像驗證器”(例如Image Enforcer)檢查漏洞。 Image Enforcer[2]基於Open Policy Agent(OPA)[3],與開源漏洞掃描程式Clair配合使用。

Dynamic admission control是Kubernetes中相對較新的功能,相對靜態插件化admission control機制提供更大的靈活性。它是通過admission webhooks和基於控制器的初始化實現的,並且只要社區解決方案達到足夠成熟的水平,就可以為集群安全做出很大貢獻。

 

Kubelet

 

Kubelet是在集群中的每個節點上運行的代理,負責它所在節點上的所有與Pod相關的活動,包括啟動/停止和重新啟動Pod容器,報告Pod容器的運行狀況等等。在API服務器之後,當涉及到安全性時,kubelet是下一個要考慮的最重要的集群組件。
訪問Kubelet REST API
kubelet在端口10250和10255上提供小型REST API。端口10250是讀/寫端口,而10255是具有API端點子集的只讀端口。
提供對端口10250的不受限制的訪問是危險的,因為可以在Pod的容器內執行任意命令,以及啟動任意Pod。 同樣,這兩個端口都提供對有關Pod及其容器的潛在敏感信息的讀訪問權,這可能會使工作負載容易受到攻擊。
為了防止潛在的危害,應通過設置kubelet的配置–read-only-port=0來禁用只讀端口。但是,端口10250需要可用於度量收集和其他重要功能。應仔細控制對此端口的訪問,因此我們將討論關鍵的安全配置。
客戶端認證
除非特別配置,否則Kubelet API對來自客戶端的未經身份驗證的請求是開放的。因此,配置一種可用的身份驗證方法非常重要;X.509客戶端證書,或具有包含bearer令牌的授權頭的請求。
對於X.509客戶端證書,需要使CA bundle的內容對kubelet可用,以便它可以在TLS握手期間驗證客戶端提供的證書。這是作為kubelet配置(–client-ca-file)的一部分提供的。
在理想的世界中,唯一需要訪問kubelet API的客戶端是Kubernetes API服務器。它需要訪問kubelet的API端點以獲取各種功能,例如收集日誌和指標,在容器中執行命令(想想kubectl exec),將端口轉發到容器等等。為了通過kubelet對其進行身份驗證,需要使用客戶端TLS憑據(–kubelet-client-certificate和–kubelet-client-key)配置API服務器。
匿名認證
如果您已經註意並配置了API服務器對kubelet API的訪問權限,那麼您可能會認為已經“完成工作”了。但事實並非如此,因為任何觸發kubelet的API的請求都不會嘗試使用kubelet進行身份驗證,這被視為匿名請求。預設情況下,kubelet會傳遞匿名請求以進行授權,而不是將其作為未經身份驗證而拒絕。
如果在您的環境中允許匿名的kubelet API請求是必不可少的,那麼就有了授權門,它可以靈活地確定API能夠和不能提供什麼服務。 但是,通過將kubelet的–anonymous-auth配置設置為false,完全禁止匿名API請求會更安全。通過這樣的配置,API向未經授權的客戶端傳回401 Unauthorized響應。
授權
通過授權對kubelet API的請求,再一次可能會違反預設的Kubernetes設置。對kubelet API的授權以兩種樣式之一運行;AlwaysAllow(預設)或Webhook。 AlwaysAllow樣式完全符合您的預期 – 它將允許所有通過身份驗證門的請求成功,這也包括匿名請求。
最好的方法是使用kubelet的–authorization-mode配置選項和webhook值,將授權決策轉移到Kubernetes API服務器,而不是將其打開。使用此配置,kubelet呼叫SubjectAccessReview API(它是API服務器的一部分)以確定是否允許主體發出請求。

 

限制Kubelet的力量

 

在較舊版本的Kubernetes(1.7之前)中,即使Node和Pod物件受另一個節點上運行的另一個kubelet的控制,該kubelet也具有對所有Node和Pod API物件的讀寫訪問權限。他們還可以讀取Pod規範中包含的所有物件:Secret,ConfigMap,PersistentVolume和PersistentVolumeClaim物件。換句話說,一個kubelet可以訪問和控制它不負責的眾多資源。這非常強大,並且在集群節點受損的情況下,損壞可能會迅速升級到相關節點之外。
節點授權
出於這個原因,專門為kubelet引入了節點授權樣式,目的是控制其對Kubernetes API的訪問。 節點授權器限制kubelet讀取與kubelet相關的那些物件上的操作(例如Pod,節點,服務),並對Secrets,ConfigMap,PersistentVolume和PersistentVolumeClaim物件應用進一步的只讀限制,這些物件與Pod系結到運行kubelet的節點。
NodeRestriction Admission Controller
將kubelet限製為與其相關的物件的只讀訪問權限是防止受損集群或工作負載的重要一步。但是,kubelet需要對其Node和Pod物件進行寫訪問,以此作為其正常功能的一種方式。為了實現這一點,一旦kubelet的API請求通過節點授權,它就會受到NodeRestriction Admission Controller的約束,該控制器限制了kubelet可以修改的Node和Pod物件(它自己的)。為此,kubelet用戶必須是system:node:,它必須屬於system:nodes組。當然,它是kubelet用戶的nodeName組件,NodeRestriction Admission Controller使用它來允許或禁止修改Node和Pod物件的kubelet API請求。接下來,每個kubelet應具有唯一的X.509證書,用於向API服務器進行身份驗證,subject的Common Name表示用戶,而組織則表示該組。
同樣,這些重要的配置無法自動完成,而且API服務器在啟動時需要將Node添加至—authorization-mode config選項的插件清單,並以逗號隔開;同時,NodeRestriction需要由—enable-admission-plugins選項在準入控制器清單內進行指定。

 

最佳實踐

 

特別需要強調的是我們只改寫了集群層的安全考慮因素的子集(儘管是重要的),如果你認為這聽起來非常令人生畏,那就不要擔心,因為有幫助在手。
與為基礎架構層的組件(如Docker)創建基準安全建議的方式相同,這個建議也適用於Kubernetes集群。互聯網安全中心(CIS)已為集群的每個組件編製了一套完整的配置設置和檔案系統檢查,並以CIS Kubernetes Benchmark[4]的形式發佈。
您可能也有興趣知道Kubernetes社區已經開發了一個開源工具,用於審核Kubernetes集群與基準測試Kubernetes Bench for Security[5]。它是一個Golang應用程式,支持許多不同的Kubernetes版本(1.6以上),以及不同版本的基準測試。
如果您認真對待集群的正確保護,那麼必須使用基準作為合規性的衡量標準。

 

總結

 

顯而易見,採取預防措施來保護具有適當配置的集群對於保護集群中運行的工作負載至關重要。雖然Kubernetes社區非常努力地提供所有必要的安全控制來實現其安全性,但由於歷史原因,一些預設配置忽略了最佳實踐。如果我們忽視這些缺點,將會帶來危險,所以我們必須在建立集群或者當升級到提供新功能的新版本時,由我們自己負責來處理這些缺點以縮小差距。
我們在這裡討論的一些內容為下一層鋪平了道路,我們利用配置的安全機制來定義和應用安全控制,以保護在集群上運行的工作負載。下一篇文章的名字叫做《Kubernetes集群安全最佳實踐》。
相關鏈接:
  1. https://www.vaultproject.io/

  2. https://github.com/open-policy-agent/contrib/tree/master/image_enforcer

  3. https://www.openpolicyagent.org/

  4. https://www.cisecurity.org/benchmark/kubernetes/

  5. https://github.com/aquasecurity/kube-bench

原文鏈接:https://blog.giantswarm.io/securing-the-configuration-of-kubernetes-cluster-components/

已同步到看一看
赞(0)

分享創造快樂