Security in MySQL  /  Using Encrypted Connections  /  Encrypted Connection Protocols and Ciphers

5.2 Encrypted Connection Protocols and Ciphers

To determine which encryption protocol and cipher are in use for an encrypted connection, check the session values of the Ssl_version and Ssl_cipher status variables:

mysql> SELECT * FROM performance_schema.session_status
       WHERE VARIABLE_NAME IN ('Ssl_version','Ssl_cipher');
+---------------+---------------------------+
| VARIABLE_NAME | VARIABLE_VALUE            |
+---------------+---------------------------+
| Ssl_cipher    | DHE-RSA-AES128-GCM-SHA256 |
| Ssl_version   | TLSv1.2                   |
+---------------+---------------------------+

If the connection is not encrypted, both variables have an empty value.

Supported Connection TLS Protocols

MySQL supports encrypted connections using the TLSv1, TLSv1.1, and TLSv1.2 protocols, listed in order from less secure to more secure. The set of protocols actually permitted for connections is subject to multiple factors:

  • MySQL configuration. Permitted TLS protocols can be configured on both the server side and client side to include only a subset of the supported TLS protocols. The configuration on both sides must include at least one protocol in common or connection attempts cannot negotiate a protocol to use. For details, see Connection TLS Protocol Configuration.

  • System-wide host configuration. The host system may permit only certain TLS protocols, which means that MySQL connections cannot use nonpermitted protocols even if MySQL itself permits them:

    • Suppose that MySQL is configured to permit TLSv1, TLSv1.1, and TLSv1.2, but your system configuration permits only connections that use TLSv1.2 or higher. In this case, you cannot establish MySQL connections that use TLSv1 or TLSv1.1, even though MySQL is configured to permit them, because the operating system does not permit them.

    • If MySQL is configured to permit TLSv1 and TLSv1.1, but your system configuration permits only connections that use TLSv1.2 or higher, you cannot establish MySQL connections at all, because no protocol permitted by MySQL is permitted by the operating system.

    Workarounds for this issue include:

    • Change the system-wide host configuration to permit additional TLS protocols. Consult your operating system documentation for instructions. For example, your system may have an /etc/ssl/openssl.cnf file that contains these lines to restrict TLS protocols to TLSv1.2 or higher:

      [system_default_sect]
      MinProtocol = TLSv1.2

      Changing the value to a lower protocol version or None makes the system more permissive. However, this workaround has the disadvantage that permitting lower (less secure) protocols may have adverse security consequences.

    • If you cannot or prefer not to change the host TLS configuration, change MySQL applications to use higher (more secure) TLS protocols that are permitted by the host system. This may not be possible for older versions of MySQL that support only lower protocol versions. For example, prior to MySQL 5.7, TLSv1 is the only supported protocol, so attempts to connect to an older server fail even if the client is from a newer MySQL version and supports higher protocol versions. In such cases, an upgrade to a version of MySQL that supports additional TLS versions may be required.

  • The SSL library. If the SSL library does not support a particular protocol, neither does MySQL, and any parts of the following discussion that specify that protocol do not apply.

    • When compiled using OpenSSL 1.0.1 or higher, MySQL supports the TLSv1, TLSv1.1, and TLSv1.2 protocols.

    • When compiled using yaSSL, MySQL supports the TLSv1 and TLSv1.1 protocols.

    Note

    It is possible to compile MySQL using yaSSL as an alternative to OpenSSL only prior to MySQL 5.7.28. As of MySQL 5.7.28, support for yaSSL is removed and all MySQL builds use OpenSSL.

Connection TLS Protocol Configuration

The value of the tls_version system variable determines which TLS protocols a server permits for encrypted connections. The tls_version value applies to connections from clients and from slave servers using regular master/slave replication. The variable value is a list of one or more comma-separated protocol versions from this list (not case-sensitive): TLSv1, TLSv1.1, TLSv1.2. By default, this variable lists all protocols supported by the SSL library used to compile MySQL (TLSv1,TLSv1.1,TLSv1.2 for OpenSSL, TLSv1,TLSv1.1 for yaSSL). To determine the value of tls_version at runtime, use this statement:

mysql> SHOW GLOBAL VARIABLES LIKE 'tls_version';
+---------------+-----------------------+
| Variable_name | Value                 |
+---------------+-----------------------+
| tls_version   | TLSv1,TLSv1.1,TLSv1.2 |
+---------------+-----------------------+

