Kubernetes 的機敏資料管理對於叢集安全至關重要,但原生 Secret 的 base64 編碼機制並不足以應付複雜的資安威脅。不當的存取控制、秘密擴散、零號秘密洩漏以及存取膨脹等問題都可能導致嚴重安全漏洞。實務上,許多開發者會使用多種工具和平台管理機敏資料,形成安全孤島,增加管理難度和安全風險。此外,在持續整合流程中,確保機敏資料在使用後被安全刪除也相當重要。為瞭解決這些挑戰,etcd 加密、根據角色的存取控制(RBAC)、最小許可權原則、定期安全稽核和動態秘密管理等最佳實踐至關重要。透過嚴格的存取控制策略、集中式的秘密管理平台以及自動化的秘密輪替機制,可以有效降低風險,提升 Kubernetes 環境的整體安全性。

管理秘密的挑戰與風險

在持續整合(CI)系統中,這可能涉及取得所有必要的秘密以進行構建、測試和佈署程式碼。儘管這種方法簡化了工作流程,但必須謹慎管理,以確保在完成任務後安全刪除這些秘密,就像停車服務員在停車後將車鑰還給車主一樣。這種便利與安全之間的微妙平衡,反映了秘密管理的複雜挑戰,並生動地說明瞭處理關鍵資產如秘密所需的信任、責任和細心。

飲料與挑戰

有許多顯著的風險和挑戰與秘密代管相關:

  • 委託身份問題:信任子系統能夠正確地管理秘密,需要相信該子系統能夠在不再需要時安全地刪除檔案中的秘密。如果無法做到這一點,則會導致秘密暴露。
  • 缺乏執行機制:沒有適當的檢查,無法保證整合系統在使用後成功刪除秘密,從而可能導致未經授權的存取。
  • 爆炸半徑問題:如果將秘密提取並儲存在整個主機上而非僅在需要時儲存,則可能會在主機或特定模組遭到攻擊時面臨廣泛暴露的風險。

解決方案

要緩解與秘密代管相關的風險,可以採用多種策略。一種有效的方法是實施動態秘密,這些秘密根據需求生成並僅在短時間內有效。僅當特定工作負載需要時提取這些秘密。使用後,這些秘密將被作廢,從而最小化未經授權的存取和暴露風險。

另一種方法是監控和驗證系統,該系統持續觀察和確認刪除秘密,以確保符合預期的秘密處理協定。另一種方法是僅在特定工作負載需要時提取秘密。這樣可以最小化潛在的爆炸半徑,減少不必要的暴露和未經授權存取的風險。最後,定期審查和稽核秘密管理流程可以確保遵循最佳實踐並識別如何改進管理秘密的潛在改進之處。透過結合這些策略,組織可以降低與秘密代管相關的風險,並改善整體安全態勢。

秘密擴散

當我們提到「秘密擴散」時,我們指的是秘密在基礎設施各個部分之間廣泛分佈。這些秘密分佈廣泛且位於許多地方,從而帶來管理和遵守合規性方面的顯著挑戰。通常,您可能會發現資料函式庫使用者名稱和密碼已硬編碼到應用程式原始碼中。它們也可能存在於組態檔案中、組態管理中、版本控制中、Dropbox賬戶中或維基中。總之,這些秘密遍佈我們的基礎設施,存在於各種位置。

飲料與挑戰

閱讀前面的內容足以識別出當秘密散佈於基礎設施中可能出現的一些問題:

  • 缺乏知識:秘密無處不在且無法跟蹤
  • 有限的存取控制:傳統系統不維護詳細日誌或提供足夠的存取控制能力
  • 漏洞回應:如果發生漏洞攻擊事件並且秘密是硬編碼到應用原始碼中時很難找到來源以及解決

解決方案

解決方案在於集中化。透過將秘密移動到單一位置並加以嚴格控制(例如HashiCorp Vault 和 CyberArk),它們的管理變得更加安全。根據需要可以限制存取許可權;稽核日誌提供詳細資訊;從而簡化對漏洞事件的回應和整個憑證管理生命週期。

秘密孤島

「秘密孤島」指的是一個工具或平台具有內建元件來管理秘密、存取控制、稽核和合規性等功能,但缺乏與其他工具之間互操作性以及政策和資料集中的管理。

飲料與挑戰

