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

PaaS小魔仙發表於2018-09-11

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

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

那麼,便引出 3 個問題:

l   Istio 憑什麼保護服務?

l   Istio 具體 如何保護服務?

l   如何告訴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 中涉及安全的元件有:

l   Pilot :將授權策略和安全命名資訊分發給代理

l   Proxy :實現客戶端和服務端之間的安全通訊

l   Citadel :用於金鑰和證書管理

l   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 就可以完成對認證和授權環節所有功能的配置,而不需要侵入地改動任何服務的程式碼。

https://www.huaweicloud.com/product/cce.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31543630/viewspace-2213963/,如需轉載,請註明出處,否則將追究法律責任。

相關文章