Add client key and cert to rethink client tls config

Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
This commit is contained in:
Riyaz Faizullabhoy 2016-05-04 16:27:26 -07:00
parent 134bdbcb90
commit 29e65f6d9a
9 changed files with 62 additions and 11 deletions

View File

@ -89,7 +89,12 @@ func getStore(configuration *viper.Viper, hRegister healthRegister) (
if err != nil { if err != nil {
return nil, err return nil, err
} }
sess, err = rethinkdb.Connection(storeConfig.CA, storeConfig.Source) tlsOpts := tlsconfig.Options{
CAFile: storeConfig.CA,
CertFile: storeConfig.Cert,
KeyFile: storeConfig.Key,
}
sess, err = rethinkdb.Connection(tlsOpts, storeConfig.Source)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error starting %s driver: %s", backend, err.Error()) return nil, fmt.Errorf("Error starting %s driver: %s", backend, err.Error())
} }

View File

@ -343,6 +343,8 @@ func TestGetStoreRethinkDBStoreConnectionFails(t *testing.T) {
"backend": "%s", "backend": "%s",
"db_url": "host:port", "db_url": "host:port",
"tls_ca_file": "/tls/ca.pem", "tls_ca_file": "/tls/ca.pem",
"client_cert_file": "/tls/cert.pem",
"client_key_file": "/tls/key.pem",
"database": "rethinkdbtest" "database": "rethinkdbtest"
} }
}`, }`,

View File

@ -16,6 +16,7 @@ import (
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/dancannon/gorethink" "github.com/dancannon/gorethink"
"github.com/docker/distribution/health" "github.com/docker/distribution/health"
"github.com/docker/go-connections/tlsconfig"
"github.com/docker/notary" "github.com/docker/notary"
"github.com/docker/notary/cryptoservice" "github.com/docker/notary/cryptoservice"
"github.com/docker/notary/passphrase" "github.com/docker/notary/passphrase"
@ -116,7 +117,12 @@ func setUpCryptoservices(configuration *viper.Viper, allowedBackends []string) (
if err != nil { if err != nil {
return nil, err return nil, err
} }
sess, err = rethinkdb.Connection(storeConfig.CA, storeConfig.Source) tlsOpts := tlsconfig.Options{
CAFile: storeConfig.CA,
CertFile: storeConfig.Cert,
KeyFile: storeConfig.Key,
}
sess, err = rethinkdb.Connection(tlsOpts, storeConfig.Source)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -121,6 +121,8 @@ func TestSetupCryptoServicesRethinkDBStoreNoDefaultAlias(t *testing.T) {
"backend": "%s", "backend": "%s",
"db_url": "host:port", "db_url": "host:port",
"tls_ca_file": "/tls/ca.pem", "tls_ca_file": "/tls/ca.pem",
"client_cert_file": "/tls/cert.pem",
"client_key_file": "/tls/key.pem",
"database": "rethinkdbtest" "database": "rethinkdbtest"
} }
}`, }`,
@ -137,7 +139,9 @@ func TestSetupCryptoServicesRethinkDBStoreConnectionFails(t *testing.T) {
`{"storage": { `{"storage": {
"backend": "%s", "backend": "%s",
"db_url": "host:port", "db_url": "host:port",
"tls_ca_file": "../../fixtures/root-ca.crt", "tls_ca_file": "../../fixtures/rethinkdb/ca.pem",
"client_cert_file": "../../fixtures/rethinkdb/cert.pem",
"client_key_file": "../../fixtures/rethinkdb/key.pem",
"database": "rethinkdbtest" "database": "rethinkdbtest"
}, },
"default_alias": "timestamp" "default_alias": "timestamp"

View File

@ -20,6 +20,8 @@
"backend": "rethinkdb", "backend": "rethinkdb",
"db_url": "rdb-proxy.rdb", "db_url": "rdb-proxy.rdb",
"database": "notaryserver", "database": "notaryserver",
"tls_ca_file": "./rethinkdb/ca.pem" "tls_ca_file": "./rethinkdb/ca.pem",
"client_key_file": "./rethinkdb/key.pem",
"client_cert_file": "./rethinkdb/cert.pem"
} }
} }

View File

@ -13,6 +13,8 @@
"backend": "rethinkdb", "backend": "rethinkdb",
"db_url": "rdb-proxy.rdb", "db_url": "rdb-proxy.rdb",
"database": "notarysigner", "database": "notarysigner",
"tls_ca_file": "./rethinkdb/ca.pem" "tls_ca_file": "./rethinkdb/ca.pem",
"client_key_file": "./rethinkdb/key.pem",
"client_cert_file": "./rethinkdb/cert.pem"
} }
} }

View File

