Kubernetes 網路政策是保護叢集安全的重要機制,允許定義 Pod 間的流量規則,限制非預期連線。傳統網路安全仰賴網路裝置的物理拓撲和組態,而 Kubernetes 網路政策提供更細緻的控制,尤其在微服務架構下,能有效降低東西向流量的攻擊面。實務上,網路政策透過 YAML 檔案定義,設定 Pod 的標籤選擇器、入口和出口規則,並可整合 RBAC 進行許可權管理。建議採用預設拒絕策略,並搭配網路政策工具進行流量分析和影響預覽,以確保政策的有效性和安全性。
網路政策:Kubernetes叢集安全防護的關鍵
在保護Kubernetes叢集的過程中,網路政策扮演著至關重要的角色。本章將探討網路政策的概念、重要性、實施方法以及最佳實踐,並提供實際範例以幫助讀者更好地理解。
網路政策的定義
網路政策是Kubernetes網路安全的核心工具,允許使用者輕鬆限制叢集中的網路流量,確保只有預期的流量能夠透過。要了解網路政策的重要性,我們首先需要回顧在網路政策出現之前,企業網路通常如何實作網路安全。
在傳統的企業網路中,網路安全主要透過設計網路裝置(交換器、路由器、防火牆)的物理拓撲結構及其相關組態來實作。這種物理拓撲結構定義了網路的安全邊界。在虛擬化的第一階段,同樣的網路和網路裝置概念被虛擬化於雲端,同樣使用建立特定網路拓撲結構的方法來提供網路安全。每當新增應用程式或服務時,往往需要額外的網路設計來更新網路拓撲和裝置組態,以提供所需的安全性。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-network-policy
spec:
podSelector:
matchLabels:
app: example-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: allowed-app
- ports:
- 80
egress:
- to:
- podSelector:
matchLabels:
app: external-service
- ports:
- 443
內容解密:
此YAML檔案定義了一個名為example-network-policy的網路政策。該政策選擇標籤為app: example-app的Pod作為目標。主要設定了兩種型別的規則:
- 入口(Ingress)規則:只允許來自標籤為
app: allowed-app的Pod,並且只允許透過80埠的流量進入目標Pod。 - 出口(Egress)規則:只允許目標Pod透過443埠存取標籤為
app: external-service的Pod。
網路政策的重要性
在攻擊者日益精進的今天,網路安全作為一道防線比以往任何時候都更加重要。雖然可以使用防火牆來限制網路周邊(通常稱為南北向流量)的流量,但由於Pod排程和IP位址的動態特性,它們對Kubernetes流量的監管能力往往僅限於整個叢集的粒度,而非特定的Pod群組。此外,大多數攻擊者在進入內部後,目標是橫向移動(東西向)以取得更高價值的目標,而根據周邊的防火牆無法對此進行有效監管。隨著應用架構從單體架構演進為微服務架構,東西向流量的增加使得橫向移動的攻擊面持續擴大。
此圖示展示了攻擊者進入內部後橫向移動的過程,以及如何透過防火牆和網路政策來限制東西向流量,從而減少攻擊面。
網路政策的最佳實踐
- 使用Kubernetes原生的網路政策工具:確保所使用的網路政策工具是Kubernetes原生的,能夠與Kubernetes叢集無縫整合。
- 根據標籤選擇器定義網路政策:利用標籤選擇器而非IP位址來定義網路政策,使其更具動態性和彈性。
- 整合到Git工作流程和CI/CD流程中:將網路政策的編寫整合到Git工作流程和CI/CD流程中,提高安全性和自動化程度。
網路政策實作
Kubernetes 定義了一個標準的網路政策 API,因此在任何叢集中,您都可以期待一套基本的特性。然而,Kubernetes 本身並不會對網路政策進行任何處理。網路政策的執行被委派給網路外掛程式,允許有多種實作方式。大多數網路外掛程式支援 Kubernetes 網路政策的主要元素,但許多並未實作規範中的每個功能。值得注意的是,大多數實作都與網路外掛程式特定的 Pod 網路實作密切相關。然而,一些網路政策實作可以在多種不同的 Pod 網路外掛程式上執行網路政策。
網路政策實作的多樣性
有多種網路和網路政策實作可供選擇,如圖 7-3 所示。
無論選擇哪種網路政策實作,我們建議使用以下原因:
- 它實作了完整的 Kubernetes 網路政策規範。
- 除了支援 Kubernetes 網路政策規範外,其自身的政策模型還提供了額外的功能,可以與 Kubernetes 網路政策一起使用,以支援額外的企業安全案例。
- 一些網路外掛程式,如 Weave Net、Kube-router 和 Calico,可以在其豐富的網路功能之上執行網路政策,也可以支援多種其他網路選項,包括 Amazon 的 Elastic Kubernetes Service(EKS)、Azure Kubernetes Service(AKS)和 Google Kubernetes Engine(GKE)使用的網路外掛程式。這使得它們成為多雲策略的特別強大的選擇,因為它提供了從廣泛的選項中選擇最適合您環境的網路的靈活性,同時在所有環境中提供相同的豐富網路政策功能。
- 網路政策可以應用於主機端點/介面,從而可以使用相同的靈活政策模型來保護 Kubernetes 節點或非叢集主機/虛擬機器。
- 它支援在網路/基礎設施層和上層強制執行的網路政策,包括在其政策規則中支援 L5-L7 匹配條件,如 HTTP 方法和路徑。多個強制執行點有助於保護您的基礎設施免受受損工作負載的影響,並保護您的工作負載免受受損基礎設施的影響。它還避免了在應用程式和基礎設施層進行雙重安全設定的需要,或學習不同層的不同政策模型。
網路政策最佳實踐
在本文中,我們將透過範例探討如何實作網路政策,並介紹實作的最佳實踐。以下範例使用 Calico 網路政策架構,它擴充套件了 Kubernetes 網路政策架構。
Ingress 和 Egress
當人們想到網路安全時,第一個想法通常是如何保護工作負載免受南北向外部攻擊者的攻擊。為了幫助抵禦這種攻擊,可以使用網路政策來限制 ingress 流量到任何可從叢集外部存取的 Pod。
然而,當攻擊者確實找到漏洞時,他們通常會利用受損的工作負載作為橫向移動的起點,探測網路的其他部分,以利用額外的漏洞,從而取得更有價值的資源或提升許可權,以進行更強大的攻擊或洩露敏感資料。
即使您有網路政策來限制叢集中所有 Pod 的 ingress 流量,橫向移動仍可能針對叢集外部的資產,這些資產的安全保護較弱。因此,最佳實踐是始終為叢集中的每個 Pod 定義 ingress 和 egress 網路政策規則。
雖然這並不能保證攻擊者無法找到額外的漏洞,但它確實大大減少了可用的攻擊面,使攻擊者的任務變得更加困難。此外,如果與適當的違規警示結合使用,則可以大大減少識別工作負載被洩露所需的時間。
不只是關鍵任務工作負載
最佳實踐已經建議確保每個 Pod 都有一個限制其 ingress 和 egress 流量的網路政策。這意味著,當您思考如何保護關鍵任務工作負載時,您實際上需要保護所有工作負載。如果不這樣做,那麼一些看似不重要、無害的工作負載可能會被用作攻擊其他網路的基礎,最終導致最重要的工作負載被攻破。
政策和標籤架構
Kubernetes 標籤和網路政策的優勢之一是其使用的靈活性。然而,因此,經常有多種不同的標籤和編寫政策的方法可以實作相同的特定目標。因此,另一個最佳實踐是考慮使用一致的架構或設計模式來標準化標籤 Pod 和編寫網路政策的方法。這可以使您的網路安全組態更加清晰、易於理解和維護。
網路策略最佳實踐
在 Kubernetes 環境中,網路策略(Network Policy)是確保微服務之間安全通訊的關鍵要素。正確地定義和實施網路策略,可以顯著提高叢集的安全性和可管理性。
標籤策略與網路策略定義
為了簡化網路策略的建立和維護,定義一套一致的標籤(Label)策略至關重要。例如,可以為每個 Pod 分配一個 app 標籤,以標識其所屬的微服務。接著,可以根據這些標籤來定義網路策略,規範微服務之間的通訊規則。
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: back-end-policy
namespace: production
spec:
selector: app == 'back-end'
ingress:
- action: Allow
protocol: TCP
source:
selector: app == 'front-end'
destination:
ports:
- 80
egress:
- action: Allow
protocol: TCP
destination:
selector: app == 'database'
ports:
- 80
內容解密:
- 網路策略定義:此範例展示了一個名為
back-end-policy的網路策略,專門針對production名稱空間中標籤為app == 'back-end'的 Pod。 - Ingress 規則:允許來自標籤為
app == 'front-end'的 Pod 對 Port 80 的 TCP 連線請求。 - Egress 規則:允許對標籤為
app == 'database'的 Pod 的 Port 80 進行 TCP 連線。 - 安全意義:此策略確保了後端服務僅能與前端服務和資料函式庫服務進行必要的通訊,從而減少了潛在的攻擊面。
使用許可標籤簡化網路策略
另一種方法是使用許可標籤(Permission-style labels)來簡化網路策略的定義。例如,可以定義一個允許具有特定許可標籤的微服務存取特定服務的規則。
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: database-policy
namespace: production
spec:
selector: app == 'database'
ingress:
- action: Allow
protocol: TCP
source:
selector: database-client == 'true'
destination:
ports:
- 80
egress:
- action: Deny
內容解密:
- 許可標籤應用:此範例展示瞭如何使用
database-client == 'true'這樣的許可標籤來控制對資料函式庫服務的存取。 - Ingress 規則:僅允許具有
database-client標籤且值為true的 Pod 對資料函式庫服務的 Port 80 進行 TCP 連線。 - Egress 規則:預設拒絕所有輸出流量,確保資料函式庫服務不會向外發起非預期的連線。
預設拒絕與預設應用程式策略
Kubernetes 網路策略規範預設允許所有入口 Pod 流量,除非有明確的網路策略對其進行限制。因此,為了提高安全性,建議實施「預設拒絕」(Default Deny)策略。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: my-namespace
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
內容解密:
- 預設拒絕策略:此範例定義了一個預設拒絕所有輸入和輸出流量的網路策略,適用於
my-namespace名稱空間中的所有 Pod。 - 安全意義:確保除非有明確允許的網路策略,否則所有流量都會被拒絕,從而提高叢集的安全性。
全域網路策略
某些網路策略實作允許定義全域網路策略(GlobalNetworkPolicy),適用於整個叢集。
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: default-deny
spec:
selector: all()
types:
- Ingress
- Egress
內容解密:
- 全域應用:此全域網路策略將預設拒絕規則應用於叢集中的所有 Pod 和名稱空間。
- 注意事項:需謹慎使用,因為錯誤的組態可能會導致叢集故障。
網路政策工具(Policy Tooling)
在 Kubernetes 叢集中有效地新增網路政策需要藉助適當的工具。本文將探討可用的工具及其優勢。
開發流程與微服務的優勢
與傳統網路安全控制相比,定義網路政策不需要網路或防火牆的專業知識。網路政策使用與其他 Kubernetes 資源相同的概念和正規化。理論上,任何熟悉在 Kubernetes 中佈署微服務的團隊都可以輕鬆掌握網路政策。因此,網路政策代表了一個採用「左移」哲學(shift-left philosophy)的機會,將網路安全定義在開發週期的早期,而不是在流程的最後階段。這是安全團隊和開發團隊協作以保護 Kubernetes 叢集的最佳機會。
許多組織正在從單體式應用架構轉向微服務架構,其中一個目標是提高開發和組織的敏捷性。在這種方法中,每個微服務通常由單一開發團隊維護,該團隊對微服務有深入的瞭解,但不一定對整個應用程式有深入的瞭解。微服務的轉變補充了網路政策的「左移」機會。負責開發微服務的團隊通常對其所依賴的其他微服務有很好的理解。他們可能還瞭解哪些微服務正在使用他們的微服務。
網路政策的實施
當與良好定義、標準化的政策和標籤架構結合時,這使得他們能夠在開發微服務的過程中實施網路政策。在這種模式下,網路政策被視為內建於開發過程中的程式碼,並像微服務的其他關鍵部分一樣進行測試。
同樣有效的方法是讓開發團隊專注於他們負責的微服務內部運作,而將微服務的操作責任交給 DevOps 團隊。然而,同樣的理念仍然適用。這樣的 DevOps 團隊通常需要對他們負責操作的微服務之間的依賴關係有很好的理解,以便管理應用的操作和微服務的生命週期。網路安全可以由 DevOps 團隊定義為程式碼,並像其他操作程式碼或指令碼一樣進行測試,然後再用於生產環境。
網路政策工具的重要性
目前,許多組織距離實作微服務、敏捷性和「左移」安全的理想狀態還有一段距離。網路安全可能在組織的流程中出現得較晚,甚至是在系統已經投入生產後才被考慮。在這種情況下,定義網路政策可能具有相當大的挑戰性,而錯誤地定義網路政策可能會對生產環境產生重大影響。幸運的是,有許多工具可以幫助進行網路政策生命週期管理,使這一過程變得更容易,包括政策建議、政策影響預覽和政策分階段/稽核模式。
政策建議(Policy Recommendations)
在負責網路安全的團隊對需要保護的應用程式或微服務之間的網路依賴關係沒有充分了解的情況下,政策建議工具是一個很大的幫助。這些工具還可以幫助您以正確的方式開始編寫網路政策,使建立網路政策比手寫更容易。
這些工具通常透過分析一段時間內每個微服務的進出網路流量來工作。這意味著要獲得建議,微服務需要在生產環境中執行,或者在一個能夠準確反映微服務與應用程式其他部分之間生產互動的測試或預生產環境中執行。
市場上有許多可供選擇的政策建議工具,它們通常具有不同程度的複雜性、Kubernetes 感知程度和政策架構方法。建議使用內建於您的網路政策解決方案中的 Kubernetes 感知型政策建議引擎。
政策影響預覽(Policy Impact Previews)
政策影響預覽工具提供了一種在將網路政策應用於叢集之前進行健全性檢查的方法。與政策建議類別似,這通常是透過分析叢集一段時間內的歷史網路流量,並計算哪些網路流會受到新政策的影響來完成的。例如,識別以前允許但現在將被拒絕的流,以及以前被拒絕但現在將被允許的流。
內容解密:
- 分析歷史網路流量:透過檢查過去一段時間內的網路流量模式,瞭解現有的通訊模式。
- 計算新政策的影響:根據歷史資料,模擬新網路政策將如何影響現有的網路流量。
- 識別受影響的流量:明確指出哪些流量將被新政策允許或拒絕。
在任何不完全依賴政策建議的場景中,政策影響預覽都是一個很大的幫助。例如,如果您手動定義網路政策或修改政策建議以符合特定的標準化政策和標籤架構方法。即使定義微服務網路政策的團隊對其微服務的網路依賴關係有很高的信心,政策影響預覽也可以幫助捕捉任何可能對合法網路流量產生重大影響的意外錯誤,例如難以發現的拼寫錯誤。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Kubernetes叢集網路政策安全防護
package "Kubernetes Cluster" {
package "Control Plane" {
component [API Server] as api
component [Controller Manager] as cm
component [Scheduler] as sched
database [etcd] as etcd
}
package "Worker Nodes" {
component [Kubelet] as kubelet
component [Kube-proxy] as proxy
package "Pods" {
component [Container 1] as c1
component [Container 2] as c2
}
}
}
api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2
note right of api
核心 API 入口
所有操作經由此處
end note
@enduml
此圖示展示了使用政策影響預覽工具的基本流程,從分析歷史流量到評估和調整新網路政策。
管理跨團隊的信任
在前一章中,我們探討了網路政策如何代表著將網路安全左移的機會,讓安全由團隊在開發週期早期定義,而不是由安全團隊在流程末期定義和維護。這種方法可以帶來許多好處,但要使其可行,需要團隊之間有相應的信任程度和責任劃分。
角色存取控制(RBAC)
Kubernetes 角色存取控制(RBAC)是定義個別使用者或使用者群組在 Kubernetes 叢集中被允許執行的操作範圍的主要工具。RBAC 許可權使用角色定義,並透過角色繫結授予使用者或使用者群組。每個角色包括資源清單(由資源型別、叢集範圍、名稱空間內或甚至特定的資源例項指定)和每個資源的許可權(例如:get、list、create、update、delete 等)。
許多 Kubernetes 資源是名稱空間的,包括佈署、daemonsets、pods 和 Kubernetes 網路政策。這使得名稱空間成為團隊之間理想的信任邊界。對於如何使用名稱空間沒有固定的規則,但常見的做法是每個微服務使用一個名稱空間。然後,RBAC 可以用於授予管理名稱空間中資源的許可權給負責操作對應微服務的團隊。
網路政策的限制
在使用 RBAC 與 Kubernetes 網路政策的左移環境中,有幾個限制值得注意:
- 預設拒絕(default deny)型別的最佳實踐需要在名稱空間建立時為每個名稱空間建立。負責為微服務定義網路政策的團隊也將有能力修改或刪除此預設政策。
- 網路政策是根據 IP 的,您不能使用完全合格的網域名稱(FQDN)。這在定義與叢集外部資源相關的政策時可能是一個限制。
網路政策工具的進階功能
為了使網路政策的撰寫變得不那麼令人望而生畏,建議使用網路政策建議工具和政策預覽工具。這些工具可以幫助您瞭解政策變更對網路流量的影響,從而避免因錯誤組態而導致的中斷。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-network-policy
spec:
podSelector:
matchLabels:
app: example-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: allowed-app
- ports:
- 80
egress:
- to:
- podSelector:
matchLabels:
app: external-service
- ports:
- 443
詳細解說
上述 YAML 程式碼定義了一個 Kubernetes 網路政策範例。此政策允許來自標籤為 app: allowed-app 的 Pod 的流量進入標籤為 app: example-app 的 Pod 的 80 連線埠,同時允許標籤為 app: example-app 的 Pod 向標籤為 app: external-service 的 Pod 的 443 連線埠傳送流量。
apiVersion和kind: 指定了 Kubernetes 資源的 API 版本和型別,在這裡是networking.k8s.io/v1和NetworkPolicy。metadata: 包含了網路政策的後設資料,如名稱。spec: 定義了網路政策的規格,包括選擇器、政策型別、入口和出口規則。podSelector: 使用標籤選擇器來選擇此網路政策套用的 Pod。policyTypes: 指定了此網路政策適用的流量型別,可以是入口(Ingress)、出口(Egress)或兩者。ingress和egress: 定義了入口和出口流量的規則,包括來源或目標 Pod 的選擇器和允許的連線埠。
透過使用此類別網路政策,您可以實作微服務之間的精細流量控制,從而提高叢集的安全性。
管理跨團隊信任的最佳實踐
- 使用 RBAC 控制存取: 為每個團隊或微服務建立獨立的名稱空間,並使用 RBAC 控制對這些名稱空間的存取許可權。
- 實施預設拒絕網路政策: 為每個名稱空間建立預設拒絕網路政策,以確保未明確允許的流量被拒絕。
- 使用網路政策工具: 利用網路政策建議工具和政策預覽工具來簡化網路政策的管理和測試。
- 監控和稽核: 持續監控和稽核您的 Kubernetes 環境,以確保安全性和合規性。
透過遵循這些最佳實踐,您可以在 Kubernetes 環境中實作有效的跨團隊信任管理,從而提高整體安全性和效率。