diff --git a/database/mysql/README.md b/database/mysql/README.md index 0cb1299..d0b908d 100644 --- a/database/mysql/README.md +++ b/database/mysql/README.md @@ -10,9 +10,10 @@ | `password` | | The user's password | | `host` | | The host to connect to. | | `port` | | The port to bind to. | -| `x-tls-ca` | | The location of the root certificate file. | -| `x-tls-cert` | | Cert file location. | -| `x-tls-key` | | Key file location. | +| `tls` | | TLS / SSL encrypted connection parameter; see [go-sql-driver](https://github.com/go-sql-driver/mysql#tls). Use any name (e.g. `migrate`) if you want to use a custom TLS config (`x-tls-` queries). | +| `x-tls-ca` | | The location of the CA (certificate authority) file. | +| `x-tls-cert` | | The location of the client certicicate file. Must be used with `x-tls-key`. | +| `x-tls-key` | | The location of the private key file. Must be used with `x-tls-cert`. | | `x-tls-insecure-skip-verify` | | Whether or not to use SSL (true\|false) | ## Use with existing client diff --git a/database/mysql/mysql.go b/database/mysql/mysql.go index 85afbfa..323edae 100644 --- a/database/mysql/mysql.go +++ b/database/mysql/mysql.go @@ -35,6 +35,7 @@ var ( ErrNilConfig = fmt.Errorf("no config") ErrNoDatabaseName = fmt.Errorf("no database name") ErrAppendPEM = fmt.Errorf("failed to append PEM") + ErrTLSCertKeyConfig = fmt.Errorf("To use TLS client authentication, both x-tls-cert and x-tls-key must not be empty") ) type Config struct { @@ -123,15 +124,6 @@ func (m *Mysql) Open(url string) (database.Driver, error) { q.Set("multiStatements", "true") purl.RawQuery = q.Encode() - c, err := urlToMySQLConfig(*migrate.FilterCustomQuery(purl)) - if err != nil { - return nil, err - } - db, err := sql.Open("mysql", c.FormatDSN()) - if err != nil { - return nil, err - } - migrationsTable := purl.Query().Get("x-migrations-table") if len(migrationsTable) == 0 { migrationsTable = DefaultMigrationsTable @@ -151,9 +143,16 @@ func (m *Mysql) Open(url string) (database.Driver, error) { return nil, ErrAppendPEM } - certs, err := tls.LoadX509KeyPair(purl.Query().Get("x-tls-cert"), purl.Query().Get("x-tls-key")) - if err != nil { - return nil, err + clientCert := make([]tls.Certificate, 0, 1) + if ccert, ckey := purl.Query().Get("x-tls-cert"), purl.Query().Get("x-tls-key"); ccert != "" || ckey != "" { + if ccert == "" || ckey == "" { + return nil, ErrTLSCertKeyConfig + } + certs, err := tls.LoadX509KeyPair(ccert, ckey) + if err != nil { + return nil, err + } + clientCert = append(clientCert, certs) } insecureSkipVerify := false @@ -167,12 +166,21 @@ func (m *Mysql) Open(url string) (database.Driver, error) { mysql.RegisterTLSConfig(ctls, &tls.Config{ RootCAs: rootCertPool, - Certificates: []tls.Certificate{certs}, + Certificates: clientCert, InsecureSkipVerify: insecureSkipVerify, }) } } + c, err := urlToMySQLConfig(*migrate.FilterCustomQuery(purl)) + if err != nil { + return nil, err + } + db, err := sql.Open("mysql", c.FormatDSN()) + if err != nil { + return nil, err + } + mx, err := WithInstance(db, &Config{ DatabaseName: purl.Path, MigrationsTable: migrationsTable,