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

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

报告相同问题?

悬赏问题

  • ¥50 关于#html5#的问题:H5页面用户手机返回的时候跳转到指定页面例如(语言-javascript)
  • ¥15 无法使用此凭据登录,因为你的域不可用,如何解决?(标签-Windows)
  • ¥15 yolov9的训练时间
  • ¥15 二叉树遍历没有报错但无法正常运行
  • ¥15 在linux系统下vscode运行robocup3d上场球员报错
  • ¥15 Python语言实验
  • ¥15 SAP HANA SQL 增加合计行
  • ¥20 用C#语言解决一个英文打字练习器,有偿
  • ¥15 srs-sip外部服务 webrtc支持H265格式
  • ¥15 在使用abaqus软件中,继承到assembly里的surfaces怎么使用python批量调动