Istio服务授权策略AuthorizationPolicy详解 –《Istio权威指南》书摘

本节书摘来自华为云原生技术丛书《Istio权威指南(上):云原生服务网格Istio原理与实践》一书原理篇的第5章 服务安全的原理,5.4节AuthorizationPolicy(服务授权策略),更多内容请参照原书

第5章 服务安全的原理

Istio以非侵入方式透明地提供面向应用的安全基础设施。在Istio中有两种不同的认证方式:①基于mTLS的对等身份认证;②基于JWT(JSON Web Token)令牌的服务请求认证。本章重点介绍这两种认证方式,以及基于这两种认证方式的细粒度的服务访问授权,会详细介绍其中认证、授权的通用原理、模型,以及Istio基于服务网格形态的实现原理和机制。本章还会详细介绍如何通过配置PeerAuthentication、RequestAuthentication和AuthorizationPolicy使用这些认证、授权能力。

5.4 AuthorizationPolicy(服务授权策略)

认证的大部分应用场景最终是基于授权的访问控制,以上两种认证策略也大多配套本节的授权策略使用。从Istio 1.4开始引入的AuthorizationPolicy替代了之前ClusterRbacConfig、ServiceRole和ServiceRoleBinding三个对象来进行授权配置,避免了配置多个API的麻烦,AuthorizationPolicy的自身功能也非常丰富。

5.4.1 入门示例

在如下示例中定义了作用于forecast负载v2版本的AuthorizationPolicy:来自cluster.local/ns/weather/sa/frontend的服务,当其携带的请求头域group是admin,并且通过PUT和POST方法访问目标服务才被允许时,其他条件的访问都会被拒绝:

 1apiVersion: security.istio.io/v1beta1
 2kind: AuthorizationPolicy
 3metadata:
 4 name: forecast
 5 namespace: weather
 6spec:
 7 selector:
 8   matchLabels:
 9     app: forecast
10     version: v2
11 rules:
12 - from:
13   - source:
14       principals: ["cluster.local/ns/weather/sa/frontend"]
15   to:
16   - operation:
17       methods: ["PUT","POST"]
18   when:
19   - key: request.headers[group]
20     values: ["admin"]

5.4.2 配置模型

AuthorizationPolicy的配置模型如图5-16所示,主要包括以下三部分。

◎ selector:描述策略应用的目标对象。

◎ rules:描述详细的访问控制规则。

◎ action:定义满足rule规则后执行的动作是允许还是拒绝。

图5-16  AuthorizationPolicy的配置模型

​ 图5-16 AuthorizationPolicy的配置模型

rule的规则主体由from、to和when构成,从字面上也能大致理解其各自的意思。这样,AuthorizationPolicy的配置模型也如图5-16所示,即通过selector给目标负载定义授权策略:对于从from发起的访问to的请求,当满足在when里定义的Condition条件时,执行action动作。

5.4.3 配置定义

AuthorizationPolicy包括三个核心配置:selector、action和rules,selector、action相对简单,本节重点介绍rules的灵活用法。

选择器selector是个通用的结构,用于描述AuthorizationPolicy生效的负载,和前面两个认证策略的选择器用法类似。比如,在5.4.1节的示例中,selector通过app和version两个标签将AuthorizationPolicy应用到forecast v2版本的负载上:

1spec:
2 selector:
3   matchLabels:
4     app: forecast
5     version: v2

授权动作action表示匹配条件后执行的动作,取值有ALLOW、DENY、AUDIT和CUSTOM。其中的默认值是ALLOW,表示匹配条件的请求授权允许;类似的DENY表示匹配条件的请求授权禁止;AUDIT表示匹配的请求会被审计,需要对应的插件Plugin支持;CUSTOM表示可扩展来进行授权判定,配合provider字段定义外置的授权扩展。

AuthorizationPolicy的核心主体rules是一个规则数组,描述匹配请求的一组规则。如果在这组规则中有一个规则匹配请求,则匹配成功。如果没有设置rules,则表示总是不匹配。rules数组中的每个规则rule都通过from、to和when三部分描述。

1)from(请求来源)

from描述请求来源的相关属性,可以不设置,表示匹配所有来源的请求。当在from中包含多个属性匹配条件时,要求满足所有条件。AuthorizationPolicy的from条件如表5-1所示,可以看到,为了方便规则定义,几个条件字段除提供了常用的正向匹配,也都提供了负向的匹配条件。

如下配置表示来源是cluster.local/ns/weather/sa/frontend身份的服务,并且IP地址不是10.2.0.0/16网段,或者来自default命名空间的请求。其中,两个from数组间是或关系,from元素内部的各个条件间是与关系。

