2019-06-02
分類:後端
閱讀(429) 評論(0)
這是題為《Securing Kubernetes for Cloud Native Applications》系列文章的最後一篇,這個系列文章中,我們討論了構成Kubernetes叢集每個層的安全性方面的內容。在終結篇中,我們將討論容器工作負載本身的安全性。我們如何確保容器內容的完整性?我們如何知道容器內部實際上是什麼?讓我們從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。 如果使用配置檔案中定義的本地金鑰,確保檔案具有適當限制的許可權非常重要。
使用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/
朋友會在“發現-看一看”看到你“在看”的內容