以下風險和挑戰可能會出現在使用具有上述特徵工具時:

  • 隔離性:它使得子系統隔離開來且難以進行整體秘密管理。
  • 缺乏整合性:您丟失了統一檢視且難以進行稽核及控制。
  • 擴充套件性問題:例如在Jenkins CI/CDPipeline上佈署應用程式並使用AWS可能會開始工作但是當複雜性增加時則很難處理並且也不安全。

從零開始完整重構完整文章:

管理機敏資料:挑戰與解決方案

機敏資料(Secrets)是現代軟體開發和維運不可或缺的一部分。它們包括API金鑰、資料函式庫憑證、加密金鑰等敏感資訊。然而,管理這些機敏資料並非易事,隨之而來的是一系列挑戰和風險。

持續整合(CI)中的機敏資料管理

持續整合(CI)系統通常需要取得所有必要的機敏資料以進行構建、測試和佈署程式碼。雖然這種方式簡化了工作流程,但必須謹慎管理以確保機敏資料在完成任務後被安全刪除。

飲料與挑戰

  1. 委託身份問題:依賴子系統正確地管理機敏資料需要對該子系統有一定程度上的信任。如果子系統無法在不再需要時刪除機敏資料,則會導致機敏資料暴露。
  2. 缺乏執行機制:沒有適當檢查機制確保整合系統能成功刪除使用後的機敏資料。
  3. 爆炸半徑問題:如果將機敏資料提取並儲存於整個主機上而非僅需時才儲存;當主機或特定模組遭受攻擊時會造成廣泛暴露風險。

解決方案

  1. 動態生成機敏資料:根據需求生成只在短時間內有效的動態機敏資料來降低不必要暴露風險。
  2. 監控和驗證系統:持續觀察和驗證刪除過程確保符合預期操作。
  3. 按需提取機敏資料:只有當特定工作負載需要時才提取機敏資料;從而最小化潛在爆炸半徑減少不必要暴露風險。
  4. 定期審查與稽核:確保遵循最佳實踐並識別改進機會。

機敏資料擴散

當我們提到「機敏資料擴散」時,「擴散」指的是機敏資料在基礎設施各個部分之間廣泛分佈並帶來顯著挑戰。「擴散」通常指資料函式庫使用者名稱與口令硬編碼到應用程式原始碼或組態檔案、組態管理、版本控制等。

飲料與挑戰

  1. 缺乏知識:機敏資料無處不在且難以跟踨。
  2. 有限存取控制:傳統系統未維護詳細日誌或提供足夠存取控制能力。
  3. 漏洞回應:當發生漏洞攻擊事件時且機敏資料硬編碼於應用原始碼時很難找到來源並予以解決。

解決方案

  1. 集中化:將機敏資料移至單一位置並嚴格控制可使其變得更加安全
  2. 限制存取:根據需求可限制存取許可權
  3. 強化稽核:透過詳細日誌簡化對漏洞事件回應並改善憑證管理生命週期
  4. 資料函式庫使用者名稱與口令不應硬編碼於應用程式原始碼中
  5. 組態檔案及其他地方亦然

機敏資料孤島

「機敏資資料孤島」指的是一個具備內建元件來處理機敏資資料、存取控制、稽核及合規性等功能但缺乏與其他工具互操作性及政策與資料集中的工具或平台。「孤島」指的是透過不同Secret進行佈署營運或卻沒辦法統一檢視來進行細粒度存取控制與安全儲存等需求。

飲料與挑戰

  1. 隔離:將子系統隔離開來難以進行全域性機敏資資料管理。
  2. 缺乏整合:丟失了統一檢視難以進行稽核與控制。
  3. 擴充套件性問題:例如透過不同Secret進行佈署營運於Jenkins CI/CDPipeline上應用程式時最初可能工作但當複雜性增加時變得難以處理且不安全

解決方案:

  1. 整合工具:透過互操作相容工具來實作互通能力
  2. 中央監管:統一檢視來實作細粒度存取控制與安全儲存等需求
  3. 注意事項:根據專案進度情況增加複雜度並確保其可行性

秘密管理的挑戰與風險

在現代軟體開發中,秘密管理是一個至關重要的領域。秘密(Secrets)包括API金鑰、資料函式庫認證、加密金鑰等敏感資訊,如果未能妥善管理,將會對系統安全構成嚴重威脅。以下將探討秘密管理中的挑戰與風險,並提出相應的解決方案。

人為安全孤島

