istio证书签发流程
envoy 中的证书验证
•combined_validation_context
组合的证书验证上下文包含默认的CertificateValidationContext和SDS配置。当SDS服务器返回动态CertificateValidationContext时,动态和默认的CertificateValidationContext都将合并到新的CertificateValidationContext中以进行验证。此合并是通过Message::MergeFrom()完成的,因此动态的CertificateValidationContext会覆盖默认CertificateValidationContext中的单个字段,并将重复的字段连接到默认CertificateValidationContext中。
•validation_context_sds_secret_config
通过SDS API获取验证上下文的配置。
•tls_certificate_sds_secret_configs
通过SDS API获取TLS证书的配置
•default_validation_context
如何验证对等证书。
•match_subject_alt_names
Subject Alternative Name匹配器的可选列表.envoy将验证所提供证书的Subject Alternative Name
是否与指定的匹配项之一匹配。当证书具有通配符DNS SAN条目时,为了匹配特定的客户端,应在字符串匹配器中将其配置为完全匹配类型。例如,如果证书的DNS SAN条目具有*.example.com
,则仅允许api.example.com
,则应按如下所示进行配置。
match_subject_alt_names: exact: "api.example.com"
pilot agent处理SDS流程
constructProxyConfig 构造proxy config getDNSDomain 根据registry生成域名
istio_agent.NewAgent 初始化agent
sa.Start(role.Type == model.SidecarProxy, podNamespaceVar.Get()) 开始启动SDS agent,默认为sidecar模式,网关需要启动为route模式
NewServer
创建SDSserver
对于sidecar模式,将执行initWorkloadSdsService进行grpc server初始化,
initWorkloadSdsService 初始化SDS service
通过s.workloadSds.register(s.grpcWorkloadServer),进行服务注册,需要实现以下接口
type SecretDiscoveryServiceServer interface { DeltaSecrets(SecretDiscoveryService_DeltaSecretsServer) error // SDS API StreamSecrets(SecretDiscoveryService_StreamSecretsServer) error // 获取secret FetchSecrets(context.Context, *envoy_api_v2.DiscoveryRequest) (*envoy_api_v2.DiscoveryResponse, error)}
FetchSecrets
FetchSecrets处理单次证书请求 通过s.st.GenerateSecret生成secret并返回,然后调用GenerateSecret,判断请求证书是否为rootca,若不是将调用generateSecret
如果开启了第三方的exchanger,则进行exchanger进行验证,现在支持Google auth 生成csr后通过sendRetriableRequest提交给pilot-discovery, sendRetriableRequest调用CSRSign方法进行证书签发,这里实际上会请求istiod(pilot-discovery)
发送请求到认证中心签发证书func (c *citadelClient) CSRSignfunc (c *istioCertificateServiceClient) CreateCertificate(ctx context.Context, in *IstioCertificateRequest, opts ...grpc.CallOption) 请求下面的接口进行证书签发/istio.v1.auth.IstioCertificateService/CreateCertificate"
StreamSecrets
FetchSecrets处理双向通信,具体操作和FetchSecrets类似
##startXDS
创建xdsclient和xdsserver,用于处理envoy请求和请求pilot-discovery
ca server签发证书流程
s.maybeCreateCA
查看目录是否有对应的文件,否则生成自签名证书,作为根证书,后续将使用该证书签发证书
s.startCA
caOpts := &CAOptions{ TrustDomain: s.environment.Mesh().TrustDomain, Namespace: args.Namespace,}
实际上调用的 s.RunCA
s.RrunCA 调用detectAuthEnv,获取k8s token pay load,内容如下示例
{"iss":"kubernetes/serviceaccount","kubernetes.io/serviceaccount/namespace":"istio-system","kubernetes.io/serviceaccount/secret.name":"istiod-service-account-token-h2mxh","kubernetes.io/serviceaccount/service-account.name":"istiod-service-account","kubernetes.io/serviceaccount/service-account.uid":"2f08fe65-6a69-4c2a-881b-8823b90dea60","sub":"system:serviceaccount:istio-system:istiod-service-account"}
caserver.NewWithGRPC
注册以下 Authenticator
•ClientCertAuthenticator
对于VM,允许使用以前颁发的证书进行授权。对于VM,将返回具有从SAN提取的身份的调用方,应为SPIFFE身份。
1.判断auth type2.判断证书链的合法性
•KubeJWTAuthenticator
1.解析bear token 2. 根据集群名称获取kubeclient 3. 调用tokenreview.ValidateK8sJwt函数对token进行验证 4. 调用k8s api server token review接口对token进行验证
然后对server进行初始化
caServer.Run()
注册下列 grpc api 用于处理证书请求 pb.RegisterIstioCertificateServiceServer(grpcServer, s)
_IstioCertificateService_CreateCertificate_Handler
srv.(IstioCertificateServiceServer).CreateCertificate(ctx, req.(*IstioCertificateRequest))
实际调用以下方法创建证书 func (s *Server) CreateCertificate
首先调用s.authenticate(ctx)用于认证客户端身份,该方法调用authn.Authenticate(ctx),也就是上面所注册的验证器进行客户端身份验证,返回caller
&Caller{ AuthSource: AuthSourceIDToken, Identities: []string{fmt.Sprintf(identityTemplate, a.trustDomain, callerNamespace, callerServiceAccount)},}
返回的caller主要包含证书的身份用于后续签发时的Subject Alternative Name,格式如下
spiffe://cluster.local/ns/foo/sa/httpbin
该字段也会用于服务授权
验证成功后
调用s.ca.GetCAKeyCertBundle().GetAll()获取证书链以及跟证书 s.ca.Sign根据csr,subjectIDs,requestedLifetime,对csr进行签发,requestedLifetime默认为24小时
最终调用util.GenCertFromCSR签发证书
- Python内置数据结构之字符串
- Discuz!X ≤3.4 任意文件删除漏洞分析
- 从学习 Paddle 开始学习深度学习
- 使用ffpython嵌入和扩展python
- FFLIB之FFLUA——C++嵌入Lua&扩展Lua利器
- Python之匿名函数
- H2Engine游戏服务器设计之属性管理器
- linux epoll 开发指南-【ffrpc源码解析】
- Python之递归函数
- 你不得不会的MarkDown
- 状态机的实现探讨
- Docker入门实战(二)——Docker镜像操作
- 使用强大的 Mockito 来测试你的代码
- java学习手册-CentOS 6.3(x86_32)下安装Oracle 10g R2
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ggplot2 核密度图和直方图
- 喜欢的歌曲不在一个平台怎么办?你需要一个自己专属的音乐播放器
- ggplot_QQ图和ECDF
- tidyverse evaluation
- 下载歌曲的时候嫌麻烦?打造专属你的音乐下载器
- Tidyverse补充
- 抖音关键词热度搜索小程序(附源码)
- python自定义函数基础
- Python-科学计算-pandas-13-列名/删除列/替换nan
- python小程序,45行代码实现可切换版代码雨(附源码)
- R海拾遗-stringr
- stringr2
- Kubernetes 无状态应用的一般特征
- 一段简单的代码,能让所有GIF图实现时光倒流
- 你喜欢的女主播颜值多少分,今天带你测试虎牙直播女主播的颜值