To change the value of tls_version, set it at server startup. For example, to permit connections that use the TLSv1.1 or TLSv1.2 protocol, but prohibit connections that use the less-secure TLSv1 protocol, use these lines in the server my.cnf file:

[mysqld]
tls_version=TLSv1.1,TLSv1.2

To be even more restrictive and permit only TLSv1.2 connections, set tls_version like this (assuming that your server is compiled using OpenSSL because yaSSL does not support TLSv1.2):

[mysqld]
tls_version=TLSv1.2

Permitted protocols should be chosen such as not to leave holes in the list. For example, these values do not have holes:

tls_version=TLSv1,TLSv1.1,TLSv1.2
tls_version=TLSv1.1,TLSv1.2
tls_version=TLSv1.2

This value does have a hole and should not be used:

tls_version=TLSv1,TLSv1.2

The prohibition on holes also applies in other configuration contexts, such as for clients or replication slaves.

For client programs, the --tls-version option specifies which TLS protocols a client permits for connections to the server. The format of the option value is the same as for the tls_version system variable described previously (a list of one or more comma-separated protocol versions).

For master/slave replication, the MASTER_TLS_VERSION option for the CHANGE MASTER TO statement specifies which TLS protocols a slave server permits for connections to the master. The format of the option value is the same as for the tls_version system variable described previously. See Setting Up Replication to Use Encrypted Connections.

The protocols that can be specified for MASTER_TLS_VERSION depend on the SSL library. This option is independent of and not affected by the server tls_version value. For example, a server that acts as a replication slave can be configured with tls_version set to TLSv1.3 to permit only incoming connections that use TLSv1.3, but also configured with MASTER_TLS_VERSION set to TLSv1.2 to permit only TLSv1.2 for outgoing slave connections to the master.

Connection attempts in MySQL negotiate the use of the highest TLS protocol version available, depending on the SSL library used to compile the server and client, which key size is used, and whether the server or client are restricted from using some protocols (for example, by means of tls_version/--tls-version):

  • For a connection attempt to succeed, the server and client must be configured to permit some TLS protocol in common.

  • If the server and client are compiled using OpenSSL, TLSv1.2 is used if possible.

  • If either or both the server and client are compiled using yaSSL, TLSv1.1 is used if possible.

  • TLSv1.2 does not work with all ciphers that have a key size of 512 bits or less. To use this protocol with such a key, use --ssl-cipher to specify the cipher name explicitly:

    AES128-SHA
    AES128-SHA256
    AES256-SHA
    AES256-SHA256
    CAMELLIA128-SHA
    CAMELLIA256-SHA
    DES-CBC3-SHA
    DHE-RSA-AES256-SHA
    RC4-MD5
    RC4-SHA
    SEED-SHA
  • For better security, use a certificate with an RSA key size of at least 2048 bits.

Note

Prior to MySQL 5.7.10, MySQL supports only TLSv1, for both OpenSSL and yaSSL, and no system variable or client option exist for specifying which TLS protocols to permit.

If the server and client have no permitted protocol in common, the server terminates the connection request. Examples:

  • if the server is configured with tls_version=TLSv1.1,TLSv1.2:

    • Connection attempts fail for clients invoked with --tls-version=TLSv1, and for older clients that do not support the --tls-version option and implicitly support only TLSv1.

    • Similarly, connection attempts fail for replication slaves configured with MASTER_TLS_VERSION = 'TLSv1', and for older slaves that do not support the MASTER_TLS_VERSION option and implicitly support only TLSv1.

  • if the server is configured with tls_version=TLSv1 or is an older server that does not support the tls_version system variable and implicitly supports only TLSv1:

    • Connection attempts fail for clients invoked with --tls-version=TLSv1.1,TLSv1.2.

    • Similarly, connection attempts fail for replication slaves configured with MASTER_TLS_VERSION = 'TLSv1.1,TLSv1.2'.

MySQL permits specifying a list of protocols to support. This list is passed directly down to the underlying SSL library and is ultimately up to that library what protocols it actually enables from the supplied list. Please refer to the MySQL source code and the OpenSSL SSL_CTX_new() documentation for information about how the SSL library handles this.

Connection Cipher Configuration

To specify a cipher or ciphers for encrypted connections, use the --ssl-cipher option, which is available for the server and for client programs.

For master/slave replication, the MASTER_SSL_CIPHER option for the CHANGE MASTER TO statement specifies which ciphers a slave server permits for connections to the master. See Setting Up Replication to Use Encrypted Connections.

To determine which ciphers a given server supports, check the session value of the Ssl_cipher_list status variable:

