Metabase MongoDB SSL/TLS 测试基础设施用 Docker 拉起 requireTLS 的 Mongo 并跑通驱动集成测试【免费下载链接】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本篇技术指南围绕 Metabase 仓库中 test_resources/ssl/mongo/README.md 展开讲解如何借助 run-server.sh 一键启动带 TLS 的 MongoDB 测试服务器理解该目录下metabase.crt、metabase.key、metaca.crt三份客户端证书的来源与作用并结合 modules/drivers/mongo 的驱动源码说明 Metabase 是如何把这三个文件装配进MongoClientSettings的 SSL 上下文中完成双向认证的。读完本文你可以完整复现启动加密 Mongo → 设置环境变量 → 运行 Mongo 驱动集成测试的端到端流程。这套测试基础设施解决什么问题Metabase 的 MongoDB 驱动需要支持加密连接TLS/SSL以及客户端证书双向认证而 CI 和本地开发环境必须有一个可重复启动的、强制加密的 MongoDB 实例来验证这些路径。test_resources/ssl/mongo/ 目录就是为此存在的它提供一个基于 Docker 的 metabase-qa MongoDB 服务器启动脚本 run-server.sh支持不同 Mongo 版本与不同 SSL 配置plain、ssl、tls后端测试所需的客户端密钥与证书客户端证书 CA 证书供驱动在建立 SSL 连接时作为 classpath 资源加载。目录布局test_resources/ssl/mongo/ 下共四个文件文件作用README.md本说明文档run-server.sh用 Docker 启动 metabase-qa Mongo 服务器metabase.crt客户端证书client-ssl-certmetabase.key客户端私钥client-ssl-keymetaca.crtCA 证书用于信任服务端ssl-cert需要特别说明的是证书的来源与入库原因原文档对此有明确交代当 docker 容器启动时后端测试所需的客户端密钥以及客户端和 CA 证书会被拷贝到该目录。虽然唯一事实来源source of truth是 docker 镜像但客户端证书仍然被检入仓库因为存在诸如 SSL 连接工厂测试这类需要有效证书和密钥的测试。也就是说这三份文件是每次运行 run-server.sh 后从容器内同步出来的产物见下文docker cp环节仓库里保留一份是为了让不启动 Docker 也能跑的单元测试如连接工厂构造测试随时能通过clojure.java.io/resource读取到有效材料。启动带 SSL 的 MongoDB 服务器run-server.sh 详解参数与默认值run-server.sh 使用getopts解析两个选项脚本头部默认值为version5、ssl选项取值说明默认值-v4.2/5MongoDB 版本决定使用的镜像 tagmongo-sample-${version}5-splain/tlsSSL 模式。脚本内 usage 提示为-s plain\|tlsREADME 中写作 plain、ssl、tls 三态未指定时ssl为空随后被置为tls注意默认行为不传-s时脚本显式执行ssltls即默认就启动 requireTLS 模式的服务器显式传-s plain时params保持为空数组启动一个无 TLS 参数的 mongod。TLS 模式下的 mongod 启动参数当ssl tls时脚本构造params(--tlsMode requireTLS --tlsCertificateKeyFile /etc/mongo/metamongo.pem --tlsCAFile /etc/mongo/metaca.crt)即服务器端强制 TLSrequireTLS服务端证书/私钥合并文件为容器内的/etc/mongo/metamongo.pem并以/etc/mongo/metaca.crt为 CA。随后执行docker run -d -it --rm -p 27017:27017 --name metamongo \ -e MONGO_INITDB_ROOT_USERNAMEmetabase \ -e MONGO_INITDB_ROOT_PASSWORDmetasample123 \ metabase/qa-databases:mongo-sample-${version} \ mongod --dbpath /data/db2/ ${params[]}要点镜像为metabase/qa-databases:mongo-sample-5或4.2这是 Metabase 团队预制的 QA 样本数据库镜像TLS 所需的服务端证书metamongo.pem、metaca.crt就烘焙在镜像的/etc/mongo/里通过MONGO_INITDB_ROOT_USERNAME/MONGO_INITDB_ROOT_PASSWORD初始化根账号metabase/metasample123——这两个凭据正是后文测试命令里要传入的用户名和密码端口固定映射27017:27017容器名metamongo--rm保证退出即清理。证书同步docker cp 回宿主机目录启动后脚本执行最后一段循环for f in metabase.crt metabase.key metaca.crt; do docker cp metamongo:/etc/mongo/$f . done把容器内/etc/mongo/下的客户端证书、客户端私钥和 CA 证书拷到脚本所在目录覆盖仓库中的检入副本——这就是 README 所说容器启动时证书被拷入本目录的具体实现也解释了为什么事实来源是 docker 镜像。使用 TLS 测试服务器运行驱动测试原文档给出的完整测试命令是MB_MONGO_TEST_USERmetabase MB_MONGO_TEST_PASSWORDmetasample123 MB_TEST_MONGO_REQUIRES_SSL1 DRIVERSmongo clj -X:dev:ci:ee:ee-dev:drivers:drivers-dev:test各部分含义均可在仓库源码中对应上MB_MONGO_TEST_USER/MB_MONGO_TEST_PASSWORD对应 run-server.sh 中初始化的 Mongo 根账号metabase/metasample123。MB_TEST_MONGO_REQUIRES_SSL1开关变量。modules/drivers/mongo/test/metabase/test/data/mongo.clj 中的ssl-required?函数读取该环境变量并判断其值是否属于#true 1为真时才向连接参数合并 SSL 配置。DRIVERSmongo限定只跑 Mongo 驱动的测试。clj -X:dev:ci:ee:ee-dev:drivers:drivers-dev:test以 Clojure CLI 的 JVM profiles 方式启动测试-X:依次激活dev、ci、ee、ee-dev、drivers、drivers-dev、test等 profile从而把modules/drivers/mongo下的驱动代码与测试代码纳入 classpath。当MB_TEST_MONGO_REQUIRES_SSL生效时测试基础设施会把如下参数合并进每条 Mongo 连接详情见 modules/drivers/mongo/test/metabase/test/data/mongo.clj 中的ssl-params与conn-details{:ssl true :ssl-use-client-auth true :client-ssl-key-value (- ssl/mongo/metabase.key io/resource slurp) :client-ssl-cert (- ssl/mongo/metabase.crt io/resource slurp) :ssl-cert (- ssl/mongo/metaca.crt io/resource slurp)}这里通过clojure.java.io/resource按 classpath 路径ssl/mongo/...读取证书——test_resources目录被挂入测试 classpath因此检入到仓库的三份证书文件可以直接以字符串形式喂给驱动。源码级解析证书如何进入 MongoClientSettings理解这套证书真正被消费的位置需要看驱动核心 modules/drivers/mongo/src/metabase/driver/mongo/connection.clj。连接字符串中的 ssl 参数db-details-connection-string在构造 URI 时若连接详情含:ssl为真则在查询串中追加ssltrue该函数还会按use-srv选择mongodb://或mongodbsrv://前缀并合并connectTimeoutMS、serverSelectionTimeoutMS与additional-options。SSL 上下文装配maybe-add-ssl-context-to-builder!真正决定信任谁、出示哪张客户端证书的是私有函数maybe-add-ssl-context-to-builder!(let [server-cert? (not (str/blank? ssl-cert)) client-cert? (and ssl-use-client-auth (not-any? str/blank? [client-ssl-cert client-ssl-key]))] (if (or client-cert? server-cert?) (let [ssl-params (cond- {} server-cert? (assoc :trust-cert ssl-cert) client-cert? (assoc :private-key client-ssl-key :own-cert client-ssl-cert)) ssl-context (driver.u/ssl-context ssl-params)] (.applyToSslSettings builder (reify com.mongodb.Block (apply [_this builder] (.context ^SslSettings$Builder builder ssl-context)))) builder)))从源码结构看其语义为只要ssl-cert即metaca.crtCA 证书非空就把它作为:trust-cert——用于校验 MongoDB 服务端证书只要ssl-use-client-auth为真且client-ssl-cert/client-ssl-key即metabase.crt/metabase.key都非空就同时装配:private-key与:own-cert——即向服务端出示客户端身份构成双向认证mutual TLS两者之一成立时经metabase.driver.util/ssl-context生成SSLContext并applyToSslSettings应用到MongoClientSettings的构建器上否则原样返回 builder。这也解释了三个文件的分工metaca.crt回答我信任哪个 CA 签发的服务端证书metabase.crtmetabase.key回答我是谁客户端证书与私钥。测试侧的佐证modules/drivers/mongo/test/metabase/driver/mongo/connection_test.clj 进一步印证了这些文件的使用方式srv-conn-str-test中的 uses x509 credentials 用例以同样的 classpath 资源ssl/mongo/metabase.key、ssl/mongo/metabase.crt、ssl/mongo/metaca.crt构造带authMechanismMONGODB-X509的连接详情断言生成的MongoCredential机制为MONGODB-X509——该测试无需真实服务器即可运行正对应 README 所说SSL 连接工厂测试需要有效证书和密钥而把证书检入仓库的原因。同文件中的additional-connection-options-test、test-ssh-connection等用例则展示了驱动对额外连接选项、SSH 隧道等相邻能力的测试方式可作延伸阅读。相邻的 SSL 测试资源背景参考test_resources/ssl/ 目录下还有两类与本文主题相邻的资源test_resources/ssl/README.md 描述了另一组用于localhost/127.0.0.1的测试证书ca.pem、server.key、server.pem等使用 cfssl 生成供需要本地服务 TLS 的其他测试使用test_resources/ssl/oracle/ 存放 Oracle 测试用的keystore.p12/truststore.p12。它们与 Mongo 证书分属不同驱动的连接测试路径本文聚焦的是 Mongo 子目录这套。实操小结在 test_resources/ssl/mongo/ 目录执行./run-server.sh默认 Mongo 5 requireTLS或./run-server.sh -s plain -v 4.2切换无 TLS / Mongo 4.2确认容器metamongo在27017端口监听且metabase.crt、metabase.key、metaca.crt已被docker cp刷新到当前目录以MB_MONGO_TEST_USERmetabase MB_MONGO_TEST_PASSWORDmetasample123 MB_TEST_MONGO_REQUIRES_SSL1 DRIVERSmongo环境运行clj -X:dev:ci:ee:ee-dev:drivers:drivers-dev:test即可在强制 TLS 的服务器上完整验证 Mongo 驱动的加密连接与双向认证路径若只想验证连接工厂层面不连真实服务器connection_test.clj 中的 X509 凭据构造用例依赖的正是这套检入的证书文件。【免费下载链接】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),仅供参考