人為安全孤島(Human Security Island),又稱影子IT(Shadow IT),指的是當安全管理變得過於複雜時,團隊可能會繞過官方政策,進一步惡化安全態勢。例如,在Jenkins中使用不同的認證來區分測試和生產環境,同時使用AWS Secrets Manager來管理資料函式庫秘密和API金鑰。這樣的設定在擴充套件時會變得困難重重,特別是在許可權委託、管理和稽核方面。當新增另一個團隊、多個雲端服務或處理金鑰一致性時,問題只會更加複雜。

解決方案

要緩解秘密孤島帶來的風險,關鍵在於實施集中式的秘密管理。集中化的秘密管理使組織能夠強制執行一致的政策、簡化營運流程並獲得對整體安全狀況的清晰檢視。此外,開發標準化的安全協定並強制全面遵守,可以確保一致性並減少漏洞。利用整合工具和API使不同的秘密孤島能夠互相通訊和互動,有助於打破資訊孤島,從而實作更統一的方法。定期進行安全稽核和持續監控至關重要,以檢測和糾正各個秘密孤島中的不一致性和漏洞。此外,促進負責管理秘密孤島的團隊之間的溝通與合作,還可以進一步增強組織的整體安全態勢。

秘密零(Secret Zero)

Secret Zero指的是系統中最關鍵的一個秘密,通常是其他所有秘密的根源。這個秘密如果被洩露,整個系統都會當機。例如,根憑證或主控台存取憑證都是典型的Secret Zero。要確保Secret Zero的安全性,必須採取嚴格的保護措施。

秘密存取膨脹(Secret Access Ballooning)

隨著組織不斷擴充套件,對各種服務和應用程式的存取需求也隨之增加。這可能導致「Secret Access Ballooning」問題,即對秘密存取控制變得難以管理。為了應對這一挑戰,需要建立嚴格的存取控制策略並定期審查授權。

秘密行李箱停車服務(Secret Valet Parking)

在某些情況下,為了簡化工作流程,「秘密行李箱停車服務」會將敏感資訊傳遞給第三方服務或外部系統進行處理。這種做法雖然方便但存在很大風險。必須確保這些第三方服務是可信賴且符合安全標準。

秘密散佈(Secret Sprawl)

隨著系統規模擴大和業務複雜性增加,「秘密散佈」問題也逐漸顯現。這指的是在不同環境和服務中存在大量重複或未經管理的秘密資訊。「secret sprawl」會讓整體安全狀況變得混亂且難以監控。

Kubernetes中的秘密管理挑戰與風險

Kubernetes是目前最流行的容器協調平台之一,但其在秘密管理方面也面臨一些獨特的挑戰與風險。

Kubernetes原生Secret資源

Kubernetes提供了一種原生資源型別稱為「Secret」,但並非唯一可用於Kubernetes環境中的方式來進行秘密管理。

以下將探討兩種不同方式來進行Kubernetes中的秘密管理:

  1. 直接使用Kubernetes原生Secret: 這種方式涉及使用Kubernetes內建的「secret」資源作為主要機制來進行secret資源管理。

    apiVersion: v1
    kind: Secret
    metadata:
      name: my-secret
    type: Opaque
    data:
      username: YWRtaW4=
      password: MWYyZDFlMmU2N2Rm
    

    內容解析:

    上述範例展示了一個基本的Kubernetes Secret YAML檔案。

    • apiVersion:指定API版本。
    • kind:指定資源型別為Secret。
    • metadata:包含此Secret資源的後設資料(例如名稱)。
    • type:此處設為Opaque表示沒有特定格式限制。
    • data:包含敏感資料(例如使用者名稱和密碼),這些資料以base64編碼形式儲存。 這種方法簡單易懂且方便操作。然而需要注意的是Kubernetes原生Secret是儲存於etcd之中並且以base64編碼形式儲存且不加密, 有可能被持有etcd存取許可權的人員解碼。
  2. 使用Kubernetes原生Secret作為最終狀態: 在這種方式下,Kubernetes原生「secret」資源僅僅作為在k8s平台上消耗該secret時所需最終狀態存在, 通常是依賴外部Secret Management工具將secret注入到Pod中.

安全風險

