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

管理Kubernetes容器工作負載的安全性

這是題為《Securing Kubernetes for Cloud Native Applications》系列文章的最後一篇,這個系列文章中,我們討論了構成Kubernetes集群每個層的安全性方面的內容。在終結篇中,我們將討論容器工作負載本身的安全性。我們如何確保容器內容的完整性?我們如何知道容器內部實際上是什麼?讓我們從Secrets(秘鑰)開始。
保護Secrets

 

通常,在Kubernetes集群上運行的雲原生應用程式需要訪問敏感信息,並且需要提供Secrets以響應來自托管該信息的系統的查詢。Secrets可以是任何東西,但通常是密碼,X.509證書,SSH密鑰或OAuth令牌。我們可能想要採用簡單的路徑並將Secrets儲存在容器的鏡像中,以便在需要時可以隨時使用它。然而,如果我們這樣做,它可能會“淚流滿面”。撇開這種方法的脆弱性,更重要的是,將Secrets暴露給不應該暴露的物體的可能性將是巨大的。鏡像定義通常需要向廣大受眾提供,並且經常由原始碼控制系統管理,這可能潛在地導致Secrets的無意暴露。有一個被廣泛接受的格言,Secrets應始終保持在容器鏡像之外。這也遵循將容器配置保留在容器之外的Twelve-Factor App方法,允許我們為不同的標的環境使用不同的Secrets,同時為每個環境使用相同的容器鏡像。
這引出了一個問題:我們如何為在Kubernetes集群中運行的容器化應用程式提供Secrets? 由於它們的敏感性,Kubernetes提供了一個專用的API資源物件來處理Secrets,稱為(不出所料)Secret。然後,可以在需要訪問它們的Pod的Spec中取用封裝在Secret物件中的秘密資料:最好是通過卷裝入,而不是通過環境變數。
重要的是要確保對Secret的訪問嚴格限於那些需要使用它的物體(用戶和Pod),它不是通過網絡未加密傳輸的,並且當儲存在磁盤上時(靜止狀態)它是不可訪問或可讀的。 在之前的文章中,我們瞭解瞭如何使用身份驗證和授權(RBAC)控制對API物件(如Secrets)的訪問,以及使用TLS加密集群組件之間的通信的需求。這滿足了其中兩個原則,包括配置節點授權和kubelet通過API訪問Secret的場景,但是需要確保Secret在靜止狀態時無法訪問或可讀。

 

靜態加密

 

