fbpx

HashiCorp Vaultㄧ保護星巴克 100,000 多台邊緣裝置的機密和身份

edge device

深入了解星巴克使用 HashiCorp Vault 為 100,000 多個零售邊緣裝置建構機密和身份管理功能的架構模式。

公司介紹

星巴克在北美擁有 500 多個商業授權和 16,000 家店面。這些店面都是單獨的個體,超過 100,000 台邊緣裝置分佈在數千個網路和商店中,而我們仍需要持續的保護和管理這些裝置。零售店中有各種各樣的計算用例,從銷貨點到溫度感測器以及中間所有的其他設備。

假設每台裝置僅運行 1 個應用程式。但如果不只運行一個程式,每個實體裝置都會有多個身份。這些身分都有不同的需求,我們不想花費 100 萬美元來保護 30 美元的資產,反之亦然。是場上缺乏邊緣環境設計的解決方案,即使有,也往往是環境建置後才部署,而不是一開始就考慮進去。Vault 無法避免這個問題,但是 Vault 的一些功能,可以幫助我們改善。

擴大 Vault 的規模

擴展 Vault 對我們的團隊來說是一個獨特的挑戰,因為我們不僅是 Vault 的新手,這也是我們在 Kubernetes 上使用 Terraform 建構的第一個大型平台。我們使用 Terraform 和 Helm ,從基礎設施和網路一直到 Vault 原則(policy)和身份。

在嘗試設計和建構平台的同時,讓團隊掌握所有新技術是一項挑戰。一個彈性和可擴展的基礎設施,簡化了大規模管理系統。
Kubernetes 提供我們擴展 Pod 以處理激增的負載的能力,而 Terraform 和 Helm 使我們能夠快速啟動新叢集、測試新功能或加入租用戶。
在我們的案例中,Vault Enterprise 有 2 個對彈性和可擴展性至關重要的功能:性能副本(performance replica)和災難修復(disaster recovery)叢集。 Vault 性能副本叢集是我們可擴展性設計重要的一環,主要有 3 個原因。

  • 它們為邊緣裝置提供了read-only 叢集,可以在不公開主要 Vault 叢集的情況下進行連接。
  • 它們提供水平擴展和區域負載平衡。
  • 透過過濾 Replication 以支援租用戶之間的實體隔離。

最後一個對我們來說非常重要,因為一些租用戶可能有 3 家商店,而另一些租用戶可能有 10,000 家。性能副本(performance replica)使我們能為龐大的租用戶提供他們自己的實體叢集,而不被其他租用戶所使用。

災難修復叢集對於滿足零售業的正常運行時間需求也至關重要。透過頻繁備份並建立修復的過程,Vault可以在沒有災難修復叢集的情況下安全的操作。但從服務彈性的角度來看,在已擁有所有關鍵資料的 warm 叢集中進行交換是很難的。在像零售業這樣需要持續正常運行時間的環境中,是一個重大的突破。但可擴展的基礎設施實際上是最容易的部分。 

Vault 在邊緣端點提供幫助

Vault 的設計為邊緣環境中的 DevSecOps 帶來極大價值。 Vault 具有非常靈活和可擴展的身份驗證方法和機密引擎secrets engines)。您可以使用 AppRoles 和 TLS 憑證等傳統方法以及 Azure AD 和 AWS IAM 等現代機器身份方法進行身份驗證。

它還支援廣泛的機密,從靜態機密到短期 PKI 憑證,再到動態資料庫和雲端訪問憑證。全部都是由 HashiCorp 和聚集在其堆棧周圍的大型社群建構和支援的。
最重要的是,您可以為您的用例建構自定義身份驗證和機密引擎,或者為尚未有官方認可的引擎的產品增加支援。過去,如果您需要管理 PKI 憑證、資料庫憑證、API 金鑰和密碼,則需要整合多個不同的系統才能有效的大規模管理所有機密。
管理所有系統的管理開銷十分龐大,甚至沒有解決您如何連接它們、輪替憑證以及提供安全、可稽核的訪問權限。
整個系統的設計理念是,憑證和機密應該是短暫的,並受到粒度的最小權限,以限制在攻擊中使用受損機密的可能性和影響。

這些身份識別的自動化機密流(secrets flows)可以成為有效且可擴展的零信任邊緣環境的主要貢獻者。為了實現這種靈活性,Vault 提供一個功能齊全的 REST API,可用在您的應用程式堆棧中建構無縫的自動輪換機密流。
Vault 平台中,所有功能都可以透過 API 完成。Vault agent 等工具增強了 API,這是一個主要的差異化功能,允許終端自動對 API 進行身份驗證以管理其機密。

如果在後端輪換靜態金鑰,agent 將自動進行更改。如果動態金鑰即將到期,agent 將輪換它。
Agent 還提供了一個快取 API,可以在邊緣環境中作為地端 Vault responder,並在與 Vault 叢集失去連接時提供一些彈性。

零機密困境(The Secret Zero Dilemma)

