facebookarchive / rocks-strata

Other
133 stars 24 forks source link

rocks-strata doesn't seem to work with TLS/SSL Mongo #14

Open cube-drone opened 8 years ago

cube-drone commented 8 years ago

My mongo server is configured using a LetsEncrypt SSL cert.

When I run the sample

RSTRATA_PATH=/go/bin/strata
LOGFILE="rocks-strata.log"
source /home/classam/creds

# Uses start-stop-daemon because, for a given replica ID, only one write-capable operation should run at once.
/sbin/start-stop-daemon --start --exec $RSTRATA_PATH -- -b=$BUCKET -p=$BUCKET_PREFIX backup -r=$REPLICA_ID --username $MONGO_USER --password $MONGO_PASS >> $LOGFILE 2>&1
/sbin/start-stop-daemon --start --exec $RSTRATA_PATH -- -b=$BUCKET -p=$BUCKET_PREFIX delete -r=$REPLICA_ID -a=$DELETE_OLDER_THAN --username $MONGO_USER --password $MONGO_PASS >> $LOGFILE 2>&1
/sbin/start-stop-daemon --start --exec $RSTRATA_PATH -- -b=$BUCKET -p=$BUCKET_PREFIX gc -r=$REPLICA_ID --username $MONGO_USER --password $MONGO_PASS >> $LOGFILE 2>&1

Rocks-strata tries to connect to the local mongo instance without ssl, and fails to connect.

igorcanadi commented 8 years ago

Yeah, you're right @classam . We never implemented ssl support.

This is where we connect to mongo: https://github.com/facebookgo/rocks-strata/blob/master/strata/mongo/lreplica/replica.go#L36. Looks like the mongo driver supports connection over ssl (https://github.com/go-mgo/mgo/issues/84#issuecomment-89156585), so it shouldn't be hard to implement if you have some time on your hand :)

derfshaya commented 7 years ago

Hi @igorcanadi, I've attempted adding SSL support by modifying the localSessionGetter.get method in such a manner, as inferred from the mgo ssl discussion link you've provided above.

// port could be the empty string
func (l *localSessionGetter) get(port, username, password string, ssl bool) (*mgo.Session, error) {
    addr := "localhost"
    if port != "" {
        addr += ":" + port
    }
    var dialServerFunc func(addr *mgo.ServerAddr) (net.Conn, error)
    if ssl {
        dialServerFunc = func(addr *mgo.ServerAddr) (net.Conn, error) {
            return tls.Dial("tcp", addr.String(), &tls.Config{})
        }
    } else {
        dialServerFunc = nil
    }
    return mgo.DialWithInfo(&mgo.DialInfo{
        Direct:   true,
        Addrs:    []string{addr},
        Timeout:  5 * time.Minute,
        Username: username,
        Password: password,
        DialServer: dialServerFunc})
}

Unfortunately, it still did not work, returning no reachable servers. I'm wondering if I've made a blunder that's immediately obvious from the snippet above. If not, I wish to find out with the help of contributors to rocks-strata, as SSL connection is crucial in the Parse migration process, and I am not aware of any workarounds, yet.

Here is my fork of rocks-strata, with my attempt: derfshaya/rocks-strata

Thank you very much, in advance!

igorcanadi commented 7 years ago

I'm afraid that I'm not familiar with mongo's go driver. :( Would it make sense to post this question to https://github.com/go-mgo/mgo/issues?

derfshaya commented 7 years ago

It would indeed make sense. Thank you for your kind help in redirection!

On Sat, 30 Jul 2016 1:08 am Igor Canadi notifications@github.com wrote:

I'm afraid that I'm not familiar with mongo's go driver. :( Would it make sense to post this question to https://github.com/go-mgo/mgo/issues?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/facebookgo/rocks-strata/issues/14#issuecomment-236237103, or mute the thread https://github.com/notifications/unsubscribe-auth/AEem7hqopcJv0p4T7buQVcJwwJiBLEo8ks5qajOHgaJpZM4IMV0M .

tredman commented 7 years ago

My experience with the mgo driver is that it hides a lot of simple errors (bad authentication, for instance) behind the very vague message 'no reachable servers', so it's a good idea to check all basic assumptions you're making (address, port, authentication, etc).

My hunch is that this is due to your TLS config. Most TLS libs are defensive about certificate chain and hostname verification. Unless you've generated a trusted certificate that matches your DB host name, it's likely to fail. You can check this quickly by initializing the tls config with InsecureSkipVerify = true. So:

return tls.Dial("tcp", addr.String(), &tls.Config{InsecureSkipVerify: true})

More info here: https://golang.org/pkg/crypto/tls/#Config

I think it may be more appropriate here to create an alternative to localSessionGetter that allows you to supply more information, such as hostname and optional certificate chain.

thapakazi commented 6 years ago

And a year or more later, on this lands of issues... any progress/ plans on this one... @derfshaya /cc @igorcanadi this ssl sounds like a fundamental one for awesome tools like this, isn't it ?