本文为翻译文章,点击查看原文。
Istio提供了非常易用的安全解决方案,包括服务间身份验证mTLS,服务间访问控制RBAC,以及终端用户身份验证JWT等,本文主要介绍如何使用服务间访问控制,同时涉及双向TLS。
- Istio版本 1.1.0
- 在的github.com/hb-go/micro-mesh中有结合示例的RBAC配置实践可以参考
要实现RBAC主要理解以下几个类型的yaml配置,以及之间的关系:
- 双向TLS
Policy或MeshPolicy,上游server开启TLSDestinationRule,下游client开启TLS
- RBAC
ClusterRbacConfig`/RbacConfig`,启用授权及范围ServiceRole,角色权限规则ServiceRoleBinding,角色绑定规则
- Optional
ServiceAccount,ServiceRoleBinding`.subjects的user`条件
假设场景
- 网格内
service-1、service-2开启RBAC访问控制 - 仅
service-1授权给ingressgateway访问,service-2则不能被ingressgateway访问

双向TLS
1.上游server开启TLS
- 网格范围策略:在网格范围存储中定义的策略,没有目标选择器部分。网格中最多只能有一个网格范围的策略。
- 命名空间范围的策略:在命名空间范围存储中定义的策略,名称为 default 且没有目标选择器部分。每个命名空间最多只能有一个命名空间范围的策略。
- 特定于服务的策略:在命名空间范围存储中定义的策略,具有非空目标选择器部分。命名空间可以具有零个,一个或多个特定于服务的策略。
策略范围可以分别由Policy、MeshPolicy设置,Policy可以选择对命名空间所有服务生效,也可以指定targets对特定服务生效,MeshPolicy则是整个网格内生效,对于命名空间范围和网格范围名称都只能为default。
同时配置多个策略时使用最窄匹配策略,特定服务>命名空间范围>网格范围,如果多个特定于服务的策略与服务匹配,则随机选择一个。下面是不同策略范围的具体配置参考:
Policy特定于服务的策略
targets支持name以及ports列表
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "policy-name"
spec:
targets:
- name: service-name-1
- name: service-name-2
ports:
- number: 8080
peers:
- mtls: {}
---
Policy命名空间范围的策略
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "default"
namespace: "namespace-1"
spec:
peers:
- mtls: {}
---
MeshPolicy网格范围策略
apiVersion: "authentication.istio.io/v1alpha1"
kind: "MeshPolicy"
metadata:
name: "default"
spec:
peers:
- mtls: {}
---
2.下游client开启TLS
client端TLS由目标规则DestinationRule配置,在流量策略trafficPolicy中开启tls
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: service-name-1
spec:
host: service-host-1
# NOTE: 开启TLS
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
subsets:
- name: v1
labels:
version: v1
---
TLSmode说明
| mode值 | 描述 |
|---|---|
| DISABLE | 不要为上游端点使用 TLS。 |
| SIMPLE | 向上游端点发起 TLS 连接。 |
| MUTUAL | 发送客户端证书进行验证,用双向 TLS 连接上游端点。 |
| ISTIO_MUTUAL | 发送客户端证书进行验证,用双向 TLS 连接上游端点。和 MUTUAL 相比,这种方式使用的双向 TLS 证书系统是由 Istio 生成的。如果使用这种模式,TLSSettings 中的其他字段应该留空。 |
RBAC
- Istio文档-授权
- Istio文档-基于角色的访问控制
- Istio文档-迁移 RbacConfig 到 ClusterRbacConfig
- 这里使用的
ClusterRbacConfig
- 这里使用的
- Istio参考配置-授权
有关RbacConfig、ServiceRole、ServiceRoleBinding的属性结构Istio文档有详细的配置可以参考:Istio参考配置-授权-RBAC
1.开启授权ClusterRbacConfig
apiVersion: "rbac.istio.io/v1alpha1"
kind: ClusterRbacConfig
metadata:
name: default
namespace: istio-system
spec:
mode: 'ON_WITH_INCLUSION'
inclusion:
#namespaces: ["namespace-1"]
services: ["service-name-1.namespace-1.svc.cluster.local", "service-name-2.namespace-1.svc.cluster.local"]
# NOTE: ENFORCED/PERMISSIVE,严格或宽容模式
enforcement_mode: ENFORCED
---
enforcement_mode可以选择ENFORCED严格模式,或PERMISSIVE宽容模式,宽容模式便于授权策略需要变更时进行验证测试,Istio任务-授权许可模式任务中有更具体的场景介绍。
模式mode说明
| mode值 | 描述 |
|---|---|
| OFF | 关闭 Istio RBAC,RbacConfig 的所有配置将会失效,且 Istio RBAC Policies 不会执行。 |
| ON | 为所有 services 和 namespaces 启用 Istio RBAC。 |
| ON_WITH_INCLUSION | 仅针对 inclusion 字段中指定的 services 和 namespaces 启用 Istio RBAC。其它不在 inclusion 字段中的 services 和 namespaces 将不会被 Istio RBAC Policies 强制执行。 |
| ON_WITH_EXCLUSION | 针对除了 exclusion 字段中指定的 services 和 namespaces,启用 Istio RBAC。其它不在 exclusion 字段中的 services 和 namespaces 将按照 Istio RBAC Policies 执行。 |
2.角色权限规则ServiceRole
namespace + services + paths + methods 一起定义了如何访问服务,其中services必选,另外有constraints可以指定其它约束,支持的约束参考Istio参考配置-授权-约束和属性#支持的约束
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: service-role-1
namespace: default
spec:
rules:
- services: ["service-name-1.namespace-1.svc.cluster.local"]
methods: ["*"]
# NOTE: 根据约束需要修改
constraints:
- key: request.headers[version]
values: ["v1", "v2"]
---
3.角色绑定规则ServiceRoleBinding
user + properties 一起定义授权给谁,支持的属性参考Istio参考配置-授权-约束和属性#支持的属性
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: service-rb-1
namespace: default
spec:
subjects:
# NOTE: 需要添加 ServiceAccount
- user: "cluster.local/ns/namespace-1/sa/service-account-2"
# NOTE: 根据属性需要修改
properties:
source.namespace: "default"
# NOTE: ingressgateway授权
- user: "cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"
roleRef:
kind: ServiceRole
name: "service-role-1"
---
Optional
部署实例添加ServiceAccount
对于需要要在ServiceRoleBinding的subjects条件中授权的user,需要在部署实例时指定serviceAccountName,如前面ServiceRoleBinding配置要允许service-2访问service-1,则部署service-2时需要配置serviceAccountName: service-account-2
# NOTE: 创建ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-2
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: service-name-2-v1
spec:
replicas: 1
template:
metadata:
labels:
app: service-name-2
version: v1
spec:
# NOTE: 为部署实例指定serviceAccountName
serviceAccountName: service-account-2
containers:
- name: service-name-2-v1
command: [
"/main"
]
image: hbchen/service-2:v0.0.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
---
总结
Istio服务网格可以很方便的实现服务间访问控制,通过服务级的授权开关,再结合ServiceRole、ServiceRoleBinding的约束和属性条件,可以实现细粒度的访问控制。本文未涉及Istio的终端用户身份验证,后面会结合Ingress、Egress的TLS和JWT一起分析边缘流量相关的安全问题。