Istio Security - Istio安全框架
目录
- 1. Istio Security概览
- 2. Istio 身份
- 2.1 Istio身份的具体示例
- 2.2 Istio workload身份的承载物 - X.509证书
- 3. 认证Authentication
- 3.1 认证策略 Authentication policies
- 3.1.1 PeerAuthentication
- 3.1.2 RequestAuthentication
- 3.1.3 认证通过后输出的principal
- 4. 授权Authorization
- 4.1 授权策略 Authorization policies
- 5. 总结
- 6. 后续 TODO
1. Istio Security概览
Istio Security可整体概括为下图:
Istio安全保护工具:
身份(strong identity)
策略(powerful policy)
:包括认证策略、授权策略传输加密(TLS encryption)
AAA(authentication, authrorization, audit)
:认证、授权、审计
Istio Security目标:
- Security by default
- Defense in depth
- Zero-trust network
Istio Security整体架构
核心组件:
CA(证书权威机构Certificate Authority)
:负责密钥key和证书cert管理Configuration API server(Authen policies, Author policies, Secure naming information)
:负责向proxies分发策略PEPs(Policy Enforcement Points,例如sidecar, perimeter proxies)
:接收安全策略并执行相关安全策略(通讯加密)Envoy proxy extensions
: manage telemetry and auditing
2. Istio 身份
身份是任何安全框架的基础,后续的认证、授权都是在身份的基础上进行的,
我们做应用开发时,身份可以表示具体的用户、企业、设备、服务等等。
2.1 Istio身份的具体示例
Istio使用了一个更广泛的service identity
的概念,service identity
可以代表:
一个人类用户
对应IstioRequestAuthentication JWT
认证,
在Istio中对应属性:request.auth.principal={iss}/{sub},
即通过JWT令牌
标识一个用户单独的workload
对应IstioPeerAuthentication mTls
验证,mTls证书中编码了workload身份,
即K8s service account
标识一个workload,
在Istio中对应属性:source.principal=cluster.local/ns/{namespace}/sa/{serviceAccountName}一组workloads
可以理解为一个K8s service account对应多个workload,
又或者如形式:cluster.local/ns/default/sa/*- 自定义的用户账户、服务账户、服务名称、Istio service account …
2.2 Istio workload身份的承载物 - X.509证书
Istio中每个workload都有一个身份,这个身份是通过X.509证书来进行表示的
(即每个workload都有一套由istiod CA签发的证书,而证书中编码了当前worload的身份信息),
在Istio中workload的身份是由K8s Service account来进行表示的
,
格式:cluster.local/ns/{namespace}/sa/{serviceAccountName}
具体证书流转流程如下:
- Istio agent(存在于sidecar 容器中的 pilot-agent 进程)负责生成key+csr
- Istio agent 请求Istiod CA生成证书(grpc服务)
- Istiod CA验证csr请求,生成并返回证书给Istio agent
- workload启动完成后,Istio agent通过
Envoy secret discovery service (SDS)
向Envory发送key+cert - Istio agent监控cert过期时间并重复发起上述流程(即cert过期后会自动向Istiod CA续签证书 )
3. 认证Authentication
Isito提供两种认证类型:
Peer Authentication
- 服务(工作负载)间的认证(service-to-service)
Istio通过envoy间的双向TLS(mutual TLS)
来实现服务间的认证
和通信加密
,
同时client需要对server端证书cert中的service account
进行安全命名(Secure Naming)检查
注:Istio使用的mTLS版本 >= TLSv1_2版本Request Authentication
- 终端用户(end-user)的请求(单个request)认证
Istio启用请求级别的JWT验证
,且支持集成自定义认证服务器
(Authentication provider、OIDC provider),如:Keycloak, Auth0, Google Auth, ORY hydra等。
注:需要应用Application自己去获取、添加JWT到请求request中
安全命名(Secure Naming)
Server Identities
到Service Name
的映射,
即K8s Service Account
到K8s Service
的映射,
Secure Naming Check即用于client检查server端cert中的service account是否被授权运行server端服务,
可用于防止DNS spoofing, BGP/route hijacking, ARP spoofing等。
注:对于非HTTP/HTTPS流量,安全命名不能保护其免于 DNS 欺骗
例如:
Server Identity | Service Name | 说明 |
---|---|---|
A | B | A被授权运行服务B |
3.1 认证策略 Authentication policies
所有的的认证策略都是作用在Server服务端,即:
- 为Server服务端指定Client客户端的认证策略
- 由Server服务端对Client客户端执行认证
之前提到过Istio认证分为2种认证类型,2种认证类型即对应各自同名的认证策略配置如下表:
认证类型 | 认证策略配置 | 说明 |
---|---|---|
Peer Authentication | PeerAuthentication |
- 服务(工作负载)间的认证(service-to-service) - Istio通过envoy间的 双向TLS(mutual TLS) 来实现服务间的认证 和通信加密 - 同时client需要对server端 证书cert中的service account 进行安全命名(Secure Naming)检查
|
Request Authentication | RequestAuthentication |
- 终端用户(end-user)的请求(单个request)认证 - Istio启用请求级别的 JWT验证 - 且支持 集成自定义认证服务器 (Authentication provider、OIDC provider)- 需要应用Application自己去获取、添加JWT到请求request中 |
认证策略的作用范围:
- Mesh-wide policy - 网格范围
定义在root命名空间(即istio-system)下的策略,且没有selector或空selector,则对整个网格内的workload都生效 - Namespace-wide policy - 命名空间范围
定义在非root命名空间下,且没有selector或空selector,则对该命名空间下的workload都生效 - workload-specific policy - 特定workload
定义在非root命名空间下,且selector不为空,则对该命名空间下selector选中的workload生效
3.1.1 PeerAuthentication
PeerAuthentication主要用来给目标workload(或特定port)指定mutual TLS模式,
具体mtls.mode如下:
- PERMISSIVE(宽容模式,默认)
同时支持明文、mtls流量 - STRICT(严格)
仅支持mtls流量 - DISABLE(禁用)
禁用mtls,即仅支持明文传输
注:
PeerAuthentication mtls
用于配置指定workload对应sidecar
需要接受的mTLS流量类型
。DestinationRule tls
用于配置客户端workload对应的siedecar
需要向指定服务端workload sidecar
发送的TLS流量类型
。
若PeerAuthentication开启mtls.mode:STRICT模式,
则DestinationRule需开启trafficPolicy.tls.mode: ISTIO_MUTUAL
(DestinationRule默认不配置则Istio网格内服务默认开启ISTIO_MUTUAL)。
PeerAuthentication和DestinationRule具体差别参见:
https://preliminary.istio.io/latest//docs/ops/configuration/traffic-management/tls-configuration/#sidecars
PeerAuthentication具体示例如下:
# 假设在命名空间foo下存在服务exmaple-service,服务提供8000端口,对应容器80端口
# 对应K8s service定义如下:
apiVersion: v1
kind: Service
metadata:name: example-servicenamespace: foo
spec:ports:- name: httpport: 8000protocol: TCPtargetPort: 80selector:app: example-app# 需求1:命名空间foo下的所有服务都需要开启mTls模式(即双向TLS认证)
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:name: "example-policy"namespace: "foo"
spec:# selector不存在# 则对命名空间foo下的所有workload均生效# 设置mtls.mode为STRICT,则开启mtls(仅接收mtls流量)mtls:mode: STRICT# 需求2:命名空间foo下的服务example-service的80端口禁用mTls模式(即支持明文传输)
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:name: "example-workload-policy"namespace: "foo"
spec:# 通过selector指定label选择特定的workloadselector:matchLabels:app: example-app# 端口级别的mTls模式设置portLevelMtls:# 指定workload的目标端口80的mtls模式为禁用80:mode: DISABLE
TODO: 多个规则合并、优先级
3.1.2 RequestAuthentication
RequestAuthentication主要用来设置对目标worload发起request请求的JWT验证,
即对JWT中标识的终端用户(end-user)的请求(request)认证。
RequestAuthentication整体配置结构如下:
namespace
策略生效的命名空间selector -> matchLables
指定策略作用的目标workloadjwtRules
jwt验证规则的配置issuer
jwt的发布者audiences
受众,即jwt的接受者jwksUri | jwks
jwks(公钥),即用来验证jwt签名的公钥,jwksUri和jwks二选一fromHeaders
jwt在请求头的位置name
header名称prefix
token前缀,如"Bearer "
fromParams
jwt在query参数中的参数名称outputPayloadToHeader
指定jwt验证通过后的payload传递给哪个请求headerforwardOriginalToken
是否保留原始token,默认false
jwtRules
概括起来分为如下几类配置:
- jwt token的位置(jwtRules.fromHeaders, jwtRules.fromParams)
- jwt.payload等相关属性(jwtRules.issuer, jwtRules.audiences)、request
- jwt公钥,即JWKS(JSON Web Key Set),用来验证jwt的签名(jwtRules.jwksUri, jwtRules.jwks)
- 是否保留jwt(jwtRules.outputPayloadToHeader, jwtRules.forwardOriginalToken)
RequestAuthentication配置示例
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:name: httpbinnamespace: foo
spec:# worload的label选择器selector:matchLabels:app: httpbin# jwt验证规则jwtRules:# jwt的发布者- issuer: "issuer-foo"# 受众,即jwt的接受者audiences:- bookstore_android.apps.example.combookstore_web.apps.example.com# jwks(公钥)uri发现地址,即用来验证jwt签名的公钥jwksUri: https://example.com/.well-known/jwks.json# jwks(此属性与jwksUri需二选一)jwks: "jwks json"# jwt在请求头的位置fromHeaders:- name: x-jwt-assertionprefix: "Bearer "# jwt在query参数中的参数名称fromParams:- "my_token"# 指定jwt验证通过后的payload传递给哪个请求header# 传递格式:base64_encoded(jwt_payload_in_JSON)outputPayloadToHeader: payload_header# 是否保留原始token(若保留则继续传递token到upstream请求),默认falseforwardOriginalToken: false
注:
- jwt验证通过,则正常接受请求
- jwt验证失败,则拒绝请求
jwt为空,默认接受请求(需通过设置Authoriation policies来拒绝不带token的请求)
- 支持多个不同位置的jwt token,
- 但仅支持一个有效的token(多个有效的token会导致输出的principal不确定)
3.1.3 认证通过后输出的principal
在认证(Authentication Policies)
通过后,Istio会将各自的认证策略中抽取到的身份信息传递给Istio 身份属性
,可供后续授权策略(AuthorizationPolies)
使用
认证策略 |
抽取出的身份属性 (Istio属性) |
授权策略 AuthorizationPolicy |
说明 |
---|---|---|---|
PeerAuthentication | source.principal | rules.from.principals |
workload的身份,需开启mTls获取 格式:cluster.local/ns/{namespace}/sa/{serviceAccountName} 示例:cluster.local/ns/default/sa/productPage |
RequestAuthentication | request.auth.principal | rules.from.requestPrinciplas |
用户身份,即 jwt令牌(认证通过)中提取的身份, 格式:{issuer}/{subject} 示例: issuer.example.com/subject-admin |
4. 授权Authorization
Isito默认开启对网格内的workload的访问控制,
由server端的Envoy代理(根据AuthorizationPolicy配置)对inbound流量执行access control,
Istio授权(Authorization)提供如下特性:
- workload-to-workload, end-user-to-workload的访问控制
- 提供简单、唯一的授权策略配置:
AuthorizationPolicy
- 兼容多协议:gRPC, HTTP, HTTPS, HTTP/2, TCP
Istio根据action类型( CUSTOM | DENY | ALLOW)
分层验证AuthorizationPolicy,
即依次验证:CUSTOM -> DENY -> ALLOW
,具体授权策略优先级如下图:
注: 若目标workload的操作
没有设置AuthorizationPolicy,则表示没有限制,放行所有对目标workload的请求
4.1 授权策略 Authorization policies
Istio提供唯一的授权策略配置:AuthorizationPolicy
,其整体结构如下:
namespace
策略生效的命名空间(即目标workload所属的namespace)selector -> matchLables
指定策略作用的目标workloadactions: CUSTOM | DENY | ALLOW
是否允许请求rules
指定触发action的条件(即满足rules定义的请求,则执行action)from -> source[]
指定请求来源(source满足的条件),为空则表示全部来源
pincipals(workload身份)、requestPrincipals(用户身份)、namespaces、ipBlocks、remoteIpBlocks及相应not属性to -> operation[]
指定请求的操作(request满足的条件),为空则表示所有操作
hosts、ports、methods、paths及相应not属性when
指定额外的附件条件(key对应Istio属性)key -> values[] | notValues[]
request.headers[header_name]、
request.auth.[principal | audiences | presenter | claims[claimName] ]、
source.[ip | namespace | principal ]、remote.ip、
destination.[ip | port]、 connection.sni
AuthorizationPolicy配置概括起来就是:
允许(或拒绝)
来源workload 或 用户
对目标workload
进行什么操作
,并且需要满足什么条件
。
具体配置示例:
# 作用目标: workload(namespace=foo, label(app=httpbin, version=v1))
# 动作action: 允许访问ALLOW
# 来源rules.from.source: principals=="cluster.local/ns/default/sa/sleep" or namepsace=="dev"
# 操作rules.to.operation:method=="GET"
# 条件rules.when: request.auth.claims[iss]=="https://accounts.google.com"
# 即[仅允许][cluster.local/ns/default/sa/sleep身份(PeerAuthentication mTls验证通过)、或者dev命名空间]的workload访问[httpbin:v1服务的GET请求]
# 且[用户RequestAuthentication JWT验证通过、且jwt.claims[iss]=="https://accounts.google.com"]
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: httpbinnamespace: foo
spec:selector:matchLabels:app: httpbinversion: v1action: ALLOWrules:- from:- source:# 指定来源workload身份# principals: ["*"]则表示需要PeerAuthentication mtls验证通过principals: ["cluster.local/ns/default/sa/sleep"]- source:# 指定来源namespacenamespaces: ["dev"]to:- operation:# 执行GET请求methods: ["GET"]when:# 指定用户jwt需验证通过,且iss为指定值- key: request.auth.claims[iss]values: ["https://accounts.google.com"]# [拒绝][不属于foo命名空间的服务]访问[httpbin:v1服务]
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: httpbin-denynamespace: foo
spec:selector:matchLabels:app: httpbinversion: v1action: DENYrules:- from:- source:# 不是来自于foo命名空间notNamespaces: ["foo"]# 访问非/healthz的请求,均需要JWT验证通过,
# 而访问/healthz的请求,可无需JWT验证(即请求未携带JWT令牌、或者携带的JWT令牌为空)
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:name: disable-jwt-for-healthznamespace: default
spec:selector:matchLabels:app: productsaction: ALLOWrules:- to:- operation:# 访问除了/healthz以外的pathnotPaths: ["/healthz"]from:- source:# 需要RequestAuthentication JWT验证通过requestPrincipals: ["*"]
5. 总结
记得刚接触Istio时,就看过Istio官网上关于Istio/Concepts/Security 这一章节,当时看的不是很懂,后来陆续接触了
- Oauth2
- Spring Security
- Spring Security Oauth
- RBAC
- OIDC
- CAS
- SSO, SLO
- IDasS
- …
最近回过头来再看Istio Security,渐渐读懂了Istio Security想要做什么了。
可以对比Spring Security
,Spring Security是Java语言在Spring平台的安全管理框架,
通过编码集成用户登录认证、用户鉴权等操作,
后续出现了Oauth, OIDC后,我们可以搭建统一认证服务器AS(Authorization server), OP(OpenID Provider),
如Keycloak、IdentityServer、又或者购买IDaaS,
然后通过Spring Security Oauth框架编码、配置集成Client端、Resource server端,
在Client端我们通过Spring Security框架注册了认证中心,由认证中心完成统一的登录认证并颁发token,
而在Resource server端由Spring Security框架帮我们完了JWT认证,
而具体的鉴权(Authorization、Access control)操作(API path、数据权限、菜单、按钮)还是需要我们通过编码来完成。
而Istio Security
是站在更高层次(Service mesh)看问题,
Istio不关心具体服务使用的是什么编程语言(Java、Python、Go…)、什么安全框架(Spring Security、Shiro…),
它以不侵入代码的形式(Sidecar Envoy),
站在通信协议(HTTP、HTTPS、gRPC、TCP)、安全协议(Oauth2、OIDC)层面看问题,
通过Istio自定义的Yaml配置(PeerAuthentication、RequestAuthentication、AuthorizationPolicy)来实现一定程度的认证、授权配置。
目前简单来看Istio可以替代部分传统安全框架(基于编码开发)的功能:
传统方式 | Istio方式 | 说明 |
---|---|---|
Spring Security Oauth - Resource Server | RequestAuthentication | JWT验证(iss, aud…) |
编码方式mTLS证书配置 容器、中间件trustStore配置 |
PeerAuthentication | 应用间(workload间)的mTls认证 |
编码方式的鉴权 | AuthorizationPolicy |
workload-to-workload end-user-to-workload Istio除了支持传统的用户鉴权, 还支持Mesh内workload间的访问控制, Istio鉴权粒度有限:workloads、hosts、paths、methods、ports |
Spring Security Oauth - Client |
AuthorizationPolicy (action.CUSTOM + provider) |
Istio实验特性 Istio支持集成外部认证中心 |
编码获取、添加JWT到请求中 | 同 | Istio安全框架也需要应用本身自己负责获取、添加JWT到请求中 |
开发、搭建统一认证服务器 | 同 | Istio安全框架不提供统一认证中心,需要应用平台自己搭建统一认证中心 |
6. 后续 TODO
- 安全命名(Secure Naming)
- Istio集成外部认证中心:External Authorization
- Istio Security与Spring Security对比
参考:
https://preliminary.istio.io/latest/docs/concepts/security
https://preliminary.istio.io/latest/docs/reference/config/security/
https://preliminary.istio.io/latest/docs/ops/configuration/traffic-management/tls-configuration/
Istio Security - Istio安全框架相关推荐
- Beyond Istio OSS——Istio服务网格的现状与未来
作者:宋净超(Jimmy Song),原文地址:https://jimmysong.io/blog/beyond-istio-oss/ 本文根据笔者在 GIAC 深圳 2022 年大会上的的演讲< ...
- Spring Security(安全框架)
一.概念 (1)Spring Security是一个高度自定义的安全框架.利用Spring IoC/DI和AOP功能,为系统提供了声明式安全访问控制功能,减少了为系统安全而编写大量重复代码的工作. ( ...
- 【Spring Security】安全框架学习(十三)
6.1 自定义权限校验方法 我们也可以定义自己的权限校验方法,在@PreAuthorize注解中使用我们的方法. 我们可以发现直接在@PreAuthorize内写方法名就可以用默认提供的方法,那么怎么 ...
- spring security 注解_Spring框架使用@Autowired自动装配引发的讨论
原文首发于掘金 作者:walkinger 链接:https://juejin.im/post/5d4163ede51d4561f64a078b 问题描述 有同事在开发新功能测试时,报了个错,大致就是, ...
- 六, 跨语言微服务框架 - Istio Ingress和Egress详解(解决Istio无法外网访问问题)
在微服务中另外一个重点就是网关,网关理论包含入口网关和出口网关,传统意义上的网关很难做到出口网络控制,但是对于Istio是一件非常轻松的事情(因为所有的出口流量都会经过Istio),入口网关控制解析路 ...
- Istio究竟是干嘛的?
上一篇介绍了<ServiceMesh究竟解决什么问题?>,当微服务架构体系越来越复杂的时候,需要将"业务服务"和"基础设施"解耦,将一个微服务进程一 ...
- 使用 Istio 实现非侵入流量治理
现在最火的后端架构无疑是微服务了,微服务将之前的单体应用拆分成了许多独立的服务应用,每个微服务都是独立的,好处自然很多,但是随着应用的越来越大,微服务暴露出来的问题也就随之而来了,微服务越来越多,管理 ...
- 万字长文从 0 详解 Istio
- 前言 - 在本教程中,我们将介绍服务网格的基础知识,并了解它如何实现分布式系统架构. 我们将主要关注Istio,它是服务网格的一种具体实现.在此过程中,我们将介绍Istio的核心架构 ...
- 图解Istio原理和实践--云平台技术栈18
" 如果你比较关注新兴技术的话,那么很可能在不同的地方听说过 Istio,并且知道它和 Service Mesh 有着牵扯. 导读:之前发布了云平台技术栈(ps:点击可查看),本文主要说一下 ...
最新文章
- 哪里可以接到python的活干-学了Python以后,我干了很多不是人干的活
- Android性能优化典范 - 第6季
- Qt 使用正则表达式进行字符串替换
- delphi 到出execl2010 文件损坏_Win7系统出现explorer.exe损坏的图像的解决方法是什么?...
- 一个略显复杂的transformation算子_distinct
- Scene Flow场景流halcon算子,持续更新
- GitHub 贡献第一的微软开源软件列表
- AcWing 253. 普通平衡树
- WinForm与脚本的交互
- Mycat_MySql更新数据库失败 --read-only
- 综合演练 对象数组 对象的方法 我们9203班 0912
- c++调用python找不到py文件的可能原因
- 领域驱动 开源项目_我如何在开源领域找到工作
- ubuntu中vim编辑器的安装与基本使用
- 详解RS232、RS485、RS422、串口和握手
- 阿里P6级别Java程序员月薪多少?阿里认证员工给出答案
- vuetify学习第6天之v-btn-toggle---按钮组
- 远程控制计算机控制不,远程控制电脑为什么打不了字
- SQL注入Cookie注入
- 螺旋无限延伸_八卦中的双螺旋结构,无限大∞符号隐含的秘密
热门文章
- HART475艾默生手操器维修注意事项及指标特点
- 如何打开.epub格式的电子书?
- 人工智能知识全面讲解:生成对抗网络的应用
- [知乎高赞回答]TCP/IP协议到底在讲什么?
- CentOS7环境下 人大金仓kes86数据库安装过程
- python open unicodedecodeerror_python 读取文件时报错UnicodeDecodeError: 'gbk' co
- 惠普喷墨打印机卡纸了
- 大S产女获张兰连续两天探望 大赞儿媳妇是骄傲
- 【年度总结 | 2022】想干什么就去干吧,少年
- 使用CompletableFuture+ExecutorService+Logback的多线程测试