Kubernetes 叢集的安全性至關重要,威脅建模是確保安全的重要步驟。本文不僅探討常見的威脅建模方法,如 STRIDE、PASTA 和 VAST,更深入分析 Kubernetes 環境中特有的威脅行為者,包含終端使用者、內部攻擊者和特權攻擊者,並說明這些攻擊者如何利用系統漏洞。理解 Kubernetes 元件間的互動關係,例如 kube-apiserver、etcd、kube-scheduler 等,是威脅建模的基礎。透過 DaemonSet 建立流程的案例,展示元件間的通訊流程及潛在安全風險。文章進一步說明如何應用最小許可權原則,利用 RBAC、網路策略、安全上下文和 Pod 安全策略等機制,限制各元件的存取許可權,降低安全風險並提升叢集的整體安全性。
Kubernetes威脅建模導論
產業通常採用以下幾種威脅建模方法:
- STRIDE:由微軟於1999年提出的威脅建模框架,涵蓋欺騙(Spoofing)、竄改(Tampering)、否認(Repudiation)、資訊洩露(Information Disclosure)、服務拒絕(Denial of Service)及許可權提升(Escalation of Privilege)六大威脅類別,藉此回答「系統可能出現哪些問題?」
- PASTA:以風險為中心的威脅建模流程,採用攻擊者視角,由業務及技術團隊共同制定以資產為核心的風險緩解策略。
- VAST:視覺化、敏捷且簡易的威脅建模方法,旨在將威脅建模整合至應用程式及基礎設施開發流程中,支援SDLC及敏捷軟體開發,提供對開發者、架構師、安全研究人員及業務主管等利害關係人皆有幫助的可行輸出結果。
除了上述三種方法外,業界還有其他威脅建模途徑,但STRIDE、PASTA和VAST是目前最常被採用的。
若威脅建模的範圍界定不清,此任務可能會無限期地持續下去。在開始識別生態系統中的威脅之前,必須清楚瞭解每個元件的架構和運作機制,以及元件之間的互動方式。
在前面的章節中,我們已經詳細探討了每個Kubernetes元件的基本功能。現在,我們將在探討Kubernetes生態系統內的威脅之前,先了解不同元件之間的互動關係。
元件互動關係
Kubernetes元件協同工作,以確保叢集內執行的微服務正常運作。舉例來說,若將微服務佈署為DaemonSet,Kubernetes元件將確保每個節點上都執行一個該微服務的Pod,不多也不少。那麼,背後究竟發生了什麼事?讓我們透過一張圖來高層次地展示元件之間的互動:
圖3.1 – Kubernetes元件之間的互動關係
簡單回顧一下這些元件的功能:
- kube-apiserver:Kubernetes API伺服器,負責驗證並組態物件的資料。
- etcd:高用性的鍵值儲存,用於儲存組態、狀態及元資料等資訊。
- kube-scheduler:Kubernetes預設的排程器,監控新建立的Pod並將其分配至合適的節點。
- kube-controller-manager:Kubernetes控制器管理員,結合了核心控制器,用於監控狀態更新並對叢集進行相應的變更。
- cloud-controller-manager:雲端控制器管理員,執行與底層雲端供應商互動的控制器。
- kubelet:在節點上執行,負責向API伺服器註冊節點,並監控由Podspecs建立的Pod,以確保Pod和容器健康運作。
值得注意的是,只有kube-apiserver會與etcd直接通訊。其他Kubernetes元件,如kube-scheduler、kube-controller-manager和cloud-controller-manager,則是透過與執行在主節點上的kube-apiserver互動來履行其職責。在工作節點上,kubelet和kube-proxy都會與kube-apiserver通訊。
圖3.2 – 在Kubernetes中建立DaemonSet
讓我們以建立DaemonSet為例來說明這些元件如何相互通訊:
- 使用者透過HTTPS向kube-apiserver傳送建立DaemonSet工作負載的請求。
- 經過身份驗證、授權及物件驗證後,kube-apiserver在etcd資料函式庫中建立DaemonSet的工作負載物件資訊。預設情況下,etcd中的資料在傳輸或靜止狀態下均未加密。
- DaemonSet控制器監控到新的DaemonSet物件被建立後,向kube-apiserver傳送建立Pod的請求。DaemonSet基本上意味著該微服務將在每個節點上的一個Pod中執行。
- kube-apiserver重複步驟2中的動作,在etcd資料函式庫中建立Pod的工作負載物件資訊。
- kube-scheduler監控到新的Pod被建立後,根據節點選擇條件決定在哪個節點上執行該Pod。隨後,kube-scheduler向kube-apiserver傳送請求,將Pod分配至指定的節點。
- kube-apiserver接收來自kube-scheduler的請求,並更新etcd中的Pod節點分配資訊。
- 在工作節點上執行的kubelet監控到新的Pod被分配至該節點後,向容器執行介面(CRI)元件(如Docker)傳送請求以啟動容器。隨後,kubelet將Pod的狀態回報給kube-apiserver。
- kube-apiserver接收來自目標節點上kubelet的Pod狀態資訊,並更新etcd資料函式庫中的Pod狀態。
- 一旦DaemonSet的Pod被建立,這些Pod就能與其他Kubernetes元件通訊,且微服務應該能夠正常運作。
需要注意的是,並非所有元件之間的通訊預設都是安全的,這取決於這些元件的組態方式。我們將在第6章「保護叢集元件」中更詳細地討論這一點。
Kubernetes環境中的威脅行為者
威脅行為者是指系統中需要被保護的實體或程式碼。從防禦的角度來看,首先需要了解潛在的敵人是誰,否則防禦策略將過於模糊。Kubernetes環境中的威脅行為者大致可分為三類別:
- 終端使用者:能夠連線到應用程式的實體。通常,這些使用者的入口點是負載平衡器或ingress。有時,Pod、容器或NodePorts可能會直接暴露在網際網路上,為終端使用者提供更多的入口點。
- 內部攻擊者:在Kubernetes叢集內具有有限存取許可權的實體。在叢集內產生的惡意容器或Pod是內部攻擊者的例子。
- 特權攻擊者:在Kubernetes叢集內具有管理員許可權的實體。基礎設品管理員、被攻陷的kube-apiserver例項以及惡意節點都是特權攻擊者的例子。
威脅行為者的例子包括指令碼小子(script kiddies)、駭客主義者(hacktivists)和國家級攻擊者。根據這些行為者在系統中的位置,他們都屬於上述三種類別之一。
下圖突出了Kubernetes生態系統中的不同行為者:
圖示說明
此圖示展示了Kubernetes生態系統中的不同威脅行為者及其可能的攻擊途徑。
內容解密:
此圖示對於瞭解不同威脅行為者在Kubernetes生態系統中的角色至關重要。它幫助我們識別潛在的安全風險,並採取相應的安全措施來保護叢集和應用程式。透過分析這些威脅行為者的特點和可能的攻擊途徑,我們可以制定更有效的防禦策略,以保護Kubernetes環境的安全。
Kubernetes 環境中的威脅建模
Kubernetes 環境中的威脅參與者
在 Kubernetes 環境中,瞭解不同的威脅參與者對於威脅建模至關重要。圖 3.3 展示了 Kubernetes 環境中的不同威脅參與者。
此圖顯示,終端使用者通常透過 ingress 控制器、負載平衡器或 Pod 公開的 HTTP/HTTPS 路由進行互動。終端使用者是許可權最低的。內部攻擊者則對叢集內的資源有有限的存取許可權。特權攻擊者擁有最高的許可權,可以修改叢集。這三類別攻擊者有助於確定威脅的嚴重程度。
Kubernetes 叢集中的威脅
瞭解 Kubernetes 元件和威脅參與者後,我們接下來探討 Kubernetes 叢集的威脅建模。下表列出了主要的 Kubernetes 元件、節點和 Pod。節點和 Pod 是執行工作負載的基本 Kubernetes 物件。所有這些元件都是資產,應受到保護以免受威脅。
| 元件 | 威脅 | 防護措施 |
|---|---|---|
| kube-apiserver | 未授權存取、資料洩露 | RBAC、網路策略 |
| etcd | 資料洩露、未授權存取 | 加密、備份 |
| 節點 | 節點被攻陷、資源耗盡 | 節點隔離、資源限制 |
| Pod | Pod 被攻陷、特權提升 | Pod 安全策略、網路策略 |
此表強調了預設 Kubernetes 組態中的一些威脅,以及開發人員和叢集管理員如何保護其資產免受這些威脅。
Kubernetes 中的應用程式威脅建模
現在,我們已經瞭解了 Kubernetes 叢集中的威脅,接下來討論如何在 Kubernetes 上佈署的應用程式進行威脅建模。Kubernetes 中的佈署增加了額外的複雜性,需要考慮額外的資產、威脅參與者和新的安全控制。
傳統 Web 應用程式與 Kubernetes 中的 Web 應用程式
考慮一個簡單的三層 Web 應用程式。在傳統架構中,其威脅模型如圖 3.4 所示。在 Kubernetes 環境中,同樣的應用程式看起來略有不同,如圖 3.5 所示。
在 Kubernetes 中,Web 伺服器、應用程式伺服器和資料函式庫都執行在 Pod 中。比較傳統 Web 架構和雲原生架構的威脅建模,我們發現雲原生架構需要保護更多的資產,並且面臨更多的威脅參與者。
在 Kubernetes 中應用最小許可權原則
最小許可權原則簡介
最小許可權原則指出,生態系統中的每個元件應該只具有執行其功能所需的最小資料和資源存取許可權。在多租戶環境中,多個資源可以被不同的使用者或物件存取。最小許可權原則確保瞭如果使用者或物件行為異常,對叢集的損害將是最小的。
Kubernetes 中的最小許可權原則
在 Kubernetes 中,最小許可權原則可以透過 Role-Based Access Control(RBAC)、網路策略、安全上下文、Pod 安全策略等安全功能來實作。本章將介紹如何使用這些功能來實作 Kubernetes 叢集中的最小許可權原則。
Kubernetes 物件的許可權
Kubernetes 中的物件(如 Pod、服務帳戶)具有不同的許可權。瞭解這些許可權並對其進行限制是實作最小許可權原則的關鍵。
使用 RBAC 控制存取
RBAC 是 Kubernetes 中的一個關鍵安全功能,允許管理員根據使用者或服務帳戶的角色來控制其對叢集資源的存取。
網路策略
網路策略允許管理員控制 Pod 之間的流量,從而限制潛在的攻擊面。
安全上下文和 Pod 安全策略
安全上下文和 Pod 安全策略提供了對 Pod 行為的細粒度控制,例如是否允許特權容器、是否允許使用主機網路等。
在 Kubernetes 中應用最小許可權原則
在這一章中,我們將涵蓋以下主題:
- 最小許可權原則的概念
- Kubernetes 主體的最小許可權
- Kubernetes 工作負載的最小許可權
最小許可權原則
許可權是指執行某個動作的授權,例如存取資源或處理資料。最小許可權原則是指任何主體、使用者、程式、程式等只應具有執行其功能所需的最低許可權。例如,Alice 是一名普通的 Linux 使用者,她可以在自己的家目錄下建立檔案。換句話說,Alice 至少具有在家目錄下建立檔案的許可權或許可。但是,Alice 可能無法在其他使用者的目錄下建立檔案,因為她沒有這樣做的許可權或許可。如果 Alice 的日常任務實際上並不需要行使在家目錄下建立檔案的許可權,但她確實具有這種許可權,那麼該機器的管理員就沒有遵守最小許可權原則。在本文中,我們將首先介紹授權模型的概念,然後討論實施最小許可權原則的好處。
授權模型
當我們談論最小許可權時,大多數情況下是在授權的背景下討論的。在不同的環境中,會有不同的授權模型。例如,存取控制列表(ACL)被廣泛用於 Linux 和網路防火牆,而根據角色的存取控制(RBAC)則用於資料函式庫系統。環境的管理員還需要根據系統中可用的授權模型定義授權策略,以確保最小許可權。以下列表定義了一些流行的授權模型:
- ACL:ACL 定義了與物件相關聯的許可列表。它指定了哪些主體被授予存取物件的許可權,以及允許對給定物件進行哪些操作。例如,
-rw檔案許可表示僅由檔案所有者讀寫。 - RBAC:授權決策根據主體的角色,角色包含一組許可或特權。例如,在 Linux 中,使用者被新增到不同的組(如
staff)以授予對某些資料夾的存取許可權,而不是單獨授予對檔案系統上資料夾的存取許可權。 - 屬性根據存取控制(ABAC):授權決策根據主體的屬性,例如標籤或屬性。根據屬性的規則檢查使用者屬性,例如
user.id="12345"、user.project="project"和user.status="active",以決定使用者是否能夠執行某項任務。
Kubernetes 支援 ABAC 和 RBAC。雖然 ABAC 強大且靈活,但 Kubernetes 中的實作使其難以管理和理解。因此,建議在 Kubernetes 中啟用 RBAC 而不是 ABAC。除了 RBAC 之外,Kubernetes 還提供了多種限制資源存取的方法。在我們深入瞭解 Kubernetes 中的 RBAC 和 ABAC 之前,讓我們討論一下確保最小許可權的好處。
最小許可權原則的好處
雖然可能需要花費相當多的時間來瞭解主體執行其功能所需的最低許可權,但如果在您的環境中實施了最小許可權原則,那麼好處也是顯著的:
- 更好的安全性:內部威脅、惡意軟體傳播、橫向移動等可以透過實施最小許可權原則來減輕。愛德華·斯諾登洩密事件就是因為缺乏最小許可權而發生的。
- 更好的穩定性:由於主體被適當地授予必要的特權,因此主體的活動變得更加可預測。反過來,系統穩定性得到增強。
- 提高稽核準備度:由於主體被適當地授予必要的特權,因此稽核範圍將大大減少。此外,許多常見的法規要求實施最小許可權原則作為合規要求。
既然您已經瞭解了實施最小許可權原則的好處,我想介紹一下挑戰:Kubernetes 的開放性和可組態性使得實施最小許可權原則變得繁瑣。讓我們看看如何將最小許可權原則應用於 Kubernetes 主體。
Kubernetes 主體的最小許可權
Kubernetes 服務帳戶、使用者和組與 kube-apiserver 通訊以管理 Kubernetes 物件。透過啟用 RBAC,不同的使用者或服務帳戶可能具有不同的操作 Kubernetes 物件的特權。例如,system:master 組中的使用者具有授予的 cluster-admin 角色,這意味著他們可以管理整個 Kubernetes 叢集,而 system:kube-proxy 組中的使用者只能存取 kube-proxy 元件所需的資源。首先,讓我們簡要介紹一下什麼是 RBAC。
RBAC 簡介
如前所述,RBAC 是一種根據授予使用者或組的角色來規範對資源存取的模型。從版本 1.6 開始,RBAC 在 Kubernetes 中預設啟用。在版本 1.6 之前,可以透過執行 API 伺服器並帶有 --authorization-mode=RBAC 標誌來啟用 RBAC。RBAC 使用 API 伺服器簡化了許可策略的動態組態。
RBAC 的核心元素包括以下內容:
- 主體:請求存取 Kubernetes API 的服務帳戶、使用者或組。
- 資源:需要被主體存取的 Kubernetes 物件。
- 動詞:主體在資源上需要的不同型別的存取——例如,建立、更新、列出、刪除。
Kubernetes RBAC 定義了主體以及它們對 Kubernetes 生態系統中不同資源的存取型別。
服務帳戶、使用者和組
Kubernetes 支援三種型別的主體,如下所示:
- 普通使用者:這些使用者由叢集管理員建立。它們在 Kubernetes 生態系統中沒有對應的物件。叢集管理員通常使用輕量級目錄存取協定(LDAP)、活動目錄(AD)或私鑰建立使用者。
- 服務帳戶:Pod 使用服務帳戶向
kube-apiserver物件進行身份驗證。服務帳戶是使用 API 呼叫建立的。它們僅限於名稱空間,並將相關憑據儲存為秘密。預設情況下,Pod 以default服務帳戶進行身份驗證。
程式碼說明
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-serviceaccount
內容解密:
上述 YAML 程式碼定義了一個名為 my-serviceaccount 的服務帳戶。這是用於向 kube-apiserver 物件進行身份驗證的憑據。在此範例中,我們建立了一個新的服務帳戶,而不是使用預設的服務帳戶。這樣做可以讓我們更好地控制 Pod 的身份驗證和授權。
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-rolebinding
roleRef:
name: my-role
kind: Role
subjects:
- kind: ServiceAccount
name: my-serviceaccount
namespace: default
內容解密:
上述 YAML 程式碼定義了一個名為 my-rolebinding 的角色繫結。它將 my-role 角色繫結到 my-serviceaccount 服務帳戶。這樣做可以讓 my-serviceaccount 服務帳戶具有 my-role 角色所定義的許可和特權。在此範例中,我們將角色繫結到特定的服務帳戶和名稱空間,以實作更精細的存取控制。
kubectl create role my-role --verb=get --verb=list --resource=pods
內容解密:
上述命令建立了一個名為 my-role 的角色,該角色具有對 Pod 資源的 get 和 list 許可。這樣做可以讓具有此角色的主體列出和取得 Pod 資源。在此範例中,我們使用 kubectl 命令列工具建立了一個新的角色,以實作對 Kubernetes 資源的存取控制。
在 Kubernetes 中實施最小許可權原則
Kubernetes 是一個強大的容器協調系統,提供了豐富的功能來管理和控制叢集內的資源存取。為了確保叢集的安全性和穩定性,實施最小許可權原則(Principle of Least Privilege)是至關重要的。本文將探討如何在 Kubernetes 中實作最小許可權原則,包括相關的概念、操作步驟以及最佳實踐。
Kubernetes 中的最小許可權概念
在 Kubernetes 中,最小許可權原則意味著為每個主體(Subject)分配最少的許可權,以滿足其執行任務的需求。這種方法可以減少因過度授權而導致的安全風險。
匿名使用者與服務帳戶
在 Kubernetes 中,任何未與常規使用者或服務帳戶相關聯的 API 請求都會被視為匿名使用者。叢集管理員可以建立新的服務帳戶並將其與 Pod 關聯,以實作最小許可權。
$ kubectl create serviceaccount new_account
上述命令會在預設名稱空間中建立一個名為 new_account 的服務帳戶。為了確保最小許可權,叢集管理員應該為每個 Kubernetes 資源分配具有最小必要許可權的服務帳戶。
角色與 ClusterRole
角色(Role)是一組許可權的集合,例如,某個名稱空間中的角色可以允許使用者在該名稱空間中建立 Pod 或列出 Secret。Kubernetes 中沒有拒絕許可權的概念,因此角色是一種新增許可權的機制。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: role-1
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
內容解密:
此 Role 定義允許對預設名稱空間中的 Pod 資源執行 get 操作。這意味著擁有此角色的主體可以檢索 Pod 的資訊,但不能建立、修改或刪除 Pod。
角色繫結(RoleBinding)與 ClusterRoleBinding
RoleBinding 物件用於將角色與主體(使用者、組或服務帳戶)關聯起來。ClusterRoleBinding 則用於在叢集範圍內授予許可權。
$ kubectl create rolebinding new-rolebinding-sa \
--clusterrole=custom-clusterrole \
--serviceaccount=default:demo-sa
內容解密:
此命令建立了一個 RoleBinding 物件,將 custom-clusterrole ClusterRole 繫結到 default 名稱空間中的 demo-sa 服務帳戶。這意味著 demo-sa 服務帳戶將獲得 custom-clusterrole 中定義的許可權。
Kubernetes 名稱空間
名稱空間(Namespace)是 Kubernetes 中的一個重要概念,用於邏輯上隔離資源。不同的應用、團隊和使用者可以在相同的叢集中工作,而不會相互幹擾。
$ kubectl create namespace test
內容解密:
此命令建立了一個名為 test 的新名稱空間。建立後,可以將資源分配到此名稱空間中。
最小許可權實施的最佳實踐
在實施最小許可權原則時,應考慮以下問題:
主體是否需要名稱空間級別或跨名稱空間的許可權?
- 如果主體需要跨名稱空間的許可權,應使用 ClusterRole 和 ClusterRoleBinding。
應該將許可權授予使用者、組還是服務帳戶?
- 將角色授予組意味著組內的所有使用者都將獲得該角色的許可權。應謹慎評估這種授權的影響。
主體需要存取哪些資源?
- 在建立角色時,應明確指定資源名稱或使用
*萬用字元來授予對某類別資源的存取許可權。
- 在建立角色時,應明確指定資源名稱或使用
透過遵循這些最佳實踐,可以有效地在 Kubernetes 中實施最小許可權原則,從而提高叢集的安全性和可管理性。