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

凡是產生鏈接關係,就一定帶來安全問題,人類社會如此,服務網格世界,亦是如此。html

今天,咱們就來談談Istio第二主打功能---保護服務。面試

那麼,便引出3個問題:api

Istio憑什麼保護服務?瀏覽器

Istio具體如何保護服務?安全

如何告訴Istio發揮保護能力?網絡

1      Istio憑什麼保護服務?

將單體應用程序分解爲一個個服務,爲大型軟件系統的開發和維護帶來了諸多好處,好比更好的靈活性、可伸縮性和可複用性。但這也帶來了一些安全問題:架構

l  爲了抵禦中間人攻擊,須要對流量進行加密運維

l  爲了提供靈活的服務訪問控制,須要 mTLS(雙向的安全傳輸層協議)和細粒度的訪問策略工具

l  要審計誰在何時作了什麼,須要審計工具性能

Istio 嘗試提供全面的安全解決方案來解決這3個問題。

 

如上圖所示,

Istio 安全的三大目標是:

l  默認安全(Security by default):應用程序代碼和基礎結構,無需更改。

l  深度防護(Defense in depth):與現有安全系統集成,提供多層防護。

l  零信任網絡(Zero-trust network):在不受信任的網絡上,構建安全解決方案。

爲了實現這3個目標,Istio 安全功能提供了4大守護系統:

l  強大的身份(Identity)系統

l  健壯的策略(Policy)系統

l  認證,受權和審計(AAA:Authentication,Authorization,Accounting)系統,用於保護服務和數據

l  透明的 TLS 加密(Encryption)系統。

就保護對象而言,Istio 安全系統能夠抵禦來自內部或外部的威脅,這些威脅主要針對服務網格內的端點(Endpoints),通訊(Communication),平臺(Platform)和數據(Data)。

2      Istio具體如何保護服務?

在安全方面,Istio具有3個遠大的目標,配備了4大守護系統,那麼它究竟是經過怎樣的架構實現這個目標的呢,又經過什麼樣的安全基礎設施,和kubernetes配合呢?

2.1      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 服務標識:

l  Kubernetes: Kubernetes 服務賬戶

l  GKE/GCE: 可使用 GCP 服務賬戶

l  AWS: AWS IAM 用戶/角色 賬戶

l  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 提供兩種類型的身份認證:

l  傳輸身份認證,也稱爲服務到服務身份認證:對直連客戶端進行驗證。Istio 提供雙向TLS做爲傳輸身份認證的全棧解決方案。咱們能夠輕鬆啓用此功能,而無需更改服務代碼。這個解決方案:

l  爲每一個服務提供強大的身份認定,以實現跨羣集和跨雲的互操做性。

l  保護服務到服務通訊和最終用戶到服務通訊。

l  提供密鑰管理系統,以自動執行密鑰和證書生成,分發和輪換。

l  來源身份認證,也稱爲終端用戶身份認證:對來自終端用戶或設備的原始客戶端請求進行驗證。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接管了的。對於客戶端調用服務端,遵循的步驟是:

  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 服務網格中的服務提供命名空間級別,服務級別和方法級別的訪問控制。它的特色是:

l  基於角色的語義,簡單易用。

l  包含服務到服務和終端用戶到服務兩種受權模式。

l  經過自定義屬性靈活定製受權策略,例如條件,角色和角色綁定。

l  高性能,由於 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值,它能夠是:

l  OFF:禁用 Istio 受權。

l  ON:爲網格中的全部服務啓用了 Istio 受權。

l  ON_WITH_INCLUSION:僅對包含字段中指定的服務和命名空間啓用 Istio 受權。

l  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 組合規定了: 容許誰在哪些條件下作什麼,具體而言:

l  誰指的是 ServiceRoleBinding 中的 subject 部分。

l  作什麼指的是 ServiceRole 中的 rule 部分。

l  哪些條件指的是咱們能夠在 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就能夠完成對認證和受權環節全部功能的配置,而不須要侵入地改動任何服務的代碼。

相關文章
相關標籤/搜索