You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法通过GoLang连接AWS DocumentDB,证书验证报错求助

解决GoLang mongo-driver连接AWS DocumentDB的证书验证问题

问题背景

已通过SSH隧道建立本地端口转发:

ssh -i "key.pem" -L 28100:endpoint.docdb.amazonaws.com:27017 ec2-user@111.111.111.111.region.compute.amazonaws.com

使用如下URI连接时,Mongo Compass可以正常访问AWS DocumentDB,但GoLang的mongo-driver连接失败:

mongodb://user:password@localhost:28100/?ssl=true&ssl_ca_certs=secrets/global-bundle.pem&retryWrites=false&directConnection=true

错误信息

server selection error: server selection timeout, current topology: { Type: Single, Servers: [{ Addr: localhost:28100, Type: Unknown, Last error: tls: failed to verify certificate: x509: certificate is valid for endpoint.docdb.amazonaws.com, not localhost }, ] }

问题原因

DocumentDB返回的TLS证书是签发给自己的官方端点域名(endpoint.docdb.amazonaws.com),但Go客户端连接的是localhost:28100,证书域名与连接地址不匹配,导致TLS验证失败。Mongo Compass内部自动处理了这种域名映射,所以可以正常连接。

解决方案

在Go的TLS配置中指定ServerName为DocumentDB的真实端点域名,让TLS验证时用该域名匹配证书:

import (
    "crypto/tls"
    "crypto/x509"
    "context"
    "io/ioutil"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
    uri := "mongodb://user:password@localhost:28100/?ssl=true&retryWrites=false&directConnection=true"
    connectTimeout := 10
    docdbEndpoint := "endpoint.docdb.amazonaws.com" // 替换为你的DocumentDB实际端点

    // 加载CA证书
    caCertBytes, err := ioutil.ReadFile("secrets/global-bundle.pem")
    if err != nil {
        log.Fatalf("无法读取CA证书: %v", err)
    }
    certPool := x509.NewCertPool()
    if !certPool.AppendCertsFromPEM(caCertBytes) {
        log.Fatal("无法将CA证书添加到证书池")
    }

    // 配置TLS,指定ServerName为DocumentDB端点域名
    tlsCfg := &tls.Config{
        RootCAs:      certPool,
        ServerName:   docdbEndpoint, // 关键配置:让TLS验证使用DocumentDB的域名
        MinVersion:   tls.VersionTLS12, // 可选:强制使用符合AWS要求的TLS版本
    }

    // 创建Mongo客户端并设置TLS配置
    clientOpts := options.Client().ApplyURI(uri).SetTLSConfig(tlsCfg)
    client, err := mongo.Connect(context.TODO(), clientOpts)
    if err != nil {
        log.Fatalf("创建客户端失败: %v", err)
    }
    defer func() {
        if err := client.Disconnect(context.TODO()); err != nil {
            log.Fatal(err)
        }
    }()

    // 验证连接
    ctx, cancel := context.WithTimeout(context.Background(), time.Duration(connectTimeout)*time.Second)
    defer cancel()

    if err := client.Ping(ctx, nil); err != nil {
        log.Fatalf("Ping失败: %v", err)
    }
    log.Println("成功连接到DocumentDB!")
}

关键说明

  • ServerName必须设置为DocumentDB的真实端点域名,确保TLS验证时匹配证书的域名字段
  • 确保CA证书路径正确,且证书文件能正常读取
  • 连接URI保持localhost:28100即可,SSH隧道会负责端口转发

内容的提问来源于stack exchange,提问作者Boon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 16:45:32