Istio技術與實踐6:Istio如何爲服務提供安全防護能力

凡是產生連接關係,就必定帶來安全問題,人類社會如此,服務網格世界,亦是如此。
今天,我們就來談談Istio第二主打功能---保護服務。
那麼,便引出3個問題:
 Istio憑什麼保護服務?
 Istio具體如何保護服務?
 如何告訴Istio發揮保護能力?

1 Istio憑什麼保護服務?
將單體應用程序分解爲一個個服務,爲大型軟件系統的開發和維護帶來了諸多好處,比如更好的靈活性、可伸縮性和可複用性。但這也帶來了一些安全問題:
 爲了抵禦中間人×××,需要對流量進行加密
 爲了提供靈活的服務訪問控制,需要 mTLS(雙向的安全傳輸層協議)和細粒度的訪問策略
 要審計誰在什麼時候做了什麼,需要審計工具
Istio 嘗試提供全面的安全解決方案來解決這3個問題。
Istio技術與實踐6:Istio如何爲服務提供安全防護能力
如上圖所示,
Istio 安全的三大目標是:
 默認安全(Security by default):應用程序代碼和基礎結構,無需更改。
 深度防禦(Defense in depth):與現有安全系統集成,提供多層防禦。
 零信任網絡(Zero-trust network):在不受信任的網絡上,構建安全解決方案。
爲了實現這3個目標,Istio 安全功能提供了4大守護系統:
 強大的身份(Identity)系統
 健壯的策略(Policy)系統
 認證,授權和審計(AAA:Authentication,Authorization,Accounting)系統,用於保護服務和數據
 透明的 TLS 加密(Encryption)系統。
就保護對象而言,Istio 安全系統可以抵禦來自內部或外部的威脅,這些威脅主要針對服務網格內的端點(Endpoints),通信(Communication),平臺(Platform)和數據(Data)。

2 Istio具體如何保護服務?
在安全方面,Istio具備3個遠大的目標,配備了4大守護系統,那麼它到底是通過怎樣的架構實現這個目標的呢,又通過什麼樣的安全基礎設施,和kubernetes配合呢?

2.1 Istio安全架構
Istio技術與實踐6:Istio如何爲服務提供安全防護能力
如上圖,與Istio的4大守護系統相對應,Istio 中涉及安全的組件有:
 Pilot :將授權策略和安全命名信息分發給代理
 Proxy :實現客戶端和服務端之間的安全通信
 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方案的配置過程:

  1. Citadel 監視 Kubernetes apiserver,爲每個現有和新的服務帳戶創建 SPIFFE 證書和密鑰對。 Citadel 將證書和密鑰對存儲爲 Kubernetes secrets。
  2. 創建 pod 時,Kubernetes 會根據其服務帳戶通過 Kubernetes secret volume 將證書和密鑰對掛載到 pod。
  3. Citadel 監視每個證書的生命週期,並通過重寫 Kubernetes secret 自動輪換證書。
  4. 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。
Istio技術與實踐6:Istio如何爲服務提供安全防護能力
本文多次提到雙向TLS認證,讓我們理解一下其在Istio裏的實現。Istio 通過客戶端和服務端各自配備的Envoy進行通信,也就是說,客戶端和服務端的流量,是被各自的Envoy接管了的。對於客戶端調用服務端,遵循的步驟是:

  1. Istio 將出站流量從客戶端重新路由到客戶端的本地 Envoy。
  2. 客戶端 Envoy 與服務端 Envoy 開始雙向 TLS 握手。在握手期間,客戶端 Envoy 還執行安全命名檢查,以驗證服務證書中提供的服務帳戶是否有權運行目標服務。
  3. 客戶端 Envoy 和服務端 Envoy 建立了一個雙向的 TLS 連接,Istio 將流量從客戶端 Envoy 轉發到服務端 Envoy。
  4. 授權後,服務端 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技術與實踐6:Istio如何爲服務提供安全防護能力
上圖顯示了基本的 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就可以完成對認證和授權環節所有功能的配置,而不需要侵入地改動任何服務的代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章