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.
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
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
}