多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

FerretDB v1.24 TLS 连接配置实战:使用双向 TLS 加密 MongoDB 协议通信

FerretDB v1.24 TLS 连接配置实战:使用双向 TLS 加密 MongoDB 协议通信 后端数据库文档数据库【免费下载链接】FerretDBA truly Open Source MongoDB alternative项目地址https://gitcode.com/gh_mirrors/fe/FerretDB点击查看免费下载导读FerretDB 作为一款开源 MongoDB 替代方案默认监听 TCP 端口时客户端与服务器之间的 MongoDB wire protocol 通信是明文传输的。本文基于 FerretDB v1.24 版本文档与源码系统讲解如何通过--listen-tls系列启动参数在 FerretDB 与客户端之间启用 TLS 加密涵盖服务器证书/私钥/根 CA 的配置、客户端mongosh连接 URI 的写法以及本地二进制部署与 Docker Compose 部署两种实战场景并深入到internal/clientconn监听器源码剖析 TLS 配置的底层实现帮助读者在用户名密码明文传输的场景下快速落地加密连接。一、TLS 加密的整体工作方式FerretDB 通过启动时的一组--listen-tls相关标志或对应的FERRETDB_*环境变量来开启 TLS 监听器。其核心思路是在原有 TCP 监听器之外额外启动一个独立的 TLS 监听器二者互不干扰客户端只需在 MongoDB URI 中携带tlstrue参数即可接入加密通道。从源码结构看监听器的设计完全印证了这一思路。internal/clientconn/listener.go 中Listener结构体同时持有三种监听器type Listener struct { *ListenerOpts tcpListener net.Listener // 明文 TCP 监听 unixListener net.Listener // Unix socket 监听 tlsListener net.Listener // TLS 监听 } type ListenerOpts struct { TCP string // empty value disables TCP listener Unix string // empty value disables Unix listener TLS string // empty value disables TLS listener TLSCertFile string TLSKeyFile string TLSCAFile string // ... }关键点在于TLS字段为空字符串时TLS 监听器完全禁用一旦配置了地址Listen() 会先校验证书文件再调用tls.Listen(tcp, l.TLS, config)启动加密监听。这意味着明文监听与加密监听可以同时存在例如默认的127.0.0.1:27017明文端口与:27018的 TLS 端口可以并行服务。二、四个核心启动参数详解根据 v1.24 配置文档 及 cmd/ferretdb/main.go 中listen-前缀的 CLI 结构体定义启用 TLS 共涉及四个参数命令行参数环境变量作用说明--listen-tlsFERRETDB_LISTEN_TLS指定 TLS 监听器使用的 TCP 主机名和端口如:27018。为空时 TLS 监听器禁用--listen-tls-cert-fileFERRETDB_LISTEN_TLS_CERT_FILE指定 PEM 编码的 TLS 服务器证书文件用于向客户端表明服务器身份--listen-tls-key-fileFERRETDB_LISTEN_TLS_KEY_FILE指定 TLS 私钥文件用于解密通信数据--listen-tls-ca-fileFERRETDB_LISTEN_TLS_CA_FILE指定根 CA 证书文件用于验证客户端证书启用双向 TLS各参数的默认值均为空字符串。其中--listen-tls支持 Go 标准的host:port形式端口可省略主机名如:27018表示监听所有网卡的 27018 端口。2.1 底层实现证书加载与客户端验证逻辑在 tlsConfig() 函数中可以看到完整的证书处理流程文件存在性校验依次对certFile、keyFile调用os.Stat任一文件不存在即返回错误如TLS certificate file: ...密钥对加载通过tls.LoadX509KeyPair(certFile, keyFile)将证书与私钥绑定加载可选客户端证书验证当caFile非空时读取并解析 PEM 格式的根 CA写入x509.NewCertPool()然后设置config.ClientAuth tls.RequireAndVerifyClientCert与config.ClientCAs ca。第 3 步是理解双向 TLS 的关键只要配置了--listen-tls-ca-fileFerretDB 就会强制要求客户端也必须出示由该根 CA 签发的客户端证书RequireAndVerifyClientCert否则握手失败。如果只希望服务器单向加密、不校验客户端身份则不传--listen-tls-ca-file即可。三、客户端连接方式服务器端开启 TLS 后客户端需要在 MongoDB URI 中使用tls查询参数。FerretDB 遵循标准 MongoDB 驱动约定因此无需特殊定制tlstrue启用 TLS 加密连接tlsCAFile当服务器证书并非由系统根证书颁发机构CA签发时指定自定义根 CA 文件路径用于校验服务器证书tlsCertificateKeyFile携带客户端证书与私钥用于双向 TLS 场景由服务端--listen-tls-ca-file触发。官方文档给出的最简示例为mongodb://ferretdb:27018/?tlstruetlsCAFilecompanyRootCA.pem若服务器证书由受信任的公共 CA 签发tlsCAFile可以省略否则必须显式指定否则客户端将因无法验证服务器证书而拒绝连接。具体参数名以所用客户端或驱动文档为准。四、PostgreSQL 后端 TLS 的完整证书布局文档特别强调当用户名和密码以明文形式在网络上传输时强烈建议启用 TLS。在 FerretDB 的典型架构FerretDB 前端 PostgreSQL 后端中TLS 保护的是 FerretDB 与 MongoDB 客户端之间的信道。以下示例展示了双端证书的标准目录布局服务器端FerretDB 使用服务器证书、私钥与根 CAserver-certs/ ├── rootCA-cert.pem ├── server-cert.pem └── server-key.pem客户端使用客户端证书与同一根 CAclient-certs/ ├── client.pem └── rootCA-cert.pem其中client.pem应包含客户端证书与私钥的合并内容常见于 MongoDB 驱动要求的 PKCS#12 或合并 PEM 格式。4.1 使用ferretdb二进制包部署本地或服务器二进制部署时直接通过命令行参数传入证书路径。以下命令连接本机 PostgreSQL 实例并使用server-certs目录下的证书开启:27018的 TLS 监听ferretdb \ --postgresql-urlpostgres://localhost:5432/ferretdb \ --listen-tls:27018 \ --listen-tls-cert-file./server-certs/server-cert.pem \ --listen-tls-key-file./server-certs/server-key.pem \ --listen-tls-ca-file./server-certs/rootCA-cert.pem注意示例中--listen-tls-ca-file已指定意味着这是双向 TLS模式客户端必须携带证书。随后使用mongosh以用户user2身份连接连接串中通过tlsCertificateKeyFile提供客户端证书、通过tlsCaFile提供根 CAmongosh mongodb://user2:pass2127.0.0.1:27018/ferretdb?authMechanismPLAINtlstruetlsCertificateKeyFile./client-certs/client.pemtlsCaFile./client-certs/rootCA-cert.pem这里有几个实践要点值得展开authMechanismPLAIN使用 PLAIN 认证机制用户名密码由 FerretDB 校验因此加密信道尤为重要tlstrue显式开启 TLS与--listen-tls端口配对tlsCertificateKeyFile指向client-certs/client.pem含客户端证书私钥tlsCaFile指向根 CA因为服务端启用了RequireAndVerifyClientCert缺少tlsCertificateKeyFile的连接会直接握手失败。4.2 使用 Docker 部署Docker 场景下通过环境变量注入 TLS 配置。官方 docker-compose.yml 给出了完整参考核心做法是将 Docker 宿主机的./server-certs目录挂载到容器的/etc/certsservices: postgres: image: postgres restart: on-failure environment: - POSTGRES_USERusername - POSTGRES_PASSWORDpassword - POSTGRES_DBferretdb volumes: - ./data:/var/lib/postgresql/data ferretdb: image: ghcr.io/ferretdb/ferretdb:1 restart: on-failure ports: - 27018:27018 environment: - FERRETDB_POSTGRESQL_URLpostgres://postgres:5432/ferretdb - FERRETDB_LISTEN_TLS:27018 - FERRETDB_LISTEN_TLS_CERT_FILE/etc/certs/server-cert.pem - FERRETDB_LISTEN_TLS_KEY_FILE/etc/certs/server-key.pem - FERRETDB_LISTEN_TLS_CA_FILE/etc/certs/rootCA-cert.pem volumes: - ./server-certs:/etc/certs networks: default: name: ferretdb启动服务docker compose up可以看到环境变量形式与命令行参数一一对应--listen-tls→FERRETDB_LISTEN_TLS依此类推容器内证书路径统一指向挂载点/etc/certs。这正是 Go CLI 解析器cmd/ferretdb/main.go 中prefix:listen-的嵌入结构自动生成的映射关系因此两种传参方式完全等价。客户端侧同样通过 Docker 运行mongosh并将./client-certs挂载到容器的/clientsdocker run --rm -it \ --networkferretdb \ --volume ./client-certs:/clients \ --entrypointmongosh \ mongo mongodb://user2:pass2host.docker.internal:27018/ferretdb?authMechanismPLAINtlstruetlsCertificateKeyFile/clients/client.pemtlsCaFile/clients/rootCA-cert.pem要点说明--networkferretdb加入与ferretdb服务相同的 compose 网络使客户端容器可通过服务名或host.docker.internal访问宿主机映射端口--volume ./client-certs:/clients把宿主机client-certs目录挂载为容器内/clients连接串中的证书路径使用容器内路径/clients/client.pem而非宿主机路径端口27018与 compose 中ports映射及FERRETDB_LISTEN_TLS:27018保持一致。五、TLS 监听器的运行机制与故障排查要点从 Run() 的实现可以看到FerretDB 为 TCP、Unix、TLS 三种监听器各启动一个独立的acceptLoopgoroutine统一受 context 生命周期管理。TLS 监听器与明文监听器完全并行因此启动时日志会分别打印Listening on TCP ...、Listening on TLS ...可用于确认 TLS 监听是否生效若--listen-tls为空则不会打印 TLS 监听日志也不存在加密端口证书文件路径错误时启动阶段即会失败并报错TLS certificate file:/TLS key file:/TLS file pair:/TLS CA file:错误信息直接指向问题文件便于快速定位CA 文件内容无法按 PEM 解析时会报TLS CA file: failed to parse。常见的排查清单确认--listen-tls端口与客户端 URI 端口一致确认服务器证书与私钥匹配tls.LoadX509KeyPair会校验二者配对若服务端配置了--listen-tls-ca-file客户端必须提供tlsCertificateKeyFile若服务器证书非公共 CA 签发客户端必须指定tlsCAFileDocker 场景下核对容器内证书挂载路径与FERRETDB_LISTEN_TLS_*环境变量指向是否一致。六、总结FerretDB 的 TLS 支持设计简洁而完整通过四个--listen-tls系列参数或FERRETDB_LISTEN_TLS_*环境变量即可开启独立的加密监听器提供--listen-tls-ca-file可一键切换为强制校验客户端证书的双向 TLS 模式客户端沿用标准 MongoDB URI 的tlstrue、tlsCAFile、tlsCertificateKeyFile参数接入与现有驱动生态完全兼容。无论采用二进制部署还是 Docker Compose只需准备好服务器证书、私钥与根 CA 三件套即可在明文传输用户名密码的场景下获得完整的传输层加密保护。更深入的理解可继续阅读源码 internal/clientconn/listener.go 与完整的 v1.24 配置参数文档。赞分享后端数据库文档数据库【免费下载链接】FerretDBA truly Open Source MongoDB alternative项目地址https://gitcode.com/gh_mirrors/fe/FerretDB点击查看免费下载相关推荐Envoy direct_response 网络过滤器对新连接快速应答与拦截流量遥测Envoy direct_response 网络过滤器对新连接快速应答与拦截流量遥测 导读 direct_response 是 Envoy 中最简洁的 L后端数据库文档数据库grpc-java TLS 加密通信实战基于 example-tls 实现单向 TLS 与双向 Mutual TLSgrpc java TLS 加密通信实战基于 example tls 实现单向 TLS 与双向 Mutual TLS gRPC 默认基于 HTTP/2 明文传后端RPC框架FerretDB TLS 连接配置指南使用证书加密客户端与服务器之间的通信FerretDB TLS 连接配置指南使用证书加密客户端与服务器之间的通信 本篇指南讲解如何在 FerretDB 中启用 TLS传输层安全加密以保护 M后端数据库文档数据库上一篇如何快速掌握OpenPose首个实时多人全身关键点检测系统的终极指南下一篇WebRTC媒体协商终极指南从Offer到Answer的完整实时通信流程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表