原理
安全原理
- 安全核心组件 Citadel 用于密钥和证书管理
 
- Envoy 作为数据面组件代理服务间的安全通信,包括认证,通道加密等
 
- Pilot 作为配置管理服务,在安全场景下将安全相关的配置分发 Envoy
 
- Mixer 可以通过配置 Adapter 来做授权和访问审计
 
从控制面到数据面的配置流程:
- Citadel 监听Kube-apiserver,为每个 Service 都生成密钥和证书,并保存为 Kubernetes Secrets.当创建Pod时,Kubernetes 将包含密钥和证书的 Secret 挂载到对应的Pod中
 
- Citadel会维护证书的生命周期,并根据配置定期重建 Kubernetes Secrets 以自动更新证书
 
- Pilot生成配置信息,定义哪个 ServiceAccount 可以运行哪个服务,并将这个配置下发给 Envoy
 
数据面主要流程如下:
- 客户端的 Envoy 拦截到服务的 Outbound 流量
 
- 客户端的 Envoy 和服务端的 Envoy 进行双向 TLS 握手
 
- 在双向TLS建立后,请求到达服务端 Envoy,服务端 Envoy 将请求转发给本地服务
 
Istio 提供的安全功能主要有认证和授权
认证方式
istio 中提供了两种认证方式:
- 传输认证: 又称为从服务到服务的认证.Istio 基于双向 TLS 来实现传输认证,包括双向认证,通道安全和证书自动维护.基于双向TLS可以保护从服务到服务的通信
 
- 来源认证: 又称为最终用户认证,用于认证请求的最终用户或设备
 
授权
istio 中的授权是基于角色的访问控制(RBAC)
密钥证书管理
Citadel 服务主要做 4 个操作:
- 给每个 Service Account 都生成 SPIFFE 密钥证书对
 
- 根据Service Account 给对应的 Pod 分发密钥和证书对
 
- 定期替换密钥证书
 
- 根据需要撤销证书
 
服务认证配置
示例:
1 2 3 4 5 6 7 8 9 10 11
   |  apiVersion: authentication.istio.io/v1alpha1 kind: Policy metadata:   name: forecast-weather-mtls   namespace: istio-system spec:   targets:   - name: forecast   peers:   - mtls: {}
 
  | 
 
认证策略定义
认证策略定义过程中重要字段如下:
targets: 表示策略作用的目标对象,如果为空,则对策略作用范围内的所有服务都生效.该字段包含 name 和 ports 分别表示服务名称及端口 
peers: 描述传输认证的配置.一般被赋值为 mtls,表示启用双向认证.若不启用,则不用赋值 
orgins: 描述访问来源认证的配置. 
认证策略典型应用
全网格服务启用双向 TLS 认证
1 2 3 4 5 6 7 8
   |  apiVersion: authentication.istio.io/v1alpha1 kind: MeshPolicy metadata:   name: default spec:   peers:   - mtls: {}
 
  | 
 
全名称空间服务启用双向 TLS 认证()
1 2 3 4 5 6 7 8 9
   |  apiVersion: authentication.istio.io/v1alpha1 kind: Policy metadata:   name: default   namespace: default spec:   peers:   - mtls: {}
 
  | 
 
对特定服务不启用双向 TLS 认证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | --- apiVersion: authentication.istio.io/v1alpha1 kind: Policy metadata:   name: enable_weather_tls   namespace: weather spec:   peers:   - mtls: --- apiVersion: authentication.istio.io/v1alpha1 kind: Policy metadata:   name: disable_adv_tls   namespace: weather spec:   targets:   - name: advertisement
   | 
 
服务授权配置
授权启用配置
1 2 3 4 5 6 7 8 9 10 11 12
   | apiVersion: rbac.istio.io/v1alpha1 kind: ClusterRbacConfig metadata: ClusterRbacConfig   name: default spec:   mode: "ON_WITH_INCLUSION"      inclusion:     namespaces:     - weather          
   | 
 
