通过上一部分认证架构可以了解到,认证策略是对服务收到的请求生效的。要在双向 TLS 中指定客户端认证策略,需要在 DetinationRule 中设置 TLSSettings。使用者可以通过yaml文件来编写认证策略,然后使用 istioctl 进行部署。
例如,要求 reviews 服务必须使用双向 TLS:
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "reviews"
spec:
targets:
- name: reviews
peers:
- mtls: {}
Istio 可以在命名空间范围或Mesh范围存储中存储身份认证策略。
配置 MeshPolicy
,指定
Mesh
范围策略,名称为
default
:
apiVersion: "authentication.istio.io/v1alpha1"
kind: "MeshPolicy"
metadata:
name: "default"
spec:
peers:
- mtls: {}
配置Policy,指定命名空间范围策略。例如命名空间myns,如不指定,则是默认命名空间:
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "default"
namespace: "myns"
spec:
peers:
- mtls: {}
命名空间范围存储中的策略只能影响同一命名空间中的服务。Mesh范围内的策略可以影响Mesh中的所有Istio服务。防止冲突和滥用,只能在Mesh范围存储中定义一个策略。该策略必须命名为 default 并且有一个空的 targets: 部分。
身份认证策略的目标指定策略适用于哪些服务。以下示例展示的是一个 targets: 部分,指定该策略适用于:
targets:
- name: product-page
- name: reviews
ports:
- number: 9000
如果您未提供 targets: 部分,则 Istio 将策略与策略存储范围内的所有服务匹配。因此,targets: 部分可以帮助您指定策略的范围:
对于每项服务,Istio 都应用最窄的匹配策略。顺序是:特定服务>命名空间范围>网格范围。如果多个特定于服务的策略与服务匹配,则 Istio 随机选择其中一个。运维人员在配置其策略时必须避免此类冲突。
值得注意的是,为了强制Mesh范围和命名空间范围的策略的唯一性,Istio 每个Mesh只接受一个身份认证策略,每个命名空间只接受一个身份认证策略。Istio 还要求Mesh范围和命名空间范围的策略具有特定名称 default。
peers: 部分定义了策略中传输身份验证支持的身份验证方法和相关参数。该部分可以列出多个方法,并且只有一个方法必须满足认证才能通过。但是,从 Istio 0.7 版本开始,当前支持的唯一传输身份验证方法是双向 TLS。如果您不需要传输身份验证,请完全跳过此部分。使用双向 TLS 启用传输身份验证的 peers: 部分:
peers:
- mtls: {}
目前(Istio1.1),双向 TLS 设置不需要任何参数。因此,-mtls: {}、- mtls: 或 - mtls: null 声明被视为相同。将来,双向 TLS 设置可以携带参数以提供不同的双向 TLS 实现。
origins: 部分定义了原始身份验证支持的身份验证方法和相关参数。Istio 仅支持 JWT 原始身份验证。策略支持多个JWT身份认证,与传输身份验证类似,必须满足身份验证才能通过。例如,该origin接受 Google 发布的 JWT:
origins:
- jwt:
issuer: "https://accounts.google.com"
jwksUri: "https://www.googleapis.com/oauth2/v3/certs"
主认证关系用键值对的方式存储绑定关系。默认情况下,Istio 使用 peers: 部分中配置的身份验证。如果在 peers: 部分中未配置身份验证,Istio 将保留身份验证。策略编写者可以使用 USE_ORIGIN 值覆盖此行为。此值将 Istio 配置为使用 origin 的身份验证作为主体身份验证。将来,Istio将支持条件绑定,如,当传输体为 X 时为 USE_PEER,否则为 USE_ORIGIN。以下示例显示了 principalBinding 键,其值为 USE_ORIGIN:
principalBinding: USE_ORIGIN
使用者可以随时更改身份认证策略。Istio 几乎实时地将更改推送到端点。但是,Istio 无法保证所有端点同时收到新策略。以下是在更新身份认证策略时避免中断的建议:
peers:
- mtls:
mode: PERMISSIVE
配置授权策略,需要指定两个Kubernetes CustomResourceDefinition( CRD)对象,ServiceRole 和 ServiceRoleBinding。
ServiceRole 和 ServiceRoleBinding 的组合规定:允许谁在哪些条件下做什么。对应相关字段:
ServiceRole规范包括规则和权限列表等。每条规范的标准字段如下:
ServiceRole 规范仅适用于 metadata 部分中指定的命名空间。规则中需要 services 和 methods 字段。 paths 是可选的。如果未指定规则或将其设置为 *,则它适用于任何实例。例如service-admin角色,以完全访问 default 命名空间中的所有服务:
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: service-admin
namespace: default
spec:
rules:
- services: ["*"]
methods: ["*"]
products-viewer角色有读取权限,包括 GET 和 HEAD,能够访问 default 命名空间中的 products.default.svc.cluster.local 服务。
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: products-viewer
namespace: default
spec:
rules:
- services: ["products.default.svc.cluster.local"]
methods: ["GET", "HEAD"]
此外,规则还支持所有字段的前缀匹配和后缀匹配。例如,您可以在 default命名空间中定义具有以下权限的 tester 角色:
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: tester
namespace: default
spec:
rules:
- services: ["test-*"]
methods: ["*"]
- services: ["bookstore.default.svc.cluster.local"]
paths: ["*/reviews"]
methods: ["GET"]
在 ServiceRole 中,namespace + services + paths + methods 的组合定义了如何访问服务。在某些情况下,您可能需要为规则指定其他条件。例如,规则可能仅适用于服务的某个版本,或仅适用于具有特定标签的服务,如 foo。您可以使用 constraints 轻松指定这些条件。
例如,下面的 ServiceRole 定义在以前的 products-viewer 角色基础之上添加了一个约束:request.headers[version] 为 v1 或 v2 。在约束和属性页面中列出了约束支持的 key 值。在属性值是 map 类型的情况下,例如 request.headers,key 是 map 中的一个条目,例如 request.headers[version]。
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: products-viewer-version
namespace: default
spec:
rules:
- services: ["products.default.svc.cluster.local"]
methods: ["GET", "HEAD"]
constraints:
- key: request.headers[version]
values: ["v1", "v2"]
ServiceRoleBinding 规范包括两部分:
您可以使用 user 或一组 properties 显式指定 *subject*。ServiceRoleBinding subject 中的 property 类似于 ServiceRole 规范中的 *constraint*。 property 还允许您使用条件指定分配给此角色的一组帐户。它包含一个 key 及其允许的*值*。约束支持的 key 值列在约束和属性页面中。
下面的例子显示了一个名为 test-binding-products 的 ServiceRoleBinding,它将两个 subject 绑定到名为 product-viewer 的 ServiceRole 并具有以下 subject
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: test-binding-products
namespace: default
spec:
subjects:
- user: "service-account-a"
- user: "istio-ingress-service-account"
properties:
request.auth.claims[email]: "[email protected]"
roleRef:
kind: ServiceRole
name: "products-viewer"
如果您想要公开访问服务,可以将 subject 设置为 user:"*" 。此值将 ServiceRole 分配给所有(经过身份验证和未经身份验证的)用户和服务,例如:
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: binding-products-allusers
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "products-viewer"
要将 ServiceRole 分配给经过身份验证的用户和服务,请使用 source.principal:"*" 代替,例如:
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
kind: ServiceRoleBinding
metadata:
name: binding-products-all-authenticated-users
namespace: default
spec:
subjects:
- properties:
source.principal: "*"
roleRef:
kind: ServiceRole
name: "products-viewer"
Istio 授权支持使用任何普通 TCP 协议的 service,例如 MongoDB。在这种情况下,您可以像配置 HTTP 服务一样配置 service role 和 service role binding。不同之处在于,某些字段、约束和属性不支持TCP协议的service,这些字段包括:
如果你在TCP service 中使用了任意 HTTP 特有的字段,Istio将会忽略它。您有一个 MongoDB service 在 27017 端口上监听,下面的示例配置了一个 service role 和一个 service role binding,仅允许 Istio 网格中的 `bookinfo-ratings-v2 访问 MongoDB service。
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: mongodb-viewer
namespace: default
spec:
rules:
- services: ["mongodb.default.svc.cluster.local"]
constraints:
- key: "destination.port"
values: ["27017"]
---
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: bind-mongodb-viewer
namespace: default
spec:
subjects:
- user: "cluster.local/ns/default/sa/bookinfo-ratings-v2"
roleRef:
kind: ServiceRole
name: "mongodb-viewer"
授权宽容模式(authorization permissive mode)是 Istio 1.1 发布版中的实验特性。其接口可能在未来的发布中发生变化,不建议在生产版本使用。授权宽容模式允许您在将授权策略提交到生产环境部署之前对其进行验证。
可以在全局授权配置和单个独立策略中启用授权宽容模式。如果在全局授权配置中设置,所有策略都将切换至授权宽容模式,不管其本身的模式。如果您设置全局授权模式为 ENFORCED,单个策略设置的强制模式将起作用。如果您没有设置任何模式,全局授权配置和单个策略都将默认被设置为 ENFORCED。
要全局启用宽容模式,将全局 Istio RBAC 授权配置中的 enforcement_mode: 设置为 PERMISSIVE,如下面的示例所示。
apiVersion: "rbac.istio.io/v1alpha1"
kind: ClusterRbacConfig
metadata:
name: default
spec:
mode: 'ON_WITH_INCLUSION'
inclusion:
namespaces: ["default"]
enforcement_mode: PERMISSIVE
如要为特定策略启用宽容模式,请将策略配置文件中的 mode: 设置为 PERMISSIVE,如下面的示例所示。
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: bind-details-reviews
namespace: default
spec:
subjects:
- user: "cluster.local/ns/default/sa/bookinfo-productpage"
roleRef:
kind: ServiceRole
name: "details-reviews-viewer"
mode: PERMISSIVE
虽然建议使用Istio 授权机制,但是Istio也支持其他授权插件,比如Mixer组件,它允许你插入自己的身份验证和授权机制。详情请了解Mixer使用和配置。