istio安全之Citadel
Citadel
- 网格内服务之间TLS
- Citadel工作原理
- CA Server
- SDS Server
- Secret Controller
- Monitor
- Citadel功能演示
- 开启服务间mTLS
- 使用SDS配置TLS Ingress Gateway
Citadel是 Istio 中负责身份认证和证书管理的核心安全组件,1.5版本之后取消了独立进程,作为一个模块被整合在istiod中。
如图,Istio所希望的是在网格中能够使用mTLS进行授权,而在网格外使用JWT+mTLS进行授权。服务间身份认证是使用mTLS,来源身份验证中则是使用JWT。
网格内服务之间TLS
istio中的服务间tls认证
- 客户端应用程序容器将纯文本HTTP请求发送到服务器。
- 客户端代理容器拦截出站请求。
- 客户端代理与服务器端代理执行TLS握手。此握手包括证书交换。
- 客户端代理对服务器的证书进行校验,以验证授权身份正在运行服务器。双向mTLS的,服务端也会对客户端证书进行校验。
- 客户端和服务器建立相互TLS连接,服务器代理将请求转发到服务器应用程序容器。
加密套件
Istio将TLS1.2作为最低TLS版本,为客户端和服务器配置了如下加密套件:
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
AES256-GCM-SHA384
AES128-GCM-SHA256
Citadel工作原理
Citadel主要包括CA Server、SDS Server、Secret Controller、Monitor等模块,它们的工作原理如下。
CA Server
Citadel中的CA签发机构,是一个gRPC服务器,启动时会注册两个 gRPC服务,一个是CreateCertificate,用来签发证书。首先会对请求中的service account token进行验证,验证通过后会对CRS进行签名;另一个是HandleCSR,用来处理CSR请求,该方法目前已被CreateCertificate替代,预计很快将会被干掉。
CA Server管理着4个证书,它们都会挂载到istiod容器的/etc/cacerts/目录下,包含ca证书ca-cert.pem、ca私钥ca-key.pem、ca证书链ca-chain.pem和根证书root-cert.pem
其中,ca证书用于给集群中的工作负载进行签名,即对pilog-agent发起的CSR请求进行签名;ca证书和ca私钥必须由根证书签名;ca证书链是ca证书与根证书之间的信任链。
Citadel给crs签名时使用的证书有两个来源:
- 默认使用自动生成的自签名证书,名为istio-ca-secret的secret
2.用户手动插入自己的CA作为根证书,具体方式是在部署istio之前在istio-system中创建名为cacerts的secret,然后istio部署的时候会自动使用这个secret中的证书
插入CA的具体方法可参考官网文档:https://istio.io/latest/zh/docs/tasks/security/cert-management/plugin-ca-cert
SDS Server
SDS即安全发现服务(Secret discovery service),它是一种在运行时动态获取证书私钥的API,Envoy通过SDS动态获取证书私钥。Istio中的SDS服务器负责证书管理,并实现了安全配置的自动化。相比传统的方式,使用SDS主要有以下优点:
- 无需重启,就可以动态的新增、删除或者更新密钥/证书对以及根证书。
- 无需加载Secret卷。创建了kubernetes Secret之后,这个Secret就会被Gateway代理捕获,并以密钥/证书对和根证书的形式发送给 Ingress Gateway。
- Gateway代理能够监视多个密钥/证书对。只需要为每个server创建 Secret并更新Gateway定义就可以了
服务间mTLS使用SDS交互流程:
- 当Envoy进程在与其它Envoy进程交互时,发现需要进行TLS认证,它会从静态配置文件或者动态配置服务器获取证书的名称等相关信息,这时Envoy就会向pilot-agent发起一个SDS请求,要求获取自己的证书和私钥。
- pilot-agent收到请求后,会首先读取本地的ServiceAccount Token,路径为/var/run/secrets/kubernetes.io/serviceaccount/token,然后从token中解析出namespace和ServiceAccount等信息,再用这些信息生成私钥和证书签名请求CSR文件。接下来会向Istiod(的Citadel)发起申请证书签名的请求,请求中包含CSR和该pod的service account token
- Istiod中的CA Server收到请求后会调用 Kube-apiserver 接口验证请求中附带的 service account token,以确认请求证书的服务身份是否合法,通过后会对根据请求对证书进行签名、生成证书,并将签名后的数字证书发送给SDS Server。
- SDS Server将私钥和从CA Server处获得的证书一起通过SDS API发送给Envoy。
- 以上过程会周期性地重复执行以便实现证书的轮换。
PS:- 除了Kubernetes之外, Istio也支持虚机部署,在虚机部署的场景下,由于没有service account,因此CA Server的验证pilot-agent请求身份的authenticator接口有三种实现,除了sevice account之外,还支持ID token和tls的方式
- SDS Server和CA Server之间通信时,也是需要互相验证对方身份,此时双方使用的公共CA便是k8s中一个名为istio-ca-root-cert的ConfigMap,此configmap在注入sidecar时会挂载到sidecar的/var/run/secrets/istio目录下,在双方交互时会使用该证书来验证对方证书的签名。
- 除了Kubernetes之外, Istio也支持虚机部署,在虚机部署的场景下,由于没有service account,因此CA Server的验证pilot-agent请求身份的authenticator接口有三种实现,除了sevice account之外,还支持ID token和tls的方式
Secret Controller
在kubernetes场景下,需要使用卷挂载方式为SideCar提供证书密钥时,secretController才会被创建和启动。 SecretController监听 istio.io/key-and-cert 类型的 Secret 资源,它会周期性的检查证书是否过期,并更新证书。
如果没有自动证书轮换功能,当证书过期时,就不得不重启签发,并重启代理。证书轮换解决了这一问题,提高了服务的可用性。Istio 里通过一个轮换器(Rotator)自动检查自签名的根证书,并在证书即将过期时进行更新,它本质上是一个协程(goroutine)在后台轮询实现的:
- 获取当前证书,解析证书的有效期并获取下一次轮换时间
- 启动定时器,如果发现证书到达轮换时间,从CA获取最新的证书密钥对
- 更新证书
Monitor
monitor负责注册exporter等工作,为promethus提供性能和指标分析
Citadel功能演示
开启服务间mTLS
在istio中有个peerauthentications的CRD资源,就是通过创建和配置这个资源来开启或关闭istio服务间双向tls认证的:
mtls支持以下模式:
- PERMISSIVE:工作负载接受双向TLS和纯文本流量。
- STRICT:工作负载仅接受双向TLS通信。
- DISABLE:双向TLS已禁用。
缺省情况下,未设置模式的网格范围对等身份验证策略使用PERMISSIVE模式。
开启mtls功能后,可以在sleep服务的pod中curl httpbin服务,在返回的结果中,会看到多了一个"X-Forwarded-Client-Cert",这便是sidecar为它们添加的证书
使用SDS配置TLS Ingress Gateway
当前版本中,istio默认开启了SDS功能,所以开始配置前,需要先做以下准备工作:
- 先用自己的CA证书和私钥,为IngressGateway创建Secret:
kubectl create -n istio-system secret generic httpbin-credential \
--from-file=key=httpbin.example.com/3_application/private/httpbin.example.com.key.pem \
--from-file=cert=httpbin.example.com/3_application/certs/httpbin.example.com.cert.pem
- 查询ingressgateway的IP和https端口,并设置环境变量
export INGRESS_HOST=10.60.212.120
export SECURE_INGRESS_PORT=443
配置单向TLS Ingress Gateway
- 创建一个Gateway ,其servers:字段的端口为443,设置credentialName的值为httpbin-credential。这个值就是Secret的名字。TLS模式设置为SIMPLE
$ cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: mygateway
spec:selector:istio: ingressgateway # use istio default ingress gatewayservers:- port:number: 443name: httpsprotocol: HTTPStls:mode: SIMPLEcredentialName: "httpbin-credential" # must be the same as secrethosts:- "httpbin.example.com"
EOF
- 配置Gateway的Ingress流量路由,并配置对应的VirtualService:
$ cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "httpbin.example.com"
gateways:
- mygateway
http:
- match:- uri:prefix: /status- uri:prefix: /delayroute:- destination:port:number: 8000host: httpbin
EOF
- 用HTTPS协议访问 httpbin 服务:
curl -v -HHost:httpbin.example.com \
--resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
--cacert httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem \
https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418
httpbin 服务会返回 418 I’m a Teapot。
- 删除Gateway的Secret,并新建另外一个,然后修改Ingress Gateway的凭据:
kubectl -n istio-system delete secret httpbin-credential
kubectl create -n istio-system secret generic httpbin-credential \
--from-file=key=httpbin.new.example.com/3_application/private/httpbin.example.com.key.pem \
--from-file=cert=httpbin.new.example.com/3_application/certs/httpbin.example.com.cert.pem
- 使用新证书curl访问httpbin服务:
curl -v -HHost:httpbin.example.com \
--resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
--cacert httpbin.new.example.com/2_intermediate/certs/ca-chain.cert.pem \
https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418
- 如果尝试使用之前的证书链来再次访问httpbin,就会得到失败的结果:
curl -v -HHost:httpbin.example.com \
--resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
--cacert httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem \
https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418
配置双向TLS Ingress Gateway
可以对Gateway的定义进行扩展,加入双向TLS的支持。要修改Ingress Gateway的凭据,就要删除并重建对应的Secret。服务器会使用CA证书对客户端进行校验,因此需要使用cacert字段来保存 CA 证书:
kubectl -n istio-system delete secret httpbin-credential
kubectl create -n istio-system secret generic httpbin-credential \
--from-file=key=httpbin.example.com/3_application/private/httpbin.example.com.key.pem \
--from-file=cert=httpbin.example.com/3_application/certs/httpbin.example.com.cert.pem \
--from-file=cacert=httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem
- 修改Gateway定义,设置TLS的模式为 MUTUAL:
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygateway
spec:
selector:istio: ingressgateway # use istio default ingress gateway
servers:
- port:number: 443name: httpsprotocol: HTTPStls:mode: MUTUALcredentialName: "httpbin-credential" # must be the same as secrethosts:- "httpbin.example.com"
EOF
- 使用前面的方式尝试发出HTTPS请求,会看到失败的过程:
curl -v -HHost:httpbin.example.com \
--resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
--cacert httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem \
https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418
- 在curl命令中加入客户端证书和私钥的参数,重新发送请求。(客户端证书参数为–cert,私钥参数为–key)
curl -v -HHost:httpbin.example.com \
--resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
--cacert httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem \
--cert httpbin.example.com/4_client/certs/httpbin.example.com.cert.pem \
--key httpbin.example.com/4_client/private/httpbin.example.com.key.pem \
https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418
- 如果不想用httpbin-credential secret来存储所有的凭据, 可以创建两个单独的 secret :
- httpbin-credential 用来存储服务器的秘钥和证书
- httpbin-credential-cacert 用来存储客户端的 CA 证书且一定要有-cacert后缀
使用以下命令创建两个单独的secret :
kubectl -n istio-system delete secret httpbin-credential
kubectl create -n istio-system secret generic httpbin-credential \
--from-file=key=httpbin.example.com/3_application/private/httpbin.example.com.key.pem \
--from-file=cert=httpbin.example.com/3_application/certs/httpbin.example.com.cert.pem
kubectl create -n istio-system secret generic httpbin-credential-cacert \
--from-file=cacert=httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem
istio安全之Citadel相关推荐
- 如何使用 Istio 进行多集群部署管理(一)
作者 | 王夕宁 阿里云高级技术专家 参与阿里巴巴云原生公众号文末留言互动,即有机会获得赠书福利! **导读:**本文摘自于由阿里云高级技术专家王夕宁撰写的<Istio 服务网格技术解析与实践 ...
- 乘风破浪,.Net Core遇见Dapr,为云原生而生的分布式应用运行时
Dapr是一个由微软主导的云原生开源项目,国内云计算巨头阿里云也积极参与其中,2019年10月首次发布,到今年2月正式发布V1.0版本.在不到一年半的时间内,github star数达到了1.2万,超 ...
- 万字长文从 0 详解 Istio
- 前言 - 在本教程中,我们将介绍服务网格的基础知识,并了解它如何实现分布式系统架构. 我们将主要关注Istio,它是服务网格的一种具体实现.在此过程中,我们将介绍Istio的核心架构 ...
- 图解Istio原理和实践--云平台技术栈18
" 如果你比较关注新兴技术的话,那么很可能在不同的地方听说过 Istio,并且知道它和 Service Mesh 有着牵扯. 导读:之前发布了云平台技术栈(ps:点击可查看),本文主要说一下 ...
- 深入浅出Istio:Service mesh快速入门与实践-读书笔记(By GisonWin)
01 服务网格历史 (以后补充) 02 服务网格的基本特性 连接 微服务错综复杂,要完成其业务目标,连接问题是首要问题.连接存在于所有服务的整个lifcecycle中,用于维持服务的运行. 安全 保障 ...
- Istio所有模块、Service、Pod的功能介绍
[TOC] Istio所有模块.Service.Pod的功能介绍 Istio模块 Proxy(Envoy) 流量代理,不可缺少 Pilot 服务发现.流量管理.智能路由等 Mixer 遥测相关 Cit ...
- Service Mesh — Istio
目录 文章目录 目录 Istio Istio 的软件架构 Istio Istio 提供了一系列高阶的服务治理能力,比如: 服务发现 负载均衡 渐进式交付(灰度发布) 混沌注入与分析 全链路追踪 零信任 ...
- Istio 1.3 发布:HTTP 遥测不再需要 Mixer
点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 作者 | 米开朗基杨 来源 | 公众号「云原生实验室」 Istio 是 Google.IBM ...
- Istio,灰度发布从未如此轻松!!!
三个问题,回顾前情提要. ServiceMesh解决什么问题? SM本质是业务服务与底层技术体系的解耦: 一个进程实现业务逻辑(不管是调用方,还是服务提供方),biz,即上图白色方块 一个进程实现底层 ...
最新文章
- 免费正则表达式辅助工具(转)
- RDKit:基于RDKit的溶解度预测的机器学习模型
- 百度 什么是主成分分析
- Clone Detective java home
- 一个jsp内嵌一个jsp
- python plot方法的使用_【python】matplotlib.pyplot入门
- 原型模式coding-克隆破坏单例
- 【项目经验】在填写表单时,首先添加一个失去焦点事件,将数据库中信息自动填充信息到表单,其余信息手动填写然后提交表单。
- 声明式事务基于注解@Transactional的理解
- C++ 对引用的理解5
- 怎么在linux上修改mysql端口映射_如何在Linux中更改默认的MySQL / MariaDB端口
- 那两个告扎克伯格抄袭的斜杠青年,后来怎么样了?
- 芯片短缺蔓延至手机市场:骁龙888短缺 三星中低端机型生产受阻
- 滴滴柳青探望被害司机家属;支付宝信用卡还款收费;ofo 查处 8 起贪腐案件 | 极客头条...
- HTML知识点详细汇总
- SDOI2015 约数个数和
- MATLAB画图详细教程
- kali2020出现中文乱码解决
- error: Microsoft Visual C++ 14.0 is required. Get it with “Microsoft Visual C++ Build Tools,亲测100%安装
- python可以做回归分析吗_使用python进行回归分析
热门文章
- 农村宅基地审批管理系统
- yolov5踩过的初坑(关于detect代码可以调用gpu而训练代码无法调用gpu的问题)
- 电子样本管理系统v1 v1.1.3
- 矩阵行秩与列秩的关系。
- uniswap - V3技术白皮书导读
- 【多模态学习】本周学习历程,附链接
- Leetcode典型题解答和分析、归纳和汇总——T46(全排列)
- 跑出数字化升级“加速度”,腾讯云启产业基地“长沙模式”的探索
- 工业视觉 四 曝光与增益 、伽马、饱和度、对比度、锐度、黑电平
- MATLAB-自动控制原理-时域分析