@ -19,10 +19,7 @@ type Timing struct {
// Connection sets up a RethinkDB connection to the host (`host:port` format) // Connection sets up a RethinkDB connection to the host (`host:port` format)
// using the CA .pem file provided at path `caFile` // using the CA .pem file provided at path `caFile`
func Connection(caFile, host string) (*gorethink.Session, error) { func Connection(tlsOpts tlsconfig.Options, host string) (*gorethink.Session, error) {
tlsOpts := tlsconfig.Options{
CAFile: caFile,
}
t, err := tlsconfig.Client(tlsOpts) t, err := tlsconfig.Client(tlsOpts)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -27,7 +27,9 @@ type Storage struct {
type RethinkDBStorage struct { type RethinkDBStorage struct {
Storage Storage
CA string CA string
Cert string
DBName string DBName string
Key string
} }
// GetPathRelativeToConfig gets a configuration key which is a path, and if // GetPathRelativeToConfig gets a configuration key which is a path, and if
@ -117,6 +119,8 @@ func ParseRethinkDBStorage(configuration *viper.Viper) (*RethinkDBStorage, error
Source: configuration.GetString("storage.db_url"), Source: configuration.GetString("storage.db_url"),
}, },
CA: GetPathRelativeToConfig(configuration, "storage.tls_ca_file"), CA: GetPathRelativeToConfig(configuration, "storage.tls_ca_file"),
Cert: GetPathRelativeToConfig(configuration, "storage.client_cert_file"),
Key: GetPathRelativeToConfig(configuration, "storage.client_key_file"),
DBName: configuration.GetString("storage.database"), DBName: configuration.GetString("storage.database"),
} }
@ -136,6 +140,11 @@ func ParseRethinkDBStorage(configuration *viper.Viper) (*RethinkDBStorage, error
"cowardly refusal to connect to %s without a CA cert", "cowardly refusal to connect to %s without a CA cert",
store.Backend, store.Backend,
) )
case store.Cert == "" || store.Key == "":
return nil, fmt.Errorf(
"cowardly refusal to connect to %s without a client cert and key",
store.Backend,
)
case store.DBName == "": case store.DBName == "":
return nil, fmt.Errorf( return nil, fmt.Errorf(
"%s requires a specific database to connect to", "%s requires a specific database to connect to",

View File

@ -215,6 +215,8 @@ func TestParseRethinkStorageDBStoreInvalidBackend(t *testing.T) {
"backend": "mysql", "backend": "mysql",
"db_url": "username:password@tcp(hostname:1234)/dbname", "db_url": "username:password@tcp(hostname:1234)/dbname",
"tls_ca_file": "/tls/ca.pem", "tls_ca_file": "/tls/ca.pem",
"client_cert_file": "/tls/cert.pem",
"client_key_file": "/tls/key.pem",
"database": "rethinkdbtest" "database": "rethinkdbtest"
} }
}`) }`)
@ -230,6 +232,8 @@ func TestParseRethinkStorageDBStoreEmptyDBUrl(t *testing.T) {
"storage": { "storage": {
"backend": "rethinkdb", "backend": "rethinkdb",
"tls_ca_file": "/tls/ca.pem", "tls_ca_file": "/tls/ca.pem",
"client_cert_file": "/tls/cert.pem",
"client_key_file": "/tls/key.pem",
"database": "rethinkdbtest" "database": "rethinkdbtest"
} }
}`) }`)
@ -245,7 +249,9 @@ func TestParseRethinkStorageDBStoreEmptyDBName(t *testing.T) {
"storage": { "storage": {
"backend": "rethinkdb", "backend": "rethinkdb",
"db_url": "username:password@tcp(hostname:1234)/dbname", "db_url": "username:password@tcp(hostname:1234)/dbname",
"tls_ca_file": "/tls/ca.pem" "tls_ca_file": "/tls/ca.pem",
"client_cert_file": "/tls/cert.pem",
"client_key_file": "/tls/key.pem"
} }
}`) }`)
@ -260,7 +266,9 @@ func TestParseRethinkStorageDBStoreEmptyCA(t *testing.T) {
"storage": { "storage": {
"backend": "rethinkdb", "backend": "rethinkdb",
"db_url": "username:password@tcp(hostname:1234)/dbname", "db_url": "username:password@tcp(hostname:1234)/dbname",
"database": "rethinkdbtest" "database": "rethinkdbtest",
"client_cert_file": "/tls/cert.pem",
"client_key_file": "/tls/key.pem"
} }
}`) }`)
@ -269,6 +277,22 @@ func TestParseRethinkStorageDBStoreEmptyCA(t *testing.T) {
require.Contains(t, err.Error(), "cowardly refusal to connect to rethinkdb without a CA cert") require.Contains(t, err.Error(), "cowardly refusal to connect to rethinkdb without a CA cert")
} }
// ParseRethinkDBStorage will require a client cert and key to connect to rethink databases
func TestParseRethinkStorageDBStoreEmptyCertAndKey(t *testing.T) {
config := configure(`{
"storage": {
"backend": "rethinkdb",
"db_url": "username:password@tcp(hostname:1234)/dbname",
"database": "rethinkdbtest",
"tls_ca_file": "/tls/ca.pem"
}
}`)
_, err := ParseRethinkDBStorage(config)
require.Error(t, err)
require.Contains(t, err.Error(), "cowardly refusal to connect to rethinkdb without a client cert")
}
func TestParseSQLStorageWithEnvironmentVariables(t *testing.T) { func TestParseSQLStorageWithEnvironmentVariables(t *testing.T) {
config := configure(`{ config := configure(`{
"storage": { "storage": {