SHOW SESSION STATUS LIKE 'Ssl_cipher_list';

The Ssl_cipher_list status variable lists the possible SSL ciphers (empty for non-SSL connections). The set of available ciphers depends on your MySQL version and whether MySQL was compiled using OpenSSL or yaSSL, and (for OpenSSL) the library version used to compile MySQL.

As of MySQL 5.7.10, order of ciphers passed by MySQL to the SSL library is significant. More secure ciphers are mentioned first in the list, and the first cipher supported by the provided certificate is selected.

MySQL passes this cipher list to OpenSSL:

ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA256
ECDHE-ECDSA-AES256-SHA384
ECDHE-RSA-AES256-SHA384
DHE-RSA-AES128-GCM-SHA256
DHE-DSS-AES128-GCM-SHA256
DHE-RSA-AES128-SHA256
DHE-DSS-AES128-SHA256
DHE-DSS-AES256-GCM-SHA384
DHE-RSA-AES256-SHA256
DHE-DSS-AES256-SHA256
ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES128-SHA
ECDHE-RSA-AES256-SHA
ECDHE-ECDSA-AES256-SHA
DHE-DSS-AES128-SHA
DHE-RSA-AES128-SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
DHE-RSA-AES256-SHA
AES128-GCM-SHA256
DH-DSS-AES128-GCM-SHA256
ECDH-ECDSA-AES128-GCM-SHA256
AES256-GCM-SHA384
DH-DSS-AES256-GCM-SHA384
ECDH-ECDSA-AES256-GCM-SHA384
AES128-SHA256
DH-DSS-AES128-SHA256
ECDH-ECDSA-AES128-SHA256
AES256-SHA256
DH-DSS-AES256-SHA256
ECDH-ECDSA-AES256-SHA384
AES128-SHA
DH-DSS-AES128-SHA
ECDH-ECDSA-AES128-SHA
AES256-SHA
DH-DSS-AES256-SHA
ECDH-ECDSA-AES256-SHA
DHE-RSA-AES256-GCM-SHA384
DH-RSA-AES128-GCM-SHA256
ECDH-RSA-AES128-GCM-SHA256
DH-RSA-AES256-GCM-SHA384
ECDH-RSA-AES256-GCM-SHA384
DH-RSA-AES128-SHA256
ECDH-RSA-AES128-SHA256
DH-RSA-AES256-SHA256
ECDH-RSA-AES256-SHA384
ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES128-SHA
ECDHE-RSA-AES256-SHA
ECDHE-ECDSA-AES256-SHA
DHE-DSS-AES128-SHA
DHE-RSA-AES128-SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
DHE-RSA-AES256-SHA
AES128-SHA
DH-DSS-AES128-SHA
ECDH-ECDSA-AES128-SHA
AES256-SHA
DH-DSS-AES256-SHA
ECDH-ECDSA-AES256-SHA
DH-RSA-AES128-SHA
ECDH-RSA-AES128-SHA
DH-RSA-AES256-SHA
ECDH-RSA-AES256-SHA
DES-CBC3-SHA

MySQL passes this cipher list to yaSSL:

DHE-RSA-AES256-SHA
DHE-RSA-AES128-SHA
AES128-RMD
DES-CBC3-RMD
DHE-RSA-AES256-RMD
DHE-RSA-AES128-RMD
DHE-RSA-DES-CBC3-RMD
AES256-SHA
RC4-SHA
RC4-MD5
DES-CBC3-SHA
DES-CBC-SHA
EDH-RSA-DES-CBC3-SHA
EDH-RSA-DES-CBC-SHA
AES128-SHA:AES256-RMD

As of MySQL 5.7.10, these cipher restrictions are in place:

  • The following ciphers are permanently restricted:

    !DHE-DSS-DES-CBC3-SHA
    !DHE-RSA-DES-CBC3-SHA
    !ECDH-RSA-DES-CBC3-SHA
    !ECDH-ECDSA-DES-CBC3-SHA
    !ECDHE-RSA-DES-CBC3-SHA
    !ECDHE-ECDSA-DES-CBC3-SHA
  • The following categories of ciphers are permanently restricted:

    !aNULL
    !eNULL
    !EXPORT
    !LOW
    !MD5
    !DES
    !RC2
    !RC4
    !PSK
    !SSLv3

If the server is started with an --ssl-cert option specifying a certificate that uses any of the preceding restricted ciphers or cipher categories, the server starts with support for encrypted connections disabled.