globalsign / mgo

The MongoDB driver for Go
Other
1.97k stars 230 forks source link

SSL Behind NGINX Stream proxy #170

Closed swrap closed 6 years ago

swrap commented 6 years ago

I have configured Nginx SSL Stream to act as a proxy in front of my Mongo DB.

I have tested it via the Mongo CLI -ssl option and it work flawlessly. However, when I try it with this library I have a problem once I query the mongo database. I receive the following error from a query Could not verify the message. Message has been tempered with!. I have scoured the internet trying to find answers, but to no avail :( It is odd because 'tempered' is misspelled, I looked in my own code thinking it was me, but it is not.

For now I can go back to manually creating the certs and have mongo authenticate them, but I would rather just used an automated cert authority and keep mongo behind nginx. Any help with this problem would be awesome!

If you need help building the Nginx library please reach out, you need to include the stream modules because it is not included in the regular build.

MGO Library version:

commit efe0945164a7e582241f37ae8983c075f8f2e870 (HEAD -> master, tag: r2018.04.23, origin/master, origin/HEAD)
Merge: f76e4f9 7a53c79
Author: Dom <dom@itsallbroken.com>
Date:   Tue Apr 24 10:13:48 2018 +0100

    Merge pull request #152 from globalsign/release/r2018.04.23

    Release/r2018.04.23

Go Version go version go1.10.2 linux/amd64

Mongo Go Setup Session:

dialInfo := &mgo.DialInfo{
    Addrs:    []string{c.uri},
    Database: ADMIN_DB,
    Username: c.dbusername,
    Password: c.dbpass,
    DialServer: func(addr *mgo.ServerAddr) (net.Conn, error) {
        return tls.Dial("tcp", addr.String(), &tls.Config{})
    },
    Timeout: time.Second * 10,
}
session, err = mgo.DialWithInfo(dialInfo)
if err != nil {
    return nil, fmt.Errorf("Error making TLS connection to server[%s]: %s", c.uri, err.Error())
}

Query:

err = c.FindId(id).One(&result)
if err == mgo.ErrNotFound {
    return nil, nil
}
if err != nil {
    return nil, fmt.Errorf("Error %s", err.Error()) #error occurs here
}

NGINX Config:

stream {
    upstream stream_mongo_backend {
      server 127.0.0.1:27017;
    }

    server {
        listen 4000 ssl;
        proxy_connect_timeout 10s;
        proxy_timeout 15s;
        proxy_pass    stream_mongo_backend;
        ssl_certificate _cert_;
        ssl_certificate_key _cert_;
        ssl_handshake_timeout 10s;
    }
}
domodwyer commented 6 years ago

Hi @swrap

This is odd - the misspelt message only adds to the weirdness!

I had a quick google and found the exact message (misspelling and all) in a Go package called cryptoengine wrapping the NaCL library - is this something you use? It's not used in mgo and I imagine the nginx module is C, so it's unlikely it's originated from there either.

Specifically mgo uses the Golang TLS implementation and doesn't do anything particularly special - we use TLS extensively (obviously!) and have no issues.

Dom

domodwyer commented 6 years ago

We don't proxy connections to mongo though - this might not work very well with clustering because mgo queries the connected node for a list of other nodes to talk to: say you connect to r1 and it says "there's r2 at 10.0.0.1 and r3 at 10.0.0.2 too" mgo will try and connect to them directly.

Does this work without the TLS?

Dom

swrap commented 6 years ago

@domodwyer Thank you for the help! What we found out was that it ended being a custom marshaller we used when grabbing some data from the mongo instance. Thank you for pointing at the repository, it was caused because we had invalid keys, you were a real help!