Istio v1beta1 授权策略简介

Istio v1beta1 授权策略的介绍、动机和设计原则。

2019年11月14日 | 作者:朱阳民 - 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 使用 GET 方法访问工作负载,前提是请求包含值为 v1v2version 标头。默认情况下,任何与策略不匹配的请求都将被拒绝。

假设 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

入口/出口网关支持

v1beta1 授权策略也可以应用于入口/出口网关,以对进入/离开网格的流量执行访问控制,您只需要更改 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
策略目标服务工作负载
默认拒绝行为通过配置 ClusterRbacConfig显式启用使用 AuthorizationPolicy隐式启用
入口/出口网关支持不支持支持
策略中的“*”值匹配所有内容(空和非空)仅匹配非空内容

下表显示了 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
用户from 中的 principals
when 条件中的 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 语义。

支持完整 v1alpha1 语义的命令预计将在 Istio 1.4 之后的补丁版本中提供。

分享此文章