【问题标题】:Connecting golang mgo to mongo via ssl通过 ssl 将 golang mgo 连接到 mongo
【发布时间】:2018-01-02 20:12:18
【问题描述】:

我正在尝试在本地设置 mongo 以测试

中描述的设置

https://www.compose.com/articles/connect-to-mongo-3-2-on-compose-from-golang/ “再难一点”部分

蒙古人

我有一组有效的自签名凭据和 mongo 设置。 我已经包含了密钥,因为这些密钥只会在开发期间用于确保 mongo ssl 代码正常工作。

mongo ssl config

使用这个时,通过

运行
mongod --config config/location

配置是

net:
  port: 27017
  ssl:
    mode: requireSSL
    CAFile: /data/mongo/ca.crt
    PEMKeyFile: /data/mongo/server.pem
    allowInvalidHostnames: true
    allowConnectionsWithoutCertificates: true

然后我可以使用

连接到数据库
mongo --ssl --sslCAFile /data/mongo/ca.crt

Golang

func NewSession(url string, ca string) (m *mgo.Session, err error) {
    roots := x509.NewCertPool()
    roots.AppendCertsFromPEM([]byte(ca))

    tlsConfig := &tls.Config{}
    tlsConfig.RootCAs = roots

    url = strings.TrimSuffix(url, "?ssl=true")
    dialInfo, err := mgo.ParseURL(url)
    dialInfo.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) {
        conn, err := tls.Dial("tcp", addr.String(), tlsConfig)
        return conn, err
    }

    //Here it is the session. Up to you from here ;)
    session, err := mgo.DialWithInfo(dialInfo)
    if err != nil {
        return m, err
    }

    session.SetMode(mgo.Monotonic, true)

    return session, nil
}

结果

golang 的东西尝试连接并达到 10 秒超时。会话顶部的 fmt 显示正确的文件正在将其放入 ca var。

Mongo 日志展示

utumongo_1         | 2017-07-27T08:09:14.964+0000 I NETWORK  [initandlisten] connection accepted from 172.19.0.4:57474 #30 (1 connection now open)
utumongo_1         | 2017-07-27T08:09:14.966+0000 E NETWORK  [conn30] SSL: error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate
utumongo_1         | 2017-07-27T08:09:14.967+0000 I NETWORK  [conn30] end connection 172.19.0.4:57474 (0 connections now open)

编辑 更新了 mongo 配置

【问题讨论】:

    标签: mongodb ssl go tls1.2 compose-db


    【解决方案1】:

    您将什么作为ca 参数传递给NewSession?这需要是 PEM 编码的 CA 证书字节,而不是 CA 证书的文件名。 AppendCertsFromPEM 将返回 true 如果它设法将任何证书添加到池中。

    文章已经展示了执行此操作的代码:

    if ca, err := ioutil.ReadFile("myPEM"); err == nil { 
        roots.AppendCertsFromPEM(ca)
    }
    

    SSL 错误意味着客户端拒绝服务器证书。我怀疑这是因为您的自签名证书未正确添加到池中。

    编辑

    我使用您的配置在本地运行了一份 mongo。使用 docker,这是:

    docker run --rm -ti -v $(pwd):/data/mongo --net=host mongo -f /data/mongo/mongo.yaml
    

    从提取配置的位置运行时

    根据我在下面的评论,在 Go 中使用 NewSession 函数表明 tls.Dial 由于缺少任何主题访问名称 (SAN) 扩展而返回错误。

    您将需要更正您的服务器证书以获取所需的适当主机名(或 IP 地址)SAN 条目。

    您可以调试此错误以及发生的任何其他 TLS 连接错误:

    dialInfo.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) {
        conn, err := tls.Dial("tcp", addr.String(), tlsConfig)
        if err != nil {
            fmt.Println(err)
        }
        return conn, err
    }
    

    【讨论】:

    • 我特别传递了一些格式 -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----
    • 避免传递文件名,而只是一个字符串,它是通过 env 等设置的 ca
    • 它似乎至少为函数获取了正确的值。
    • 您是否确认AppendCertsFromPEM 正在返回true。此外,重新阅读您的帖子,您的 mongo 连接正在使用客户端证书。您是否只想接受经过身份验证的客户端?如果有,需要将客户端证书添加到tlsConfig
    • AppendCertsFromPEM 返回 true,只是稍微更新了 mongo 配置,删除了客户端证书验证。它最初试图验证客户端证书,但后来删除了它(据我所知,无法在 compose 中进行配置)。
    猜你喜欢
    • 2019-07-31
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多