Istio技術與實踐6:Istio如何為服務提供安全防護能力
今天,我們就來談談Istio第二主打功能---保護服務。
那麽,便引出3個問題:
? Istio憑什麽保護服務?
? Istio具體如何保護服務?
? 如何告訴Istio發揮保護能力?
1 Istio憑什麽保護服務?
將單體應用程序分解為一個個服務,為大型軟件系統的開發和維護帶來了諸多好處,比如更好的靈活性、可伸縮性和可復用性。但這也帶來了一些安全問題:
? 為了抵禦中間人×××,需要對流量進行加密
? 為了提供靈活的服務訪問控制,需要 mTLS(雙向的安全傳輸層協議)和細粒度的訪問策略
? 要審計誰在什麽時候做了什麽,需要審計工具
如上圖所示,
Istio 安全的三大目標是:
? 默認安全(Security by default):應用程序代碼和基礎結構,無需更改。
? 深度防禦(Defense in depth):與現有安全系統集成,提供多層防禦。
? 零信任網絡(Zero-trust network):在不受信任的網絡上,構建安全解決方案。
為了實現這3個目標,Istio 安全功能提供了4大守護系統:
? 強大的身份(Identity)系統
? 健壯的策略(Policy)系統
? 認證,授權和審計(AAA:Authentication,Authorization,Accounting)系統,用於保護服務和數據
就保護對象而言,Istio 安全系統可以抵禦來自內部或外部的威脅,這些威脅主要針對服務網格內的端點(Endpoints),通信(Communication),平臺(Platform)和數據(Data)。
2 Istio具體如何保護服務?
在安全方面,Istio具備3個遠大的目標,配備了4大守護系統,那麽它到底是通過怎樣的架構實現這個目標的呢,又通過什麽樣的安全基礎設施,和kubernetes配合呢?
2.1 Istio安全架構
如上圖,與Istio的4大守護系統相對應,Istio 中涉及安全的組件有:
? Pilot :將授權策略和安全命名信息分發給代理
? Citadel :用於密鑰和證書管理
? Mixer :管理授權和審計
由此可見,Pilot不僅負責流量規則和策略的分發,還負責安全相關策略的下發,有點像皇上的貼身太監,負責宣讀聖旨;Proxy有點像各州屬的州官,負責奉天承運;Citadel有點像玉璽和虎符,負責鑒真去假;Mixer有點像三省六部,負責授權審計。
2.2 兩個安全基本概念
2.2.1 Identity
身份(Identity)是幾乎所有安全基礎架構的基本概念。在服務和服務的通信開始前,雙方必須用其身份信息交換憑證,以達到相互認證的目的。在客戶端,根據安全命名(secure naming)信息,檢查服務端的標識,以查看它是否是該服務的授權運行程序;在服務端,服務端可以根據授權策略(authorization policies)信息,確定客戶端可以訪問哪些數據,審計其在什麽時間訪問了什麽,拒絕未授權客戶端的訪問。
在 Istio 身份模型中,Istio 使用一流的服務標識來確定服務的身份。這為表示人類用戶,單個服務或一組服務提供了極大的靈活性和粒度。在沒有此類身份的平臺上,Istio 可以使用可以對服務實例進行分組的其他身份,例如服務名稱。
不同平臺上的 Istio 服務標識:
? Kubernetes: Kubernetes 服務帳戶
? GKE/GCE: 可以使用 GCP 服務帳戶
? AWS: AWS IAM 用戶/角色 帳戶
? On-premises (non-Kubernetes): 用戶帳戶,自定義服務帳戶,服務名稱,istio 服務帳戶或 GCP 服務帳戶。
做個類比,京東和天貓都有自己的一套非常成熟的服務賬戶系統,淘寶只需要復用天貓的賬戶系統即可,無需重新開發一套,這樣我們就可以用天貓的賬號,直接登錄淘寶。而Istio也更傾向於復用業界一流的服務賬戶系統,如Kubernetes和AWS的,但也可以自定義服務賬戶,並按需復用Kubernetes的賬戶系統。
2.2.2 PKI
Istio PKI(Public Key Infrastructure)建立在 Istio Citadel 之上,可為每個工作負載提供安全且強大的工作負載標識。Istio 使用 X.509 證書來攜帶 SPIFFE 格式的身份信息。PKI 還可以大規模自動化地進行密鑰和證書輪換。
Istio 支持在 Kubernetes pod 和本地計算機上運行的服務。目前,Istio為每個方案使用不同的證書密鑰配置機制,下面試舉例Kubernetes方案的配置過程:
- Citadel 監視 Kubernetes apiserver,為每個現有和新的服務帳戶創建 SPIFFE 證書和密鑰對。 Citadel 將證書和密鑰對存儲為 Kubernetes secrets。
- 創建 pod 時,Kubernetes 會根據其服務帳戶通過 Kubernetes secret volume 將證書和密鑰對掛載到 pod。
- Citadel 監視每個證書的生命周期,並通過重寫 Kubernetes secret 自動輪換證書。
- Pilot 生成安全命名信息,該信息定義了哪些服務帳戶可以運行某個服務。接著Pilot 將安全命名信息傳遞給 Envoy。
3 如何告訴Istio發揮保護能力?
如上一章節所言,Istio基於控制面組件,引入了一流的服務賬戶系統,結合強大的PKI,實現了對服務網格的安全守護。同時,Istio也開放了接口,讓我們可以進行精細化的配置,全方位滿足我們對服務的安全需求。
服務安全,總是離不開兩個具體過程:認證(Authentication)和鑒權(Authorization)。Istio通過Policy和MeshPolicy文件,實現對認證相關功能的定義;通過RbacConfig、ServiceRole和ServiceRoleBinding文件,實現對鑒權相關功能的啟用和定義。
讓我們舉個幾個通俗的例子來區分認證和鑒權:
進火車站需要提供×××和火車票,×××可以證明你就是你,這是認證;火車票可以證明你有權上那趟火車,這是授權。
又例如,你要訪問自己淘寶的購物車,需要先登錄,這是認證。你要訪問朋友的購物車,就需要他的允許,這是授權。
再例如,有經驗的朋友能發現瀏覽器經常會面對兩個錯誤碼:401和403。通常而言,401就是未登錄的意思,需要認證;403就是禁止訪問的意思,需要授權。
3.1 認證
Istio 提供兩種類型的身份認證:
? 傳輸身份認證,也稱為服務到服務身份認證:對直連客戶端進行驗證。Istio 提供雙向TLS作為傳輸身份認證的全棧解決方案。我們可以輕松啟用此功能,而無需更改服務代碼。這個解決方案:
? 為每個服務提供強大的身份認定,以實現跨群集和跨雲的互操作性。
? 保護服務到服務通信和最終用戶到服務通信。
? 提供密鑰管理系統,以自動執行密鑰和證書生成,分發和輪換。
? 來源身份認證,也稱為終端用戶身份認證:對來自終端用戶或設備的原始客戶端請求進行驗證。Istio 通過 JSON Web Token(JWT)、Auth0、Firebase Auth、Google Auth 和自定義身份認證來簡化開發者的工作,使之輕松實現請求級別的身份認證。
在這兩種情況下,Istio 都通過自定義 Kubernetes API 將身份認證策略存儲在 Istio 配置存儲(Istio config store)中。Pilot會在適當的時候進行同步,為每個Proxy更新其最新狀態以及密鑰。此外,Istio 支持在許可模式下進行身份認證,以幫助我們理解策略變更前後,服務的安全狀態是如何變化的。
3.1.1 認證架構
我們可以使用身份認證策略,為 Istio 網格中接收請求的服務指定身份認證要求。我們使用 .yaml 文件來配置策略,策略將保存在 Istio 配置存儲中。在任何策略變更後,Pilot 會將新策略轉換為適當的配置,下發給Envoy,告知其如何執行所需的身份認證機制。Pilot 可以獲取公鑰並將其附加到 JWT 進行配置驗證。或者,Pilot 提供 Istio 系統管理的密鑰和證書的路徑,並將它們安裝到負載 Pod 中,以進行雙向 TLS。
本文多次提到雙向TLS認證,讓我們理解一下其在Istio裏的實現。Istio 通過客戶端和服務端各自配備的Envoy進行通信,也就是說,客戶端和服務端的流量,是被各自的Envoy接管了的。對於客戶端調用服務端,遵循的步驟是:
- Istio 將出站流量從客戶端重新路由到客戶端的本地 Envoy。
- 客戶端 Envoy 與服務端 Envoy 開始雙向 TLS 握手。在握手期間,客戶端 Envoy 還執行安全命名檢查,以驗證服務證書中提供的服務帳戶是否有權運行目標服務。
- 客戶端 Envoy 和服務端 Envoy 建立了一個雙向的 TLS 連接,Istio 將流量從客戶端 Envoy 轉發到服務端 Envoy。
- 授權後,服務端 Envoy 通過本地 TCP 連接將流量轉發到服務端的服務。
3.1.2 認證策略配置
和其他的 Istio 配置一樣,可以用 .yaml 文件的形式來編寫認證策略,然後使用 Istioctl 二進制工具進行部署。如下圖的配置,通過配置Policy文件,對reviews服務進行了傳輸身份認證的配置,要求其必須使用雙向TLS做認證。
apiVersion: "authentication.Istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "reviews"
spec:
targets:
- name: reviews
peers: - mtls: {}
3.2 授權
Istio 的授權功能,也稱為基於角色的訪問控制(RBAC),為 Istio 服務網格中的服務提供命名空間級別,服務級別和方法級別的訪問控制。它的特點是:
? 基於角色的語義,簡單易用。
? 包含服務到服務和終端用戶到服務兩種授權模式。
? 通過自定義屬性靈活定制授權策略,例如條件,角色和角色綁定。
? 高性能,因為 Istio 授權功能是在 Envoy 裏執行的。
3.2.1 授權架構
上圖顯示了基本的 Istio 授權架構。和認證的生效過程一樣,運維人員使用.yaml文件指定 Istio 授權策略。部署後,Istio 將策略保存在Istio Config Store中。Pilot 會一直監視 Istio 授權策略的變更,如果發現任何更改,它將獲取更新的授權策略,並將 Istio 授權策略分發給與服務實例位於同一 pod 內的 Envoy 代理。
每個 Envoy 代理都運行一個授權引擎,該引擎在運行時授權請求。當請求到達代理時,授權引擎根據當前授權策略評估請求上下文,並返回授權結果ALLOW或DENY。
3.2.2 授權策略配置
我們可以使用 RbacConfig 啟用授權策略,並使用ServiceRole和ServiceRoleBinding配置授權策略。
RbacConfig是一個網格維度的單例,其固定名稱值為default,也就是說我們只能在網格中配置一個RbacConfig實例。與其他 Istio 配置對象一樣,RbacConfig被定義為Kubernetes CustomResourceDefinition (CRD)對象。
在RbacConfig中,運算符可以指定mode值,它可以是:
? OFF:禁用 Istio 授權。
? ON:為網格中的所有服務啟用了 Istio 授權。
? ON_WITH_INCLUSION:僅對包含字段中指定的服務和命名空間啟用 Istio 授權。
? ON_WITH_EXCLUSION:除了排除字段中指定的服務和命名空間外,網格中的所有服務都啟用 Istio 授權。
在以下示例中,為default命名空間啟用了 Istio 授權,。
apiVersion: "rbac.Istio.io/v1alpha1"
kind: RbacConfig
metadata:
name: default
namespace: Istio-system
spec:
mode: ‘ON_WITH_INCLUSION‘
inclusion:
namespaces: ["default"]
針對服務和命名空間啟用授權後,我們還需要配置具體的授權策略,這通過配置ServiceRole和ServiceRoleBinding實現。與其他 Istio 配置對象一樣,它們同樣被定義為CRD對象。
ServiceRole定義了一組訪問服務的權限。ServiceRoleBinding向特定對象授予 ServiceRole,例如用戶,組或服務。
ServiceRole 和 ServiceRoleBinding 組合規定了: 允許誰在哪些條件下做什麽,具體而言:
? 誰指的是 ServiceRoleBinding 中的 subject 部分。
? 做什麽指的是 ServiceRole 中的 rule 部分。
? 哪些條件指的是我們可以在 ServiceRole 或 ServiceRoleBinding 中使用Istio Attributes指定的 condition 部分。
讓我們再舉一個簡單的例子,如下圖,ServiceRole和 ServiceRoleBinding的配置規定:將所有用戶(user=“*”)綁定為(products-viewer)角色,這個角色可以對products這個服務發起GET或HEAD請求,但是其限制條件是請求頭必須包含version,且值為v1或v2。
apiVersion: "rbac.Istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: products-viewer
namespace: default
spec:
rules:
- services: ["products"]
methods: ["GET", "HEAD"]
constraints:-
key: request.headers[version]
values: ["v1", "v2"]apiVersion: "rbac.Istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: binding-products-allusers
namespace: default
spec:
subjects:
-
- user: "*"
roleRef:
kind: ServiceRole
name: "products-viewer"
至此,我們做個簡單的總結:單體應用程序拆分成成千上百個服務後,帶來了安全問題,Istio嘗試在由服務組成的服務網格裏,加入了一套全棧解決方案。這套方案裏,Istio默默處理了大部分安全基礎設施,但也暴露了認證和授權兩個功能讓用戶進行自定義配置。我們通過Policy、MeshPolicy以及RbacConfig、ServiceRole、ServiceRoleBinding就可以完成對認證和授權環節所有功能的配置,而不需要侵入地改動任何服務的代碼。
Istio技術與實踐6:Istio如何為服務提供安全防護能力