1from:
2  - source:
3      principals:
4        - cluster.local/ns/weather/sa/frontend
5      notIpBlocks:
6        - 10.2.0.0/16
7  - source:
8      namespaces:
9        - default

表5-1中principals、notPrincipals、namespaces和notNamespaces等条件需要启用mTLS才能生效。在如下授权条件定义中,来自bff的命名空间的服务访问会被拒绝,但如果未启用mTLS,则因为源命名空间条件匹配不成功,不满足这个授权条件,该访问被允许通过:

1spec:
2  action: DENY
3  rules:
4  - from:
5    - source:
6        namespaces: ["bff"]

注意:在AuthorizationPolicy中如果配置了依赖mTLS才能提取的属性,但是未启用mTLS,则会导致请求总被允许。

另外,表5-1中的两个字段ipBlocks/notIpBlocks和remoteIpBlocks/notRemoteIpBlocks,前者匹配到达服务网格的IP地址,后者匹配真正的访问者的源IP地址。当经过七层代理时,源IP地址可以从X-Forwarded-For头域中获取;当经过四层代理并启用了代理协议时,源IP地址可以从代理协议中获取。在实际的授权配置中,remoteIpBlocks/ notRemoteIpBlocks的应用更广泛一些。

2)to(目标服务操作)

to条件描述对目标服务的操作属性。若不设置to条件,则表示匹配所有操作。AuthorizationPolicy的to条件如表5-2所示,匹配请求中的对应信息。to条件也提供了规则的正向匹配和负向匹配的字段定义。

如下示例表示匹配host是cloudnative-istio.book后缀的GET请求,或路径不是/admin前缀的PUT或POST请求:

 1to:
 2  - operation:
 3      methods:
 4        - GET
 5      hosts:
 6        - '*.cloudnative-istio.book'
 7  - operation:
 8      methods:
 9        - PUT
10        - POST
11      notPaths:
12        - /admin*
3)when(请求条件)

when描述请求的附加条件,当不设置时,表示匹配任何条件的请求。AuthorizationPolicy的when条件如表5-3所示,基于请求的内容可以进行丰富的条件定义。类似from和to条件,when中的条件表达式也提供了针对特定属性的正向匹配和负向匹配。

如下配置条件匹配HTTP请求头域中版本标识是v1和v2的请求:

1  when:
2   - key: request.headers[version]
3     values: ["v1", "v2"]

有些条件,例如请求主体身份,既可以在from中通过requestPrincipals定义,也可以在when中通过request.auth.principal定义。同样,when中的source.principal和source.namespace也需要启用mTLS,当未启用时,也会碰到前面from对应字段类似的问题。source.ip和remote.ip的用法与前面的ipBlocks/notIpBlocks和remoteIpBlocks/ notRemoteIpBlocks完全相同。

5.4.4 典型应用

AuthorizationPolicy可以配置的信息很丰富,多种条件搭配能支持的场景也非常多,下面通过几个典型场景了解如何解决我们的实际问题。

1. 认证身份访问和非认证身份访问

在AuthorizationPolicy中可以通过将source的principals设置为通配符“*”来表示只匹配认证的身份。在如下示例中只有认证的身份可以通过多个HTTP方法访问weather命名空间的服务:

 1apiVersion: security.istio.io/v1beta1
 2kind: AuthorizationPolicy
 3metadata:
 4  name: all-method-for-identity
 5  namespace: weather
 6spec:
 7  action: ALLOW
 8  rules:
 9    - from:
10        - source:
11            principals: ["*"]
12      to:
13        - operation:
14            methods: ["GET", "POST", "PUT", "DELETE"]

将soucre设置为空,表示所有认证和非认证的身份均可访问。在如下示例中,所有身份都可以通过GET方式访问开放的接口:

 1apiVersion: security.istio.io/v1beta1
 2kind: AuthorizationPolicy
 3metadata:
 4 name: get-only-for-unidentified
 5 namespace: weather
 6spec:
 7action: ALLOW
 8 rules:
 9   to:
10   - operation:
11       methods: ["GET"]
2. TCP服务访问授权

Istio授权主要应用于应用的访问授权,可以看到rule的条件大多定义在HTTP上。但也有部分条件定义在TCP上,可以配置对TCP的流量进行授权管理。在如下示例中,只允许来自特定网段的服务访问目标forecast的3002端口:

 1apiVersion: security.istio.io/v1beta1
 2kind: AuthorizationPolicy
 3metadata:
 4  name: tcp-auth-policy
 5  namespace: weather
 6spec:
 7 selector:
 8   matchLabels:
 9     app: forecast
10 action: ALLOW
11 rules:
12 - from:
13   - source:
14       ipBlocks: ["10.2.0.0/16"]
15   to:
16   - operation:
17       ports: ["3002"]
3. JWT服务请求授权

