Istio v1beta1 授权策略概述

Istio v1beta1 授权策略的设计原则、基本概述及迁移操作。

Nov 14, 2019 | By Yangmin Zhu - Google

Istio 1.4 引入了 v1beta1 授权策略,这是对 以前 v1alpha1 的基于角色的访问控制(RBAC)策略的重要更新。包括以下改进:

v1beta1 策略不向后兼容,需要一次转换。Istio 提供了一个工具来自动执行此过程。 Istio 1.6 以后将不再支持先前的配置资源 ClusterRbacConfigServiceRoleServiceRoleBinding

本文描述了新的 v1beta1 授权策略模型、设计目标和从 v1alpha1 RBAC 策略的迁移。 有关 v1beta1 授权策略的详细说明,请参见 authorization concept 页面。

我们欢迎您在 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 将替换 ServiceRoleBindingServiceRole 中的其他字段。

示例

以下授权策略适用于 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 即可选择入口或出口工作负载。

以下策略适用于具有 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
策略目标serviceworkload
默认拒绝行为通过显式的配置 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
groupto 字段下的 paths
source.ip 属性from 字段下的 ipBlocks
source.namespace 属性from 字段下的 namespaces
source.principal 属性from 字段下的 principals
request.headers 属性when 字段下的 request.headers
request.auth.principal 属性from 字段下的 requestPrincipalswhen 字段下的 request.auth.principal
request.auth.audiences 属性when 字段下的 request.auth.audiences
request.auth.presenter 属性when 字段下的 request.auth.presenter
request.auth.claims 属性when 字段下的 request.auth.claims

除了所有差异之外,与 v1alpha1 类似,v1beta1 策略也由 Envoy 引擎强制执行,并支持同样的身份验证(双向 TLS 或 JWT)、条件和其他基元(如 IP、端口等)。

未来的 v1alpha1 策略

v1alpha1 RBAC 策略(ClusterRbacConfigServiceRoleServiceRoleBinding)将被 v1beta1 授权策略替代并弃用。

Istio 1.4 继续支持 v1alpha1 RBAC 策略,以便使您有足够的时间完成迁移。

v1alpha1 策略迁移

对于给定的工作负载,Istio 仅支持两个版本之一:

一般准则

迁移到 v1beta1 策略的典型流程是首先检查 ClusterRbacConfig,以确定哪些命名空间或服务启用了 RBAC。

对于启用了 RBAC 的每个服务:

  1. 从服务定义中获取工作负载选择器。
  2. 使用工作负载选择器创建一个 v1beta1 策略。
  3. 根据应用与服务的每个 ServiceRoleServiceRoleBinding 更新 v1beta1 策略。
  4. 应用该 v1beta1 策略并监视流量,以确保该策略按预期工作。
  5. 对启用了 RBAC 的下一个服务重复该过程。

对于启用了 RBAC 的每个命名空间:

  1. 把拒绝所有流量的 v1beta1 策略应用到给定的命名空间。

迁移示例

假设在 foo 命名空间中您有以下 v1alpha1 策略用于 httpbin 服务:

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 的全部语义。

支持完整 v1alpha1 语义的命令预计在 Istio 1.4 之后的修补程序版本中发布。