我們如何將單一身份識別引導到數十萬個邊緣裝置?我們稱之為“零機密困境”,這一切都歸結為「信任」。
在邊緣環境中,信任該裝置的唯一原因是因為我可以識別、管理、監控它,並在需要時將其變磚。
可擴展性是在邊緣解決零機密的最大挑戰。如果我需要為這 100,000 台裝置中的每台裝置提供單一憑證,則該過程必須全自動化,因為在這種規模下,任何人工參與都會使運營團隊超過負荷。

零機密模式(Secret Zero Patterns)

此外,由於我們有如此廣泛的用例和安全需求,我們需要一組可重複的模式來適應我們的各種用例。
在深入了解第一個零機密模式的細節之前,我想簡單解釋一下 HashiCorp 創建的稱為「響應封裝(response wrapping)」的構造。響應封裝是一種透過零信任網路將機密安全地傳遞給裝置的方法。

從 Vault 請求響應封裝的金鑰時,您將收到一個短暫的一次性使用令牌,而不是實際的金鑰。然後可以使用此令牌對 Vault 進行身份驗證,並從名為「cubbyhole」的臨時機密儲存中獲取實際的機密 ID。讓您透過提供短期存取器而不是實際金鑰,來限制金鑰在傳輸過程中被洩露的風險。它還使您能夠知道封裝令牌(wrapping token)在到達終端裝置之前是否被破壞,因為如果封裝令牌被嘗試解封裝兩次,則會觸發稽核事件。

協作器輪詢模式(The Orchestrator Poll Pattern)

它是唯一可以真正適應邊緣環境的 HashiCorp 參考架構。在許多模式中,我將假設邊緣環境中的裝置已經配置了角色 ID,作為映像過程的一部分。
一旦您的信任的協作器發現有一個需要機密 ID 的新裝置,它就可以從 Vault 請求一個封裝機密 ID(wrapped secret ID)並將其傳給裝置,然後裝置解封令牌並使用角色 ID 和機密 ID 登入到 Vault。這為我們提供了一個很好的動態流程,讓協作器頻繁輪換憑證,並讓我們利用協作器的身份連接到 Vault。

協作器會使用雲端或資料中心身份驗證方法,在此模式中,我們提供了比終端提供更好的保障。
缺點是許多協作器無法以這種方式與外部系統整合,如果可以,這種類型的緊密耦合可能是不良的。協調器的任何問題也可能產生後續影響,導致管理裝置上的 Vault 憑證錯過輪換和過期。

基於終端的索取模式(Client-Based Pull Pattern)

使用 Vault agent 作為 API 終端以保持一致性,但這可以由您的應用程式與 Vault API 的整合替換。
在基於終端的索取模式中,您受信任的協作器會在每台配置的裝置上安裝一個啟動包(bootstrapping package)。這包含 Vault Agent 和共享註冊 AppRole。AppRole 的作用域(scoped)是最小的,並且只能為該作用域內的其他裝置請求封裝機密 ID。

邊緣裝置透過註冊 AppRole 登入 Vault,並為所需的角色 ID 請求唯一的機密 ID。 Vault 將向裝置返回一個唯一的機密 ID,然後裝置將使用它登入 Vault 並訪問其機密。
這是一個不錯且簡單的模式,可以很好地適用於安全需求低或其他緩解控制的用例。它是動態和終端啟動的,讓您的憑證使用相對較短的存活時間 (TTL),並使終端能夠在憑證過期時自動修復。 它也比其他的模式更靈活,因為它不需要協作器的任何獨特功能或特性。只要您可以將程式碼部屬到裝置,您就可以使用這種模式。

然而,這也是這種方法的缺點。從安全角度來看,擁有一個廣泛的共享角色,可以用來承擔該範圍內任何其他裝置的身份,但從安全的角度來看,這並不是很好。您對邊緣裝置的身份缺乏保證,而且不可否認性( non-repudiation)幾乎是不可能的。註冊 AppRole 的作用域需要是最小的,並頻繁輪換,這在具有許多範圍和裝置的大規模環境中帶來一系列全新的挑戰。

批次模式(The Batch Pattern)

批次處理對一些人來說應該很熟悉,因為它是在多個 API 之間整合的常見模式。這裡,我們有一個按計劃運行的 cronjob,假設每小時運行一次。此作業向協作器查 Vault 憑證所信任的所有裝置列表。
然後,cron job 從步驟 1 中的裝置進行迴圈,並為每個裝置請求一個唯一的封裝機密 ID。一旦 Vault 返回封裝令牌,cron job 將使用協調器的 API 將這些令牌分配給每個裝置。

接著,協作器啟動一個啟動包,其中包括 Vault agebt 和封裝令牌。終端解封令牌以獲取機密 ID,然後登入 Vault 以請求機密。
您的 cron job 實際上只是一個小型 API 協調者,在機密經過這些工具時保護它們。
但是,這可能會影響大規模供應。如果您嘗試每天配置數千台裝置,則此 cron job 的 1 小時間隔可能會遇到嚴重的瓶頸。
這也往往會導致較長的金鑰 ID,因為您需要在系統中預留足夠的空間,以防止由於 cron job 的延遲或問題導致的停機。這也可能存在一些協作器的限制,因為並非所有協作器都有一個 API,可以讓您擷取和設置 metadata 或運行包(run package)。

