news 2026/9/13 5:47:37

Metabase 测试 SSL 证书实战:用 cfssl 生成本地 CA 与服务器证书并驱动 Driver 测试管线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Metabase 测试 SSL 证书实战:用 cfssl 生成本地 CA 与服务器证书并驱动 Driver 测试管线

Metabase 测试 SSL 证书实战:用 cfssl 生成本地 CA 与服务器证书并驱动 Driver 测试管线

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

test_resources/ssl/是 Metabase 仓库中一套为“把服务当作 localhost 运行”而准备的测试证书资产,涵盖 CA 与服务器证书的生成方法(基于 cfssl)、各文件的用途说明,以及这些证书如何被 driver 层的 SSL 工具函数和单元测试消费。读完本文,你可以完整复现这套证书的重建流程,理解 CA、服务器证书与 SAN hostname 的对应关系,并看清这些测试资产在 Metabase 后端测试管线中的真实调用链路与再生成证书时的注意事项。

一、这套测试证书的定位与文件清单

Metabase 需要连接支持 SSL/TLS 的数据库(Mongo、Oracle 等),其 driver 测试管线必须持有可用的密钥与证书文件。test_resources/ssl/顶层目录提供了一组本地测试证书,目录说明 明确其用途是“running a service as localhost”。目录内各文件的职责如下:

文件用途
ca-csr.json生成 CA 所用的 CSR 配置
ca-key.pemCA 的私钥
ca.pemCA 的公钥证书(即客户端需要“信任”的部分)
server-csr.json生成服务器密钥所用的 CSR 配置
server.keyserverd服务器证书的私钥
server.pemserver.key对应的公钥证书
ca.csr生成过程产出的 CSR 中间文件

除顶层文件外,该目录还包含两个面向具体数据库驱动的证书子目录:mongo/ 与 oracle/,后者会在第四部分展开。

二、用 cfssl 生成 CA 与服务器证书

这套证书由 Cloudflare 开源的证书工具 cfssl 生成。原 README 给出的两条命令是完整的最小生成流程:

1. 生成 CA(自签名根证书)

cfssl genkey -initca ca-csr.json | cfssljson -bare -stdout
  • cfssl genkey -initca读取 CSR 配置并生成“初始 CA”:产出 CA 的 CSR 与私钥,并由该 CA 自签名出根证书;
  • 管道后接cfssljson -bare -stdout将 cfssl 的输出 JSON 拆解为裸文件(-bare会去掉文件名中的随机后缀),直接输出到标准输出。

ca-csr.json 的内容非常简洁,关键参数如下:

{ "hosts": [ "127.0.0.1" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Seattle", "O": "Someone", "OU": "WWW", "ST": "Washington" } ] }
  • hosts指定了证书 subjectAltName 覆盖127.0.0.1,这是本地服务回环地址校验的基础;
  • key指定 RSA 2048 位密钥;
  • names中的C/L/O/OU/ST组成证书 DN(Distinguished Name),即ou=www,o=someone,l=seattle,st=washington,c=us——这个 DN 后面会出现在单元测试的断言里。

2. 生成服务器证书(由该 CA 签发)

cfssl gencert -ca ca.pem -ca-key ca-key.pem -hostname=127.0.0.1,localhost server-csr.json | cfssljson -bare -stdout
  • -ca ca.pem -ca-key ca-key.pem指定用刚生成的 CA 证书与 CA 私钥来签发服务器证书,形成“CA → 服务器证书”的信任链;
  • -hostname=127.0.0.1,localhost将两个主机名写入 SAN,使同一张证书既能匹配127.0.0.1又能匹配localhost,与“running a service as localhost”的用途直接对应;
  • server-csr.json 中额外声明了"CN": "server.local",且hosts同时包含127.0.0.1localhost,与命令行-hostname参数保持一致。

cfssljson -bare的输出命名以输入文件名(去掉扩展名)为前缀:CA 流程产出ca.csrca-key.pemca.pem,服务器流程产出server.csrserver.keyserver.pem,与目录中实际存在的文件一一对应。

三、这些证书在 Metabase 源码中的真实消费链路

证书生成只是第一步,更关键的是它们在测试管线里如何被消费。

1. 单元测试如何读取这些文件

test/metabase/driver/util_test.clj 中的generate-trust-store-test直接以相对路径读取本目录的两个证书:

(let [cert-string (slurp "./test_resources/ssl/ca.pem") keystore (driver.u/generate-trust-store cert-string)] (is (true? (.containsAlias keystore test-ca-dn))))

该测试还覆盖:

  • 传入非法证书字符串"fooobar"时必须抛出java.security.cert.CertificateException
  • ca.pemserver.pem拼接成多证书字符串后,信任库应同时包含 CA 与服务器证书两个别名;
  • ca.pem构造ssl-socket-factory应返回javax.net.ssl.SSLSocketFactory实例。

值得注意的是测试文件顶部的两个常量与注释(util_test.clj):

;; if the CA certificate (ca.pem) used in this test is regenerated, ;; you'll need to update this DN (def ^:private test-ca-dn "ou=www,o=someone,l=seattle,st=washington,c=us") ;; if the server certificate (server.pem) used in this test is regenerated, ;; you'll need to update this DN (def ^:private test-server-dn "cn=server.local,ou=www,o=someone,l=seattle,st=washington,c=us")

这印证了第二部分的 CSR 配置与测试断言之间的强耦合:证书别名取自证书的 DN 字符串,若按 ca-csr.json / server-csr.json 原样重新生成,这两个 DN 常量可保持不变;一旦修改namesCN,就必须同步更新这两个常量,否则断言失败。

2. driver 层 SSL 工具的实现原理

上述测试调用的工具函数定义在 src/metabase/driver/util.clj,其“TLS Helpers”部分构成一条清晰的调用链:

  • dn-for-cert:通过getSubjectX500Principal getName提取证书 DN,作为 KeyStore 条目的别名来源;
  • parse-certificates:用CertificateFactory/X.509从 PEM 字符串解析出一组证书——这正是generate-trust-store支持“多证书拼接字符串”的原因;
  • generate-identity-store:把 PEM 私钥(parse-rsa-key做 PKCS8 解码)与证书链装入KeyStore,以证书 DN 为别名写入setKeyEntry,用于“身份证明”(client 侧);
  • generate-trust-store:除了把传入的自定义证书逐一setCertificateEntry之外,还会初始化一个TrustManagerFactory,把 JVM 默认信任库中全部getAcceptedIssuers也克隆进新的 KeyStore——即“内置 CA + 自定义 CA”合并信任;
  • ssl-context/ssl-socket-factory:组装KeyManager(需要private-key+own-cert)与TrustManager(需要trust-cert),最终产出SocketFactory

从源码结构看,test_resources/ssl/顶层证书主要覆盖“仅信任”这一路径(trust-cert分支),而完整的双向身份验证路径则由ssl-socket-factory-test(util_test.clj)用 mongo/ 目录下的metabase.keymetabase.crtmetaca.crt来验证,例如仅凭信任信息、仅凭身份信息两种组合都应能成功构造SSLSocketFactory

四、面向具体数据库的证书子目录

1. mongo/:Mongo SSL 测试客户端证书

mongo/README.md 说明该目录支撑metabase-qa的 Mongo docker 服务(支持 plain、ssl、tls 不同 SSL 配置),run-server.sh 用于拉起测试服务器。其要点是:docker 镜像是“source of truth”,容器启动时会把后端测试所需的客户端密钥与客户端/CA 证书拷贝进该目录;但客户端证书仍然签入仓库,因为ssl-socket-factory等测试必须在 CI 中拿到有效证书与密钥。文档同时给出了对 TLS Mongo 跑测试的完整命令:

MB_MONGO_TEST_USER=metabase MB_MONGO_TEST_PASSWORD=metasample123 MB_TEST_MONGO_REQUIRES_SSL=1 DRIVERS=mongo clj -X:dev:ci:ee:ee-dev:drivers:drivers-dev:test

这与第三部分ssl-socket-factory-test中读取的ssl/mongo/metabase.keymetabase.crtmetaca.crt资源路径相互印证(测试中客户端密钥口令为"passw")。

2. oracle/:PKCS12 格式的 keystore 与 truststore

oracle/README.md 说明 keystore.p12 与 truststore.p12 是 CI 中测试 Oracle driver SSL 认证所用的 PKCS12 keystore:

  • keystore.p12包含CN=metabase,C=US的私钥与公钥,以及由 docker 镜像内 CA 签发的证书;
  • truststore.p12包含 docker 镜像内自签名 CA 的证书。

这两个 keystore 与metabase/qa-databases:oracle-xe-21.3测试镜像配套,整体配置遵循 Oracle JDBC thin 客户端的 SSL 方案。与顶层目录的 PEM 文件相比,这里体现的是 Java 生态常见的 PKCS12 二进制 keystore 形态,对应 driver 连接配置中 keystore 类型的信任/身份材料。

五、实践要点与适用边界

  • 复现生成:只需安装 cfssl,按“第二部分”两条命令在 test_resources/ssl/ 下执行即可重建ca.*server.*文件;-hostname参数决定 SAN 覆盖范围,本地服务场景应保持127.0.0.1,localhost不变。
  • 再生成的同步义务:修改 ca-csr.json 或 server-csr.json 的names/CN后,util_test.clj 中test-ca-dntest-server-dn两个 DN 常量必须同步更新,这是测试注释中明示的约束。
  • 信任库语义generate-trust-store并非“只信传入的 CA”,而是自定义证书叠加 JVM 默认信任(见 util.clj),理解这一点有助于判断哪些自签名场景会被该测试信任链接受。
  • 资产边界:这些文件全部服务于测试管线(本地 localhost 服务、Mongo/Oracle QA 镜像),私钥以明文 PEM 形式存放且被测试硬编码引用(如口令"passw"),不应在任何生产环境复用;生产连接应使用正规 CA 签发的证书,并通过 Metabase 数据库连接配置中的 SSL/keystore 选项提供。

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 5:47:06

Android音视频开发核心技术解析与实践指南

1. Android音视频处理的核心场景与技术栈在移动应用开发领域,音视频处理能力已经成为衡量应用成熟度的重要指标。从社交应用的实时通话到短视频平台的滤镜特效,从在线教育课件录制到车载娱乐系统,音视频技术贯穿了现代移动体验的各个环节。An…

作者头像 李华
网站建设 2026/9/13 5:46:28

2024学生装机指南:6000-8000元Intel Ultra 7 265K配置方案

1. 学生装机需求分析与市场定位 6000-8000元价位段一直是学生群体装机的主力预算区间,这个价格带既能保证主流游戏的流畅运行,又能兼顾学习、创作等生产力需求。作为2024年Intel推出的重磅产品,Ultra 7 265K凭借其混合架构设计和出色的能效比…

作者头像 李华
网站建设 2026/9/13 5:44:35

现代科技环境下主体性缺失与重建路径探析

1. 现代人主体性缺失的现象观察每天早上七点,数百万上班族被手机闹铃惊醒,机械地刷着社交媒体推送,匆忙吞下标准化早餐,挤进地铁车厢开始日复一日的通勤。办公室里,人们熟练地使用着企业规定的沟通话术,在K…

作者头像 李华
网站建设 2026/9/13 5:44:10

大模型开发资料获取与高效学习方法

1. 大模型开发资料获取的现状与挑战 当前大模型开发已成为AI领域最热门的方向之一,但高质量开发资料的获取却面临三大痛点:信息碎片化、技术门槛高、资源筛选困难。根据2023年AI开发者调查报告显示,78%的开发者表示在入门大模型时遇到过"…

作者头像 李华