介紹 Istio v1beta1 授權策略

Istio v1beta1 授權策略的介紹、動機和設計原則。

2019 年 11 月 14 日 | 作者:Yangmin Zhu - Google

Istio 1.4 引入了v1beta1 授權策略,這是對先前 v1alpha1 基於角色的存取控制 (RBAC) 策略的重大更新。新策略提供了以下改進:

v1beta1 策略不向下相容,需要進行一次性轉換。提供了一個工具來自動化此過程。從 Istio 1.6 開始,將不再支援先前的配置資源 ClusterRbacConfigServiceRoleServiceRoleBinding

這篇文章描述了新的 v1beta1 授權策略模型、其設計目標以及從 v1alpha1 RBAC 策略的遷移。請參閱授權概念頁面,以深入了解 v1beta1 授權策略的詳細說明。

我們歡迎您在 discuss.istio.io 上提供關於 v1beta1 授權策略的回饋。

背景

到目前為止,Istio 提供了 RBAC 策略,以使用三個配置資源來強制執行對服務的存取控制:ClusterRbacConfigServiceRoleServiceRoleBinding。透過這個 API,使用者能夠在網格級別、命名空間級別和服務級別強制執行存取控制。與其他 RBAC 策略一樣,Istio RBAC 使用相同的角色和綁定概念,來授予身份權限。

儘管 Istio RBAC 一直可靠地運行,但我們發現仍有許多改進空間。

例如,使用者錯誤地認為存取控制的強制執行發生在服務級別,因為 ServiceRole 使用服務來指定套用策略的位置,但是,該策略實際上是套用在工作負載,該服務僅用於查找相應的工作負載。當多個服務引用同一個工作負載時,這種細微差異非常重要。如果兩個服務引用同一個工作負載,則對服務 A 的 ServiceRole 也會影響服務 B,這可能會導致混淆和錯誤的配置。

另一個例子是,由於需要深入了解三個相關的資源,因此使用者很難維護和管理 Istio RBAC 配置。

設計目標

新的 v1beta1 授權策略有幾個設計目標:

AuthorizationPolicy

AuthorizationPolicy 自訂資源啟用對工作負載的存取控制。本節概述 v1beta1 授權策略中的變更。

AuthorizationPolicy 包含一個 selector 和一個 rule 列表。selector 指定在哪個工作負載上套用該策略,而 rule 列表指定該工作負載的詳細存取控制規則。

rule 是累加的,這表示如果任何 rule 允許該請求,則該請求將被允許。每個 rule 都包含一個 fromtowhen 的列表,指定在哪些條件下,被允許做什麼

selector 取代了 ClusterRbacConfigServiceRole 中的 services 欄位提供的功能。rule 取代了 ServiceRoleServiceRoleBinding 中的其他欄位。

範例

以下授權策略適用於在 foo 命名空間中具有 app: httpbinversion: v1 標籤的工作負載

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 selector:
   matchLabels:
     app: httpbin
     version: v1
 rules:
 - from:
   - source:
       principals: ["cluster.local/ns/default/sa/sleep"]
   to:
   - operation:
       methods: ["GET"]
   when:
   - key: request.headers[version]
     values: ["v1", "v2"]

該策略允許主體 cluster.local/ns/default/sa/sleep 在請求包含值為 v1v2version 標頭時,使用 GET 方法存取工作負載。任何與策略不符的請求都將預設被拒絕。

假設 httpbin 服務定義為

apiVersion: v1
kind: Service
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    app: httpbin
    version: v1
  ports:
    # omitted

您需要在 v1alpha1 中配置三個資源才能達到相同的結果

apiVersion: "rbac.istio.io/v1alpha1"
kind: ClusterRbacConfig
metadata:
  name: default
spec:
  mode: 'ON_WITH_INCLUSION'
  inclusion:
    services: ["httpbin.foo.svc.cluster.local"]
---
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: httpbin
  namespace: foo
spec:
  rules:
  - services: ["httpbin.foo.svc.cluster.local"]
    methods: ["GET"]
    constraints:
    - key: request.headers[version]
      values: ["v1", "v2"]