授权策略配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | --- apiVersion: rbac.istio.io/v1alpha1 kind: ServiceRole metadata:   name: advertisement-reader   namespace: weather spec:   rules:   - services: ["advertisement.weather.svc.cluster.local"]     methods: ["GET"] --- apiVersion: rbac.istio.io/v1alpha1 kind: ServiceRoleBinding metadata:   name: binding-advertisement-reader   namespace: weather spec:   subjects:   - properties:       source.namespace: "terminal"   roleRef:     kind: ServiceRole     name: advertisement-reader
   | 
 
serviceRole 定义
关键字 rules,表示权限的许可,元素 rule 通过如下字段来定义
servces: 必选字段,表示作用的服务的集合 
paths: 配置对应服务的接口列表.未指定时表示所有 path 
methods: 指定接口的方法,如 GET,POST 等 
constraints: 可选字段,可以理解为服务的扩展字段.常用扩展字段如下
destination.labels: 目标服务上的标签,如 destination.labels[version] 是 [v1] 来描述对特定版本权限 
request.headers: 通过 Header 上取值 来描述规则 
destination.ip: 目标服务实例的 IP 地址 
destination.port: 目标服务端口 
destination.namespace: 目标服务名称空间 
destination.user: 目标服务负载上取到的标识 
 
serviceRoleBinding 定义
serviceRoleBinding 作为绑定的定义,主要绑定两个对象,一个是定义的角色 roleRef,另一个是角色分配的目标对象 subjects
roleRef: 必选字段,表示要绑定的角色.包含 kind(角色类型,ServiceRole) 和 name(角色名称) 两个字段 
subjects: 必选字段,表示角色分配的目标,是一个列表,可将角色分配到多个对象上.该字段有两个属性分类
user: 对应用户名或 ID. “*” 表示授权给所有用户和服务 
properties: 扩展属性.支持以下属性
source.ip: 源服务实例的 IP 地址 
source.namespace: 源服务实例的名称空间 
source.principal: 源服务实例标识 
request.headers: 请求 HTTP header 
request.auth.principal: 请求认证主体 
request.auth.audiences: 认证信息的目标受众 
request.auth.presenter: 授权的凭证提供者 
request.auth.claims: 来源 JWT 声明 
 
 
授权策略典型应用
特定名称空间授权
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | apiVersion: rbac.istio.io/v1alpha1 kind: ServiceRole metadata:   name: advertisement-reader   namespace: weather spec:   rules:   - services: ["*"]     methods: ["*"] --- apiVersion: rbac.istio.io/v1alpha1 kind: ServiceRoleBinding metadata:   name: binding-advertisement-reader   namespace: weather spec:   subjects:   - properties:       source.namespace: "client"   roleRef:     kind: ServiceRole     name: advertisement-reader
   | 
 
特定服务授权
1 2 3 4 5 6 7 8 9
   | apiVersion: rbac.istio.io/v1alpha1 kind: ServiceRole metadata:   name: advertisement-reader   namespace: weather spec:   rules:   - services: ["advertisement.weather.svc.cluster.local"]     methods: ["GET"]
   | 
 
特定接口授权
1 2 3 4 5 6 7 8 9 10
   | apiVersion: rbac.istio.io/v1alpha1 kind: ServiceRole metadata:   name: advertisement-reader   namespace: weather spec:   rules:   - services: ["advertisement.weather.svc.cluster.local"]     paths: ["v2/weatherdata"]     methods: ["GET"]
   | 
 
特定版本授权
1 2 3 4 5 6 7 8 9 10 11 12
   | apiVersion: rbac.istio.io/v1alpha1 kind: ServiceRole metadata:   name: advertisement-reader   namespace: weather spec:   rules:   - services: ["advertisement.weather.svc.cluster.local"]     methods: ["GET"]     constraints:     - key: "destination.labels[version]"       value: ["v2"]
   | 
 
特定源授权
1 2 3 4 5 6 7 8 9 10 11 12
   | apiVersion: rbac.istio.io/v1alpha1 kind: ServiceRoleBinding metadata:   name: binding-advertisement-reader   namespace: weather spec:   subjects:   - properties:       source.ip: "1.1.0.0/16"   roleRef:     kind: ServiceRole     name: advertisement-reader
   |