信賴平台模組(Trusted Platform Module)

TPM(信賴平台模組)是一種標準化且便宜的硬體安全模組,在行動裝置和企業 PC 中變得越來越普遍。
TPM 有 3 個最相關的主要面向。第一個是一對公共密碼學金鑰(endorsement key pair)。將其稱為公開金鑰的“EK_pub”和私密金鑰的“EK_pri”。這是一對加密金鑰,在製造時印在晶片中,並且永遠不會改變。它提供了一種很好的機制,可以在裝置移動到不同位置、用戶、重新映像時在其整個生命週期內識別裝置。

第二個是儲存根密鑰(storage root key pair)。將其稱為公開金鑰的“SRK_pub”和私密金鑰的“SRK_pri”。當系統或用戶獲得 TPM 的所有權時會產生一對加密金鑰,並且在清除 TPM 時會輪換。此金鑰告訴我們裝置的所有權何時變更。
最後,TPM 可以用於憑證等安全的地端機密儲存,因此我們不必將它們保存在磁碟上。

第二個 Trusted Computing Group 連結是關於向 TPM 規格添加新金鑰的提案,該提案專門針對這些模式中可能感興趣的裝置身份和入口網站。

註冊閘道模組(The Enrollment Gateway Model Pattern)

在此模組中,您的協調器安裝包含 Vault agent 的啟動包、註冊金鑰、註冊終端,可以是服務,甚至只是一個簡單的腳本、可選擇在配置時未提供角色 ID。
註冊終端將透過向包含 EK_pub、SRK_pub、主機名、協作器 ID 和 Vault namespace的註冊閘道發送特徵(fingerprint)來請求 Vault 機密 ID。

接著,閘道器將針對協調器或 CMDB 驗證該特徵,以確保這些公開金鑰映射到具有我們的安全工具,並符合我們狀態檢查的管理裝置。
如果特徵驗證成功,註冊閘道將透過產生隨機 nonce 並使用 SRK_pub 對其進行加密,然後使用 EK_pub 再次對其進行加密。這使我們能夠驗證身份驗證裝置是否可以訪問私密金鑰,而無需離開 TPM。

TPM 將使用 EK_pri 和 SRK_pri 來解密 nonce,然後透過發送由 nonce 簽名的註冊金鑰來認證。
現在我們已經驗證了裝置的身份,並且它已經使用其私密金鑰進行身份驗證,註冊閘道可以從 Vault 請求一個封裝機密 ID 並將其傳遞給裝置。

裝置解封令牌並使用 AppRole 登入。顯然,這是一個更複雜的流程,但它提供了價值。我們仍然有一個很好的、動態的終端啟動流程,允許較短 TTL,而不需要協作器提供大量特定功能,並且我們獲得 TPM 更高品質的保障。
我們仍然有一個需要管理和輪換的作用域共享金鑰,但由於特徵驗證流程和狀態檢查,該金鑰相關的風險較低。
但是,我們確實需要特徵驗證的基礎設施,因此讓 CMDB 或協作器知道您裝置的 TPM 公開金鑰非常重要。

實驗模組(Experimental Pattern)

如果我們使用 TPM 直接對 Vault 進行身份驗證,可以免去複雜的中間層,不需要這些額外的整合點,也避免失效的風險。 
在這個流程中,我們的啟動包非常簡單。所需要的只是您的 Vault API 終端。邊緣裝置將使用與上一個範例相同的特徵直接向 Vault 發送 TPM 身份驗證請求。

然後,Vault 可以觸發協作器或 CMDB 以使用一組可插入式驗證器來驗證特徵。如果驗證檢查成功,Vault 將啟動前一個模組中描述的 nonce 驗證。
一旦裝置解密並返回 nonce,證明它擁有與公開金鑰相關聯的私密金鑰,Vault 就會發布一個令牌,然後該裝置可以請求它的機密。這是一個非常有趣的模組,因為它有可能完全繞過零機密交付。

只要您的配置過程從每台新裝置中擷取金鑰,並且您的協作器或 CMDB 在其整個生命週期中追蹤裝置,我們就可以使用 TPM 的硬體身份來建立和維護信任。
這也是一種完整的身份驗證方法,如果裝置被標記為受損或不合規時,它可以自動阻止對 Vault 進行身份驗證。
從工作流和基礎架構的角度來看,這也是複雜度最底且高可擴展性的方法,而不會犧牲密碼安全性。

缺點是程式碼複雜度非常高。這可以是內部建構和管理的自定義身份驗證方法,但通常不建議在正式環境這樣做,因為建構自己的身份驗證可能會出錯,而且除非你經常這樣做,否則工作量相當高。理想情況下,這將是 HashiCorp 官方批准和支援的身份驗證方法。

相關文章