---
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: httpbin
  namespace: foo
spec:
  subjects:
  - user: "cluster.local/ns/default/sa/sleep"
  roleRef:
    kind: ServiceRole
    name: "httpbin"

工作負載選擇器

v1beta1 授權策略的一個主要變更在於,它現在使用工作負載選擇器來指定在哪裡套用該策略。這與 GatewaySidecarEnvoyFilter 配置中使用的相同工作負載選擇器。

工作負載選擇器清楚地表明,該策略是套用和強制執行在工作負載上,而不是服務上。如果一個策略套用到被多個不同服務使用的工作負載,則相同的策略將影響所有不同服務的流量。

您可以簡單地將 selector 留空,以將該策略套用到命名空間中的所有工作負載。以下策略適用於 bar 命名空間中的所有工作負載

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: policy
 namespace: bar
spec:
 rules:
 # omitted

根命名空間

根命名空間中的策略適用於每個命名空間中網格中的所有工作負載。根命名空間可在MeshConfig 中配置,預設值為 istio-system

例如,您在 istio-system 命名空間中安裝了 Istio,並在 defaultbookinfo 命名空間中部署了工作負載。根命名空間從預設值變更為 istio-config。以下策略將適用於每個命名空間(包括 defaultbookinfoistio-system)中的工作負載

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: policy
 namespace: istio-config
spec:
 rules:
 # omitted

Ingress/Egress 閘道支援

v1beta1 授權策略也可以套用到 Ingress/Egress 閘道,以強制執行進入/離開網格的流量存取控制,您只需變更 selector 以選擇 Ingress/Egress 工作負載即可。

以下策略適用於具有 app: istio-ingressgateway 標籤的工作負載

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: ingress
 namespace: istio-system
spec:
 selector:
   matchLabels:
     app: istio-ingressgateway
 rules:
 # omitted

請記住,授權策略僅適用於與策略相同的命名空間中的工作負載,除非該策略套用在根命名空間中

比較

下表重點說明了舊的 v1alpha1 RBAC 策略和新的 v1beta1 授權策略之間的關鍵差異。

功能

功能v1alpha1 RBAC 策略v1beta1 授權策略
API 穩定性alpha向下相容beta保證向下相容
CRD 的數量三個:ClusterRbacConfigServiceRoleServiceRoleBinding只有一個:AuthorizationPolicy
策略目標服務工作負載
預設拒絕行為透過配置 ClusterRbacConfig 明確啟用使用 AuthorizationPolicy 隱式啟用
Ingress/Egress 閘道支援不支援支援
策略中的 "*"比對所有內容(空白和非空白)僅比對非空白內容

下表顯示了 v1alpha1v1beta1 API 之間的關係。

ClusterRbacConfig

ClusterRbacConfig.ModeAuthorizationPolicy
OFF未套用任何策略
ON在根命名空間中套用拒絕所有策略
ON_WITH_INCLUSION策略應套用於 ClusterRbacConfig 中包含的命名空間或工作負載
ON_WITH_EXCLUSION策略應套用於 ClusterRbacConfig 中排除的命名空間或工作負載

ServiceRole

ServiceRoleAuthorizationPolicy
servicesselector
pathsto 中的 paths
methodsto 中的 methods
限制中的 destination.ip不支援
限制中的 destination.portto 中的 ports
限制中的 destination.labelsselector
限制中的 destination.namespace由策略的命名空間取代,即中繼資料中的 namespace
限制中的 destination.user不支援
限制中的 experimental.envoy.filterswhen 中的 experimental.envoy.filters
限制中的 request.headerswhen 中的 request.headers

ServiceRoleBinding

