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
一起分析边缘流量相关的安全问题。