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的配置模型
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 以白名单方式授权
(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 临时关闭所有授权
(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 临时开启所有授权
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"]