ServiceRoleBindingAuthorizationPolicy
userfrom 中的 principals
groupwhen 中的 request.auth.claims[group]
屬性中的 source.ipfrom 中的 ipBlocks
屬性中的 source.namespacefrom 中的 namespaces
屬性中的 source.principalfrom 中的 principals
屬性中的 request.headerswhen 中的 request.headers
屬性中的 request.auth.principalfrom 中的 requestPrincipalswhen 中的 request.auth.principal
屬性中的 request.auth.audienceswhen 中的 request.auth.audiences
屬性中的 request.auth.presenterwhen 中的 request.auth.presenter
屬性中的 request.auth.claimswhen 中的 request.auth.claims

儘管存在所有差異,v1beta1 策略與 Envoy 中使用的引擎相同,並支援與 v1alpha1 策略相同的已驗證身分(相互 TLS 或 JWT)、條件和其他基本要素(例如 IP、埠等等)。

v1alpha1 策略的未來

v1alpha1 RBAC 策略(ClusterRbacConfigServiceRoleServiceRoleBinding)已被 v1beta1 授權策略棄用。

Istio 1.4 將繼續支援 v1alpha1 RBAC 策略,讓您有足夠的時間從 alpha 策略中轉移。

v1alpha1 策略遷移

針對給定的工作負載,Istio 僅支援兩個版本之一

一般指南

遷移到 v1beta1 策略的典型流程是先檢查 ClusterRbacConfig 以決定哪個命名空間或服務啟用了 RBAC。

對於每個啟用 RBAC 的服務

  1. 從服務定義中取得工作負載選擇器。
  2. 使用工作負載選擇器建立 v1beta1 策略。
  3. 更新應用於服務的每個 ServiceRoleServiceRoleBindingv1beta1 策略。
  4. 套用 v1beta1 策略並監控流量,以確保該策略如預期運作。
  5. 針對下一個啟用 RBAC 的服務重複此流程。

對於每個啟用 RBAC 的命名空間

  1. 套用一個 v1beta1 策略,拒絕所有流向給定命名空間的流量。

遷移範例

假設您在 foo 命名空間中,對 httpbin 服務有以下 v1alpha1 策略

apiVersion: "rbac.istio.io/v1alpha1"
kind: ClusterRbacConfig
metadata:
  name: default
spec:
  mode: 'ON_WITH_INCLUSION'
  inclusion:
    namespaces: ["foo"]
---
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: httpbin
  namespace: foo
spec:
  rules:
  - services: ["httpbin.foo.svc.cluster.local"]
    methods: ["GET"]
---
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: httpbin
  namespace: foo
spec:
  subjects:
  - user: "cluster.local/ns/default/sa/sleep"
  roleRef:
    kind: ServiceRole
    name: "httpbin"

以以下方式將上述策略遷移到 v1beta1

  1. 假設 httpbin 服務具有以下工作負載選擇器

    selector:
      app: httpbin
      version: v1
    
  2. 使用工作負載選擇器建立 v1beta1 策略

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: httpbin
     namespace: foo
    spec:
     selector:
       matchLabels:
         app: httpbin
         version: v1
    
  3. 使用應用於服務的每個 ServiceRoleServiceRoleBinding 更新 v1beta1 策略

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: httpbin
     namespace: foo
    spec:
     selector:
       matchLabels:
         app: httpbin
         version: v1
     rules:
     - from:
       - source:
           principals: ["cluster.local/ns/default/sa/sleep"]
       to:
       - operation:
           methods: ["GET"]
    
  4. 套用 v1beta1 策略並監控流量,以確保其如預期運作。

  5. 套用以下 v1beta1 策略,拒絕所有流向 foo 命名空間的流量,因為 foo 命名空間已啟用 RBAC

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: deny-all
     namespace: foo
    spec:
     {}
    

確保 v1beta1 策略如預期運作,然後您可以從叢集中刪除 v1alpha1 策略。

自動化遷移

為了協助簡化遷移,提供了 istioctl experimental authz convert 命令,以自動將 v1alpha1 策略轉換為 v1beta1 策略。

您可以評估該命令,但在 Istio 1.4 中,它仍處於實驗階段,並且截至本部落格文章發布之日,尚未完全支援 v1alpha1 語意。

預計在 Istio 1.4 後的修補程式版本中,將提供支援完整 v1alpha1 語意的命令。

分享此文章