ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Apache Pulsar Etcd 元数据存储 TLS 测试证书:基于 cfssl 的自签名证书生成与使用指南

Apache Pulsar Etcd 元数据存储 TLS 测试证书:基于 cfssl 的自签名证书生成与使用指南 消息队列后端【免费下载链接】pulsarApache Pulsar - distributed pub-sub messaging system项目地址https://gitcode.com/gh_mirrors/pulsar24/pulsar点击查看免费下载导读Apache Pulsar 使用 pulsar-metadata 模块对接 Etcd 作为元数据存储并在其测试套件中完整覆盖了 Etcd TLS 加密通道场景。本文以仓库中 pulsar-metadata/src/test/resources/ssl/README.md 为线索系统讲解该目录下 Etcd TLS 测试证书的目录结构、generate-self-signed-certificates.sh自签名证书生成脚本的每一步原理以及证书如何被 EtcdMetadataStoreTest.java 和EtcdConfig配置项消费。读完本文你将掌握用 Cloudflare cfssl 为 Etcd 集群签发 CA 与多主机证书的完整流程并理解 Pulsar 中useTls、tlsTrustCertsFilePath、tlsKeyFilePath、tlsCertificateFilePath、authority等 TLS 配置参数的底层实现。一、ssl目录的定位Etcd 元数据测试的证书仓库在 Apache Pulsar 仓库中pulsar-metadata模块负责封装 ZooKeeper、Etcd、RocksDB 等元数据后端。当使用 Etcd 作为元数据存储并开启 TLS 时测试环境需要一个完整的公钥基础设施PKI包括证书颁发机构CA、Etcd 服务端证书和客户端证书。ssl 目录 正是为这一目的而存在。其 README.md 明确说明了两点约束该目录专用于 Etcd 元数据测试This directory is used for Etcd metadata testing不允许修改目录结构DO NOT EDIT THIS DIRECTORY STRUCTURE——因为测试代码通过Resources.getResource(ssl/cert/...)以固定相对路径加载证书任何目录结构变更都会导致测试失效。目录由三部分组成组成部分说明cert/存放 Etcd TLS 证书CA、服务端、客户端及其 CSR、私钥generate-self-signed-certificates.sh基于 Cloudflare cfssl 生成上述自签名证书的脚本.gitignore忽略cfssl临时二进制目录避免污染版本库二、证书生成脚本逐段拆解generate-self-signed-certificates.sh 是从 jetcd 项目移植而来脚本头部注释注明了来源。它完成下载 cfssl → 生成 CA → 签发各主机证书 → 转换密钥格式的完整链路。2.1 准备 cfssl 工具链脚本首先规划了两个工作目录ROOT$(cd $(dirname $0) pwd) CFSSL_HOME${ROOT}/cfssl # cfssl 二进制存放目录已被 .gitignore 忽略 CERT_HOME${ROOT}/cert # 证书输出目录随后根据操作系统选择二进制平台并通过 GitHub Releases 下载 cfssl v1.6.1 及其配套的cfssljsonOS$(uname -s) case $OS in Linux) PLATFORMlinux_amd64 ;; Darwin) PLATFORMdarwin_amd64 ;; esac curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_${PLATFORM} cfssl/cfssl curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_${PLATFORM} cfssl/cfssljson chmod x cfssl/{cfssl,cfssljson}要点固定使用 cfsslv1.6.1版本保证证书行为可复现只支持linux_amd64与darwin_amd64两种平台其他系统如 ARM 架构需要自行调整 PLATFORM 值下载依赖外网访问 GitHub离线环境需提前放置好两个二进制。2.2 生成 CA 根证书与签名策略脚本先以 JSON 描述生成 CAecho {CN:CA,key:{algo:rsa,size:2048}} \ | $CFSSL_HOME/cfssl gencert -initca - \ | $CFSSL_HOME/cfssljson -bare ca -即签发一个 CN 为CA、RSA 2048 位的自签根证书产物为ca.pem证书、ca-key.pem私钥、ca.csr证书签名请求。随后生成签名策略文件 ca-config.json{signing:{default:{expiry:876000h,usages:[signing,key encipherment,server auth,client auth]}}}这里的关键含义expiry: 876000h即 100 年测试证书长期有效无需频繁重新签发usages同时包含server auth与client auth意味着同一套 CA 签发的证书既能充当服务端证书也能充当客户端证书这正是后续一套证书、双向认证测试的基础。2.3 为 Etcd 集群各节点签发服务端证书脚本依次为 5 个主机名签发证书逻辑完全一致仅NAME与ADDRESS即 SAN/Subject Alternative Name不同export ADDRESSetcd-ssl export NAMEserver echo {CN:$NAME,hosts:[],key:{algo:rsa,size:2048}} \ | $CFSSL_HOME/cfssl gencert -configca-config.json -caca.pem -ca-keyca-key.pem \ -hostname$ADDRESS - \ | $CFSSL_HOME/cfssljson -bare $NAME被签发的 5 个主机名及其用途NAMEADDRESSSAN产物用途serveretcd-sslserver.pem、server-key.pem、server.csr服务端证书对应 etcd 集群对外域名etcd0etcd0etcd0.pem、etcd0-key.pem、etcd0.csr第一个 Etcd 节点etcd1etcd1etcd1.pem、etcd1-key.pem、etcd1.csr第二个 Etcd 节点etcd2etcd2etcd2.pem、etcd2-key.pem、etcd2.csr第三个 Etcd 节点SANSubject Alternative Name是 TLS 校验的关键客户端连接etcd://etcd0:...时会校验服务端证书的 SAN 是否包含etcd0。证书生成后使用openssl可验证openssl x509 -in pulsar-metadata/src/test/resources/ssl/cert/etcd0.pem -noout -text | grep -A1 Subject Alternative Name从 server.pem 的 X.509 扩展字段可以看到其 SAN 确实被写入为etcd-ssl与脚本中-hostnameetcd-ssl一一对应。2.4 签发客户端证书并转换为 PKCS#8 格式export ADDRESS export NAMEclient echo {CN:$NAME,hosts:[],key:{algo:rsa,size:2048}} \ | $CFSSL_HOME/cfssl gencert -configca-config.json -caca.pem -ca-keyca-key.pem \ -hostname$ADDRESS - \ | $CFSSL_HOME/cfssljson -bare $NAME openssl pkcs8 -topk8 -inform PEM -outform PEM -in client-key.pem -out client-key-pk8.pem -nocrypt客户端证书的ADDRESS为空即不含任何 SAN——客户端身份仅由 CN 标识。最后一步值得特别注意脚本将client-key.pem通过 OpenSSL 转换为PKCS#8 未加密格式的 client-key-pk8.pem。这是因为 Java 的 TLS 密钥管理KeyManager对 PKCS#8 格式的兼容性最好而测试代码加载的正是这个client-key-pk8.pem详见下文。2.5 完整产物清单脚本运行后cert 目录 应包含ca-config.json # cfssl 签名策略100 年有效期server/client auth ca-key.pem # CA 私钥必须保密 ca.csr / ca.pem # CA 的 CSR 与根证书 server-key.pem / server.csr / server.pem # SANetcd-ssl 的服务端证书 etcd0-key.pem / etcd0.csr / etcd0.pem # SANetcd0 etcd1-key.pem / etcd1.csr / etcd1.pem # SANetcd1 etcd2-key.pem / etcd2.csr / etcd2.pem # SANetcd2 client-key.pem / client.csr / client.pem # 客户端证书 client-key-pk8.pem # 客户端私钥PKCS#8 未加密三、测试如何消费这些证书3.1 三个测试场景EtcdMetadataStoreTest.java 中针对 Etcd 元数据存储设计了三个由浅入深的测试testCluster3 节点 Etcd 集群useTls(false)验证普通明文通道下的元数据读写put后exists断言testClusterWithTls3 节点 Etcd 集群useTls(true)验证 TLS 加密通道下同样的读写能力testTlsInstance单节点 Etcd 集群useTls(true)验证最小规模 TLS 部署。3.2 TLS 测试的配置构造以testClusterWithTls为例测试通过EtcdConfig.builder()构造 TLS 配置再从 classpath 资源中加载证书路径EtcdConfig etcdConfig EtcdConfig.builder() .useTls(true) .tlsProvider(null) .authority(etcd0) .tlsTrustCertsFilePath(Resources.getResource(ssl/cert/ca.pem).getPath()) .tlsKeyFilePath(Resources.getResource(ssl/cert/client-key-pk8.pem).getPath()) .tlsCertificateFilePath(Resources.getResource(ssl/cert/client.pem).getPath()) .build();三个证书路径恰好对应脚本的三个产物形成完整信任链ca.pem作为信任锚trust manager 校验服务端证书链到 CAclient-key-pk8.pem作为客户端私钥PKCS#8 格式client.pem作为客户端证书向服务端证明客户端身份用于双向 TLS。authority(etcd0)用于覆盖证书的 SAN 校验目标配合 Etcd 节点 SAN 使用。配置通过 YAML 落盘后以MetadataStoreConfig.builder().configFilePath(...)传入最终由MetadataStoreFactory.create(etcd:..., config)创建真实的 Etcd 元数据存储实例并执行读写断言。四、TLS 配置项的源码级解读4.1 配置文件模板仓库在 etcd_config_example.yml 中给出了完整的 Etcd TLS 配置模板共 6 个字段# Configure whether to use TLS connection useTls: false # Name for TLS provider: one of OPENSSL, JDK tlsProvider: # Path for the trusted TLS certificate file tlsTrustCertsFilePath: # Path for the TLS private key file tlsKeyFilePath: # Path for the TLS certificate file tlsCertificateFilePath: # Override SAN(Subject Alternative Name) of certificate authority:字段含义如下配置项类型默认值说明useTlsbooleanfalse是否启用 TLS 连接为true时才会加载其余证书配置tlsProviderenum空TLS Provider可选OPENSSL或JDK为空时使用 Netty/gRPC 默认实现tlsTrustCertsFilePathstring空受信任的 CA 证书路径用于校验服务端身份tlsKeyFilePathstring空客户端私钥路径脚本生成的是 PKCS#8 未加密格式tlsCertificateFilePathstring空客户端证书路径authoritystring空覆盖证书 SAN 校验目标的主机名4.2newEtcdClient的底层实现EtcdMetadataStore.java 的newEtcdClient方法是这些配置的实际消费点调用链为从元数据 URL 中剥离etcd:前缀得到逗号分隔的 endpoint 列表若设置了configFilePath用 Jackson YAML 反序列化为EtcdConfig对象该内部类定义在同一文件第 494 行附近字段与 YAML 模板一一对应当useTlstrue时读取三个证书文件并用 Netty 的GrpcSslContexts.forClient()构建客户端 SSL 上下文if (etcdConfig.isUseTls()) { File trustCertsFile readFile(etcdConfig.getTlsTrustCertsFilePath()); File keyFile readFile(etcdConfig.getTlsKeyFilePath()); File certFile readFile(etcdConfig.getTlsCertificateFilePath()); SslContext context GrpcSslContexts.forClient() .trustManager(trustCertsFile) .sslProvider(etcdConfig.getTlsProvider()) .keyManager(certFile, keyFile) .build(); clientBuilder.sslContext(context); }若设置了authority则通过clientBuilder.authority(...)覆盖 gRPC 通道的校验主机名对应脚本中证书 SAN 的作用if (StringUtils.isNotEmpty(etcdConfig.getAuthority())) { clientBuilder.authority(etcdConfig.getAuthority()); }从源码可以看出keyManager(certFile, keyFile)接受的正是client.pem与client-key-pk8.pem这一对密钥证书组合而trustManager(trustCertsFile)校验的是ca.pem签发的服务端证书链——这就是脚本生成三件套 → 测试消费三件套的完整闭环。五、实践要点与常见问题5.1 重新生成证书当测试证书过期或需要更换主机名时在pulsar-metadata/src/test/resources/ssl目录下直接执行bash generate-self-signed-certificates.sh脚本会重新下载 cfssl、重建cert目录下的全部证书。注意脚本会覆盖cert下的同名证书文件若需保留旧证书请先备份cfssl二进制目录已被 .gitignore 忽略不会进入版本库仓库的 README.md 明确要求保持目录结构不变新增或移动证书文件会破坏测试的资源加载路径。5.2 三个容易踩的坑客户端私钥格式Java KeyManager 需要 PKCS#8 格式私钥因此脚本专门用openssl pkcs8 -topk8 ... -nocrypt生成client-key-pk8.pem。测试代码加载的是client-key-pk8.pem而非原始的client-key.pem两者不可混用SAN 必须匹配Etcd 服务端证书的 SANetcd0/etcd1/etcd2/etcd-ssl必须与客户端连接的主机名或authority覆盖值一致否则 TLS 握手会在证书主机名校验阶段失败双向 TLSca-config.json中同时启用了server auth和client auth配合测试中同时提供客户端证书与私钥实际验证的是 etcd 与 Pulsar 客户端之间的双向认证链路。结语Apache Pulsar 在pulsar-metadata模块中为 Etcd 元数据存储准备了完整、可复现的 TLS 测试基础设施generate-self-signed-certificates.sh用 cfssl 一键生成 100 年有效期的 CA 及多主机证书cert目录按约定结构存放全部产物而 EtcdMetadataStoreTest.java 与 EtcdMetadataStore.java 则分别从测试与实现两个层面验证了EtcdConfig各 TLS 配置项的真实行为。理解这套机制既能帮助你读懂 Pulsar 的元数据层测试也可以直接复用到自己项目中 Etcd TLS 证书的生成与管理实践。赞分享消息队列后端【免费下载链接】pulsarApache Pulsar - distributed pub-sub messaging system项目地址https://gitcode.com/gh_mirrors/pulsar24/pulsar点击查看免费下载相关推荐Nomad TLS 证书生成实战用 nomad tls 命令创建自签名证书与测试证书Nomad TLS 证书生成实战用 nomad tls 命令创建自签名证书与测试证书 本指南围绕 Nomad 仓库中 helper/tlsutil/testd任务调度云原生运维后端etcd 集群的 TLS 证书怎么生成用仓库自带 cfssl 脚本签发 CA、client 与 peer 证书etcd 集群的 TLS 证书怎么生成用仓库自带 cfssl 脚本签发 CA、client 与 peer 证书 给 etcd 集群开启 TLS客户端走 HT后端数据库分布式数据库KV存储云原生服务注册发现配置中心Databend 测试 TLS 证书体系全解析基于 cfssl OpenSSL 的证书生成、轮换与集成Databend 测试 TLS 证书体系全解析基于 cfssl OpenSSL 的证书生成、轮换与集成 导读 Databend 的 TLS 相关能力My数据库数据分析向量数据库全文检索云原生AI 应用上一篇i茅台自动预约系统5分钟快速部署的智能茅台抢购解决方案下一篇GPT-Neo 1.3B13亿参数开源语言模型完全指南 创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表