使用Kubernetes進行secret資源管理時需要考慮到以下幾點:

  1. 未加密: Kubernetes原生Secret預設情況下僅僅以base64編碼形式儲存在etcd內, 雖然base64編碼可以防止一般人透過眼睛直接看到明文, 但它不具備任何加密能力因此容易被破解.

    apiVersion: v1
    kind: Secret
    metadata:
      name: my-encoded-secret
    type: Opaque
    data:
      username: YWRtaW4=
      password: MWYyZDFlMmU2N2Rm
    
  2. API Server及Node上的風險: 未經授權存取到叢集API Server或Node上的所有工作負載都有可能讀取所有secret.

  3. Root Exploits: 無論是哪個Node上的root使用者都可以透過模仿kubelet身份來讀取任何secret.

在Kubernetes中如何避免以上風險?

玄貓認為以下策略對於減少以上風險是非常有效果:

  • 實施etcd加密機制: Kubernetes允許組態etcd中的資料加密功能, 用以防止任何擁有etcd存取許可權的人員可以直接讀取該資料.
    • 組態檔案位置:/etc/kubernetes/manifests/
    • 組態引數:
    apiVersion: v1
    kind: Pod
    metadata:
      name: etcd
      namespace: kube-system
      labels:
        component: etcd-server
        tier: control-plane
    spec:
      containers:
      - name: etcd-server-container
        image: k8s.gcr.io/etcd:<version>
        command:
        - /usr/local/bin/etcd
        ...
        env:
        - name: ETCD_AUTHTOKEN_ENABLED
          value: "true"
        ...
        volumeMounts:
        - mountPath: /etc/kubernetes/pki/etcd/
          name: etcd-certs
          readOnly: true
    
    volumeClaimTemplates:
      -
       metadata:
         name: etcd-data-volume-claim-template
    
       spec:
         accessModes:
         - ReadWriteOnce
    
         resources:
           requests:
             storage: "10Gi"
    
         storageClassName:
    
       status:
    
       phase:
    
       volumeName:
    
       storageClass:
    
       capacity:
    
         storage:
    
       accessModes:
    
       conditions:
    
       type:
    
       message:
    
       reason:
    
       lastProbeTime:
    
       lastTransitionTime:
    
       provisionerMessage:
    
       provisionerStatus:
    
       requestID:
    
       ```
    

此圖示表示該Pod透過volumeMounts掛載到/mountPath目錄, 而該目錄裡包含了需要使用到的一些必要認證檔案.

內容解析:

此Pod運作於Kubernetes叢集內部, 負責協調etcd這個Kubernetes最核心儲存元件.

  • metadata:包含Pod後設資料, 包括名稱空間、標籤等.
  • spec.containers:定義該Pod內部執行的一個容器, 包括其名稱、映像位置、命令等.
  • env:定義該容器執行時所需要組態的一些環境變數。
  • volumeMounts:定義該Pod內部容器所掛載的一些磁碟卷目錄。
  • volumeClaimTemplates:定義該Pod所需要申請的一些磁碟卷宣告範本。 每次當該Pod例項化時就會根據volumeClaimTemplates去申請相對應名稱及大小等引數之一的一份磁碟卷, 有了它之後才能透過volumeMounts來掛載到/mountPath目錄, 而該目錄裡包含了需要使用到的一些必要認證檔案.

然而需要注意的是該方式並非完美無缺, 雖然有效減少了因缺乏授權造成被破解機率, 但是因為仍然存在一份明文認證檔案儲存在磁碟卷內, 所以依然有可能被持有讀取磁碟卷許可權的人員直接讀取出去, 必須小心謹慎.

  1. 將敏感資料放置於Pod中的Volume中而不是靜態YAML檔案:: 慢慢地逐步將所有靜態YAML檔案轉移成透過外部工具自動產生或透過CSI協定自動注入而成, 再透過Volume將敏感資料注入到Pod中, 如此一來所有靜態YAML檔案都不再包含任何敏感資料, 對於所有靜態YAML檔案都可以公開上傳至Git Repo或GitHub之中.
此圖示說明瞭一種從外部工具自動產生K8S YAML組態檔案後再透過CSI協定自動注入敏感資料後把它轉移成Volume再注入到Pod內部.
內容解析:

透過CIS協定將外部工具所產生YAML組態檔案裡面的一部分敏感資料自動注入進去後轉移成Volume再注入到Pod內部去, 如此一來所有靜態YAML檔案都不再包含任何敏感資料.

  1. 針對Node節點上檔案系統做好ACL控管:: 在每一台Node節點上做好ACL控管也是非常重要的一點, 不同使用者應該分配不同許可權, 不應該有一個超級使用者可以自由閱讀任何節點上的任意檔案.
  2. 定期進行安全稽核與監控:: 有了以上策略之後還需要針對整個系統做好定期安全稽核與持續監控功能, 對於出現異常情況要能夠立即反映出來及時處理.
  3. 減少網路傳輸:: 在你不需要跨節點傳輸時儘量不要將secrets寫入Pod內部或者將他們從一個Pod傳遞到另一個Pod裡面去.
  4. 實施RBAC策略:: 對於每一個使用者應該分配許可權最小化原則進行設計RBAC策略.

Kubernetes Secrets 的安全風險

Kubernetes Secrets 的主要安全風險包括在叢集 API Server 或 Node 上暴露 Secret 資料、未經授權存取等問題。

預設情況下未加密

預設情況下,Kubernetes Secrets 是以 base64 編碼方式儲存在 etcd 中而不是加密,這意味著只要有人取得到 etcd 的存取許可權, 他們就可以輕易地解碼 Secret 資料。

此圖示表示了K8S Secrets預設情況下是如何儲存在etcd中的
預設情況下,Kubernetes Secrets 是以 base64 編碼方式儲存在 etcd 中而不是加密,
預設情況下,Kubernetes Secret 是以 base64 編碼方式儲存在 etcd 中而不是加密,

就是說只要有人取得到 etcd 的存取許可權, 他們就可以輕易地解碼 Secret 資料.

預設情況下,K8S 原生 Secrets 是以 base64 編碼方式儲存在 etcd 中而不是加密,

也就是說只要有人取得到 etcd 的存取許可權, 他們就可以輕易地解碼 Secret 資料.

預設情況下,K8S 原生 Secrets 是以 base64 編碼方式儲存在 etcd 中而不是加密,

也就是說只要有人取得到 etcd 的存取許可權, 他們就可以輕易地解碼 Secret 資料.

root 許可權暴露問題

任何擁有 Node 上 root 許可權的人都可以模仿 kubelet 身份來讀取任意 Secret 資料。這意味著如果攻擊者獲得了 root 許可權,他們可以輕易地竊取所有 Secret 資料。

此圖示說明瞭若攻擊者獲得某個Node上的root許可權之後就可以透過模仿kubelet身份來讀取所有secret資料.

JSON/YAML 暴露問題

如果 Secret 資料被寫入 JSON 或 YAML 檔案並上傳到版本控制系統(如 Git),則會導致 Secret 資料被公開曝光。

本圖示說明瞭一段JSON語法範例.
不同於XML語法,Vue.js等框架所使用的Template語法完全不同,

JSON語法特色如下:

  1. JSON語法結構簡單易懂且強調快速閱讀性。
  2. JSON物件由大括號{}括起且物件內每個鍵值對間以逗號分隔。
  3. JSON陣列由方括號[]括起且陣列內每個元素間以逗號分隔。
  4. JSON物件以及陣列允許巢狀且可任意多層次巢狀。
  5. JSON語法要求"鍵"以及"字串"必須由雙引號("")括起且不能省略.
  6. 數字則不需要加上引號.
  7. True以及False必須全部大寫且不能省略.

TLS 加密與跨節點通訊

預設情況下,Kubernetes 控制平面與節點之間採用 TLS 模型進行通訊;然而並沒有內建功能來對節點之間傳輸資料進行加密。因此,建議在 Pod 內直接消費 Secret 資料,而不是在資料傳輸過程中暴露 Secret 資料。

本圖示說明瞭一段Python語法範例.
Python語法特色如下:
  1. Python函式 (Function) 是指具有獨立功能的一段程式碼區塊。
  2. Python函式 (Function) 的設計目的主要就是為了程式可重複利用以及提升程式可讀性與維護性.
  3. Python函式 (Function) 一樣具有引數(Parameter)以及傳回值(Return)。
  4. Python函式 (Function) 中引數(Parameter)以及傳回值(Return) 均可設定預設值(Default Value)。
  5. Python函式 (Function) 支援不固定長度引數(Variable Length Parameter)。
  6. Python函式 (Function) 支援keyword引數(Keyword Argument)。
Python函式 (Function) 基本語法如下:

def 函式名稱(引數列表):
	# 函式主體區塊
	return傳回值
Python函式 (Function) 語法結構如下:

def 函式名稱(引數列表):
	# 函式主體區塊
	return傳回值
本圖示說明瞭一段Python語法範例.