dongrang2186 2017-07-27 08:16
浏览 131
已采纳

通过SSL将Golang mgo连接到Mongo

I'm trying to setup mongo locally to test the setup described in

https://www.compose.com/articles/connect-to-mongo-3-2-on-compose-from-golang/ "A Little Harder" section

Mongo

I have a working set of self signed credentials, and mongo setup. I've included keys, as those will only be used during dev to make sure mongo ssl code is working.

mongo ssl config

When using this, running via

mongod --config config/location

The config is

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

I can then connect to the db with

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
}

Result

The golang stuff tries to connect and hits the 10s timeout. A fmt at the top of session shows the correct file is making it into the ca var.

Mongo logs show

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)

Edit Updated mongo config

  • 写回答

1条回答 默认 最新

  • dongzhi7763 2017-07-27 09:00
    关注

    What are you passing into NewSession as the ca parameter? This needs to be the PEM encoded CA certificate bytes, not the file name of the CA certificate. AppendCertsFromPEM will return true if it managed to add any certificates to the pool.

    The article already shows code to do this:

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

    The SSL error means that the client is rejecting the server certificate. I suspect it is because your self-signed certificate was not added to the pool correctly.

    EDIT

    I ran a copy of mongo locally with your config. Using docker, this was:

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

    When ran from where your configuration was extracted

    Using your NewSession func inside Go showed that the tls.Dial was returning an error due to the lack of any Subject Access Name (SAN) extensions as per my comment below.

    You will need to correct your server certificate to have the appropriate host name (or IP address) SAN entries required.

    You can debug this and any other TLS connection errors that occur with:

    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
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计