Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve TLS documentation for older servers #1657

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,11 @@ Valid Values: true, false
Default: false
```

`allowFallbackToPlaintext=true` acts like a `--ssl-mode=PREFERRED` MySQL client as described in [Command Options for Connecting to the Server](https://dev.mysql.com/doc/refman/5.7/en/connection-options.html#option_general_ssl-mode)
`allowFallbackToPlaintext=true` permits fallback to an unencrypted connection if the server is not configured to use TLS. This behavior is enabled automatically when using `tls=preferred`, but it is also available as a separate parameter to allow plaintext fallback when using a custom TLS configuration.

Plaintext fallback only occurs if the server is not configured to use TLS at all. MySQL 5.7+ and MariaDB 11.4+ ship with TLS support pre-enabled by default using a self-signed server cert, so plaintext fallback typically won't occur with these server versions.

Setting `allowFallbackToPlaintext=true` does **not** allow plaintext fallback in situations where the server has TLS enabled but is incompatible with the client configuration's cipher suites or TLS version. In recent Golang versions, establishing an encrypted connection to older server versions (e.g. MySQL 5.x or MariaDB 10.1) often requires a custom TLS configuration which allows RSA key exchange cipher suites. Very old server versions also require reducing the client's minimum TLS version. See documentation for [`mysql.RegisterTLSConfig`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig) for example code.

##### `allowNativePasswords`

Expand Down Expand Up @@ -431,8 +435,9 @@ Valid Values: true, false, skip-verify, preferred, <name>
Default: false
```

`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side) or use `preferred` to use TLS only when advertised by the server. This is similar to `skip-verify`, but additionally allows a fallback to a connection which is not encrypted. Neither `skip-verify` nor `preferred` add any reliable security. You can use a custom TLS config after registering it with [`mysql.RegisterTLSConfig`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).
`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side) or use `preferred` to use TLS only when advertised by the server. Using `tls=preferred` is equivalent to setting `tls=skip-verify&allowFallbackToPlaintext=true`, which permits fallback to an unencrypted connection if the server is not configured to use TLS at all. Neither `skip-verify` nor `preferred` add any reliable security. You can use a custom TLS config after registering it with [`mysql.RegisterTLSConfig`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).

In recent Golang versions, establishing an encrypted connection to older server versions (MySQL 5.x or MariaDB 10.1) often requires a custom TLS configuration, in order to allow RSA key exchange cipher suites and a lower minimum TLS version. See documentation for [`mysql.RegisterTLSConfig`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig) for example code.

##### `writeTimeout`

Expand Down
24 changes: 24 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,33 @@ var (
// log.Fatal(err)
// }
// clientCert = append(clientCert, certs)
// cipherSuites := []uint16{
// // These 10 are the normal Go 1.22+ defaults
// tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
// tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
// tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
// tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
// tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
// tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
// tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
// tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
// tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
//
// // These 4 use RSA key exchange, no longer included by default in Go 1.22+
// // but often needed to connect to MySQL 5.7, MariaDB 10.1, or anything older
// tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
// tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
// tls.TLS_RSA_WITH_AES_128_CBC_SHA,
// tls.TLS_RSA_WITH_AES_256_CBC_SHA,
// }
// mysql.RegisterTLSConfig("custom", &tls.Config{
// RootCAs: rootCertPool,
// Certificates: clientCert,
//
// // Only include the following two lines when supporting older servers
// CipherSuites: cipherSuites, // in Go 1.22+, allow TLS connection to MySQL 5.x or MariaDB 10.1 or older
// MinVersion: tls.VersionTLS10, // in Go 1.18+, allow TLS connection to MySQL 5.6 or older
// })
// db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom")
func RegisterTLSConfig(key string, config *tls.Config) error {
Expand Down
Loading