與所有API物件一樣,Secrets儲存在Kubernetes的分佈式狀態資料庫etcd中,只需用base64編碼。實際上,這使得有權訪問etcd的人可以使用Secrets,因此應該小心控制對etcd的訪問,並且應該使用TLS對etcd實體之間的通信進行加密。然而,在靜止狀態時,當etcd將其資料庫寫入磁盤時,Secrets以未加密的方式儲存,易受未經授權訪問主機檔案系統的任何人的攻擊。
幸運的是,可以使用–experimental-encryption-provider-config引數配置API服務器以加密Secret物件(或任何其他資源物件),該引數指定配置檔案的位置,該檔案確定物件將被如何加密。本質上,API服務器使用在配置檔案本身(通常是AES-CBC加密)中提供的密鑰,或者由行程外密鑰管理服務(KMS)提供程式(如Azure)對物件進行加密/解密,亦或者密鑰保管庫或AWS KMS。 如果使用配置檔案中定義的本地密鑰,確保檔案具有適當限制的權限非常重要。
使用外部Secrets儲存
使用Kubernetes Secrets API和用於加密靜態Secrets的機制可能足以滿足您組織的風險控制,但如果您的要求超出Kubernetes提供的要求,則可以使用更安全的解決方案。
Hashicorp的Vault是一個完全專註於Secrets管理的解決方案,包括創建,儲存,撤銷,輪換,生命周期(租賃)和範圍。在發出客戶端可用於訪問儲存的Secrets的令牌之前,Vault要求客戶端對其中一種身份驗證方法進行身份驗證。令牌包含定義客戶端可以訪問和不能訪問的策略。
對於Kubernetes,Vault具有特定的身份驗證方法,該方法依賴於與Pod的服務帳戶關聯的令牌。當Pod嘗試使用Vault進行身份驗證時,Vault會訪問API服務器的TokenReview API,以便驗證令牌。經過身份驗證後,Vault會向Pod發出一個令牌,其中包含服務帳戶的相關範圍。這使得Pod能夠在令牌的租約期間安全地檢索Secrets。
鏡像內容
我們知道在鏡像中儲存Secrets是禁忌,但在容器鏡像中還應該註意什麼呢? 這是一個引出許多不同意見的主題,但一個不可避免的事實是,您添加到鏡像越多,利用從鏡像派生的容器的機會就越多。
最小化鏡像
在理想的世界中,我們可以使用應用程式二進制檔案以及二進制檔案所依賴的任何相關依賴項來創建鏡像。事實上,沒有什麼可以阻止我們通過使用scratch作為FROM Dockerfile指令的引數來省略鏡像(我們構建我們自己的鏡像的鏡像),並將靜態鏈接的二進制檔案複製到鏡像中。可能沒有其他依賴項,在這種情況下,鏡像將包含單個檔案,以及一些描述容器如何運行的元資料。這對於鏡像分發速度(鏡像倉庫的推/拉)非常有用,並且可以顯著減少派生容器內的攻擊面。
基礎鏡像
然而,這可能並不總是可行或不實際,在這種情況下,我們需要警惕我們對基礎鏡像的選擇。最好的方法是構建你自己的基礎鏡像,因為你不依賴於第三方製作的基礎鏡像——如果你已經製作了鏡像,你就知道其中的確切內容。然而,製作你自己的基礎鏡像是有代價的——這是一個在內容維護方面需要相當大的努力的過程,這可能使它變得令人望而卻步,並且如果做得不好,可能會使你的鏡像不那麼安全。
然後,下一個最佳方法是使用操作系統供應商支持的鏡像,或者使用由社區策劃的Docker Hub註冊表中的官方鏡像庫。如果您的組織使用基於訂閱的分發(例如RHEL或SLES),則可能適合使用您信任的內容,利用所提供的支持,並使用這些供應商提供的鏡像。
切勿盲目使用您之前未經過審查的不受信任來源的鏡像,尤其是在生產環境中。
鏡像掃描
無論您從何處獲取鏡像,最終您都將依賴該鏡像內容的完整性。但是,我們永遠無法保證我們創建或使用的軟體沒有漏洞,這適用於我們使用的鏡像內容。例如,Bash二進制檔案中的Shellshock錯誤在2014年發現之前隱藏了25年,許多Docker鏡像自動包含Bash二進制檔案!這意味著我們需要瞭解現有鏡像中可能存在的漏洞,甚至是那些已經用於在Kubernetes集群中派生運行容器的漏洞。
檢測鏡像中的這些漏洞是一個非常重要的問題,但是有許多工具已經出現以應對問題。我們在之前的文章Clair中提到了一個備受推崇的開源示例,它是容器鏡像的靜態漏洞分析器。無論是開源世界還是商業解決方案,如JFrog Xray,都有很多替代方案。一個有趣的免費鏡像掃描工具是Aqua Security的MicroScanner,它允許您在構建鏡像時掃描鏡像。
鏡像掃描對於保持容器工作負載的安全至關重要,並且可以確保您的鏡像定期通過信譽良好的工具進行掃描,因此請花時間評估滿足您需求的最佳解決方案。
提供鏈保證
如果我們能夠在構建容器鏡像之前確保構成容器鏡像的組件提供鏈的完整性,那就更好了。它永遠不會消除定期和一致地掃描我們的鏡像是否存在漏洞的需要,但是我們越早發現問題,他們越不可能通過網絡進入生產工作負載的鏡像。
Snyk幫助識別和修複應用程式依賴項中的漏洞,而Grafeas和in-toto通過應用CI/CD管道的安全原則和策略來幫助保護整個提供鏈。

 

鏡像起源