基于认证的授权不但可以是常用的基于证书认证的身份标识,也可以是基于服务请求的认证。在如下示例中,只有携带特定认证标识的请求才可以访问目标服务的特定接口,这个标识既可以通过when条件的request.auth.principal配置,也可以通过from条件的requestPrincipals直接配置:

 1apiVersion: security.istio.io/v1beta1
 2kind: AuthorizationPolicy
 3metadata:
 4 name: forecast
 5 namespace: weather
 6spec:
 7  rules:
 8  - from:
 9    - source:
10        namespaces: ["default"]
11    to:
12    - operation:
13        methods: ["GET"]
14        paths: ["/list"]
15    when:
16    - key: request.auth.claims[iss]
17      values: ["weather@cloudnative-istio.book"]
4. 服务网格入口流量访问授权

AuthorizationPolicy除了可以用来控制内部服务间的访问,还可以用来控制服务网格出入流量的授权管理。在如下示例中可以只允许特定IP段的外部流量通过网关访问服务网格管理的服务,AuthorizationPolicy的selector选中Ingress-gateway,将策略应用到网关上。当然,这类基于源IP地址的访问授权的前提是保证网关能获取访问的源IP地址:

 1apiVersion: security.istio.io/v1beta1
 2kind: AuthorizationPolicy
 3metadata:
 4  name: ingress-authz-policy
 5  namespace: istio-system
 6spec:
 7  selector:
 8    matchLabels:
 9      app: istio-ingressgateway
10  action: ALLOW
11  rules:
12  - from:
13    - source:
14        ipBlocks: ["10.2.0.0/16"]
5. 全局授权控制

Istio中基于优先级的授权策略可以方便地支持以下全局授权控制场景。

(1)以白名单方式授权。在比较严格的授权管理场景中,我们经常采用白名单的方式进行授权管理,即只允许名单中的服务访问,对其他服务都拒绝。在如下示例中,不配置AuthorizationPolicy中的规则rules,就不会匹配任何条件。如图5-17所示,这个策略会拒绝所有的授权访问,只有特定的条件开启了授权,才允许访问。

1apiVersion: security.istio.io/v1beta1
2kind: AuthorizationPolicy
3metadata:
4  name: allow-nothing-for-whitelist
5namespace: weather
6spec:
7  action: ALLOW

图5-17 以白名单方式授权

​ 图5-17 以白名单方式授权

(2)临时关闭所有授权。权限管理在大多数时候都是极其复杂的,多变、复杂的业务需求落实在灵活的授权体系上,有时还会出现各种权限漏洞问题,比如一些本来不应该有权限的访问莫名地被授权允许了。如果是一个重要的服务或接口有安全漏洞,那就需要强制将所有授权都临时关闭。

在如下AuthorizationPolicy配置中,rules的空结构表示匹配所有请求,而动作是拒绝,结果如图5-18所示,不管其他AuthorizationPolicy的内容是什么,通过这个策略就可以拒绝所有的访问授权:

1apiVersion: security.istio.io/v1beta1
2kind: AuthorizationPolicy
3metadata:
4  name: authz-deny-all
5namespace: weather
6spec:
7  action: DENY
8  rules:
9  - {}

图5-18 临时关闭所有授权

​ 图5-18 临时关闭所有授权

(3)临时开启所有授权。除了上面可以通过一个全匹配的AuthorizationPolicy临时关闭所有授权,也可以如图5-19所示,通过一个全匹配的AuthorizationPolicy临时开启所有条件的访问授权。当然,用户配置的动作为DENY或CUSTOM的授权不受影响。

1apiVersion: security.istio.io/v1beta1
2kind: AuthorizationPolicy
3metadata:
4  name: authz-allow-all
5namespace: weather
6spec:
7  action: ALLOW
8  rules:
9  - {}

图5-19 临时开启所有授权

​ 图5-19 临时开启所有授权

6. 外部授权配置

实际使用中的授权判定逻辑一般业务性较强。AuthorizationPolicy可以通过CUSTOM定义一个扩展动作。这个CUSTOM动作在默认的ALLOW和DENY动作前执行。一般设置授权动作为CUSTOM,并通过provider配置一个外置的授权服务。当满足条件的请求到来时,通过外部授权服务custom-authz进行授权判定:

 1apiVersion: security.istio.io/v1beta1
 2kind: AuthorizationPolicy
 3metadata:
 4 name: custom-authz
 5 namespace: weather
 6spec:
 7action: CUSTOM
 8 provider:
 9   name: "custom-authz"
10 rules:
11 - to:
12   - operation:
13       methods: ["PUT","POST"]