一旦我們確定我們打算用於容器工作負載的鏡像內容合理,我們就應該對我們的工作負載是安全的有很大的信心。然而,如果我們允許隨機鏡像用於容器,或者如果我們允許自己被欺騙使用的鏡像不是我們認為的那樣,那麼這種信心就會破滅。出於這個原因,通過強制控制可以使用哪些鏡像,從哪些特定來源檢查圖像的來源,並檢查鏡像是否是它看起來是最符合我們利益的。這是另一個難以解決的問題。
鏡像策略
確保起源的一種方法是定義使用定義Pod容器的鏡像的策略。例如,我們可能希望通過摘要而不是標記來專門取用鏡像,這將確保我們可以使用非常特定的鏡像版本。標簽是可變的,這意味著在一段時間內,鏡像標簽可以表示完全不同的鏡像內容。然而,鏡像的摘要對於其內容是唯一的,這意味著我們可以確定我們正在處理已知內容的鏡像。另一個策略示例可能是我們希望確保只使用儲存在位於組織防火牆範圍內的鏡像倉庫中的鏡像。無論要求是什麼,重要的是能夠強制執行我們定義的策略,這樣我們就不會最終使用我們不應該使用的鏡像。
為此,Kubernetes有一個內置的ImagePolicyWebhook許可控制器,它依賴於外部後端來授權使用為Pod容器定義的鏡像。如果配置正確——在允許Pod進入群集之前——後端將發送一個ImageReview物件,其中包含容器鏡像的詳細信息,根據其配置的策略允許或禁止容器鏡像。
儘管在Kubernetes中可以輕鬆獲得鏡像策略的機制,但是後端實現很少,並且它在很大程度上是未使用的功能。相反,更多通用動態許可解決方案傾向於被使用,其中可以實施鏡像策略,以及與Pod配置的其他方面相關的策略。一種越來越流行的定義動態接納策略的技術是利用開放策略代理(OPA),這是一個實現通用策略引擎的雲原生計算基礎(CNCF)專案。OPA通過在授權客戶端(在本例中為Kubernetes)提供的資料的背景關係中評估以其自己的語言Rego定義的策略——然後基於評估的策略傳回二進制允許/禁止結果。基於OPA的準入控制器的示例是kubernetes-policy-controller。
可信鏡像
雖然我們可以確保我們使用策略只從受信任的位置下載鏡像,但我們不能斷然說我們下載的是我們認為的那麼安全。我們可能信任容器鏡像的作者,並且基於該信任,我們可能想要將鏡像用於Pod的容器。但是,我們沒有辦法確保作者的鏡像沒有被篡改,在他們發起推送該鏡像到鏡像倉庫之間,到我們完成從該鏡像中拉出該鏡像的時刻。我們應當考慮如何安全地更新軟體,這是一個普遍公認的問題。
更新框架(TUF)是由CNCF托管的規範,系統和專案,用於保護打包軟體更新的分發。 TUF規範描述了一種允許發佈者對其打包內容進行數字簽名的系統,以便消費者可以驗證相同內容的完整性和來源。Notary——另一個CNCF專案,是TUF的開源實現,允許我們為容器鏡像建立這種起源鏈接。
Docker引擎可以配置為將鏡像推送到具有支持的Notary服務器和簽名者(Docker Content Trust)的鏡像倉庫,並從中提取鏡像,但Kubernetes沒有抽象的用戶界面,這使得它很難使用。它本質上也是二進制的,要麼所有鏡像都需要信任,要麼都不需要信任。Portieris是一個開源的Kubernetes準入控制器,在Kubernetes集群中實現與Notary的鏡像內容信任時,允許更小細粒度的方法。策略在ImagePolicy或ClusterImagePolicy物件中定義,該物件允許為特定鏡像儲存庫啟用內容信任,包括要求鏡像應由特定可信簽署者簽名。當在Kubernetes集群中使用容器鏡像時,這為應用內容信任時提供了更大的靈活性。
自動化
在本文中,我們一直在討論在整個工作流程中考慮安全性的必要性,而不僅僅是在部署時。讓我們明確指出安全性需要“向左移”,並且與構建,測試和可觀察性一樣,也是CI/CD管道的一部分。 它需要被事先處理而不是事後的想法,並且需要關註過程和文化。
總結

 

這是題為《Securing Kubernetes for Cloud Native Applications》系列文章的最後一篇文章,我們講了很多內容。我們已經看到安全性需要仔細考慮並應用於包含Kubernetes集群的堆棧中的所有層,這不僅可以確保我們涵蓋安全的各個方面,還可以為我們提供“深度防禦”所需的冗餘。我們還看到,明智地應用最佳實踐安全控制使我們能夠在管理對敏感資源的訪問時採用“最小權限原則”。最後,我們已經討論了在部署之前,安全性需要如何遍及整個工作流程,而不是它是最後一步的活動。
安全性很難,但並非不可能,它應該與製作一流的雲原生應用程式的其他因素一樣受到關註。一定要投入必要的技能來做到公正,或者與已經進行了投資的組織合作,並獲得大規模生產Kubernetes集群所帶來的實際見解。
原文鏈接:https://blog.giantswarm.io/managing-the-security-of-kubernetes-container-workloads/

 

赞(0)

分享創造快樂