Enable TLS between TiDB Clients and Servers

By default, TiDB allows insecure connections between the server and clients. This enables third parties that monitor channel traffic to know and possibly modify the data sent and received between the server and the client, including query content and query results. If a channel is untrustworthy (such as if the client is connected to the TiDB server via a public network), an insecure connection is prone to information leakage. In this case, for security reasons, it is recommended to require a connection that is secured with TLS.

The TiDB server supports secure connections based on the TLS (Transport Layer Security) protocol. The protocol is consistent with MySQL secure connections and is directly supported by existing MySQL clients such as MySQL Client, MySQL Shell and MySQL drivers. TLS is sometimes referred to as SSL (Secure Sockets Layer). Because the SSL protocol has known security vulnerabilities, TiDB does not support SSL. TiDB supports the following protocols: TLSv1.2 and TLSv1.3.

When a TLS secured connection is used, the connection has the following security properties:

  • Confidentiality: the traffic plaintext is encrypted to avoid eavesdropping
  • Integrity: the traffic plaintext cannot be tampered
  • Authentication: (optional) the client can verify the identity of the server and the server can verify the identity of the client to avoid man-in-the-middle attacks

To use connections secured with TLS, you first need to configure the TiDB server to enable TLS. Then you need to configure the client application to use TLS. Most client libraries enable TLS automatically when the server has TLS support configured correctly.

Similar to MySQL, TiDB allows TLS and non-TLS connections on the same TCP port. For a TiDB server with TLS enabled, you can choose to securely connect to the TiDB server through an encrypted connection, or to use an unencrypted connection. You can use the following ways to require the use of secure connections:

  • Configure the system variable require_secure_transport to require secure connections to the TiDB server for all users.

  • Specify REQUIRE SSL when you create a user (create user), or modify an existing user (alter user), which is to specify that specified users must use TLS connections to access TiDB. The following is an example of creating a user:

    CREATE USER 'u1'@'%' IDENTIFIED BY 'my_random_password' REQUIRE SSL;

Configure TiDB server to use secure connections

See the following descriptions about the related parameters to enable secure connections:

  • auto-tls: enables automatic certificate generation (since v5.2.0)
  • ssl-cert: specifies the file path of the SSL certificate
  • ssl-key: specifies the private key that matches the certificate
  • ssl-ca: (optional) specifies the file path of the trusted CA certificate
  • tls-version: (optional) specifies the minimum TLS version, e.g. "TLSv1.2"

auto-tls allows secure connections but does not provide client certificate validation. For certificate validation, and to control how certificates are generated, see the advice on configuring the ssl-cert, ssl-key and ssl-ca variables below.

To enable secure connections with your own certificates in the TiDB server, you must specify both of the ssl-cert and ssl-key parameters in the configuration file when you start the TiDB server. You can also specify the ssl-ca parameter for client authentication (see Enable authentication).

All the files specified by the parameters are in PEM (Privacy Enhanced Mail) format. Currently, TiDB does not support the import of a password-protected private key, so it is required to provide a private key file without a password. If the certificate or private key is invalid, the TiDB server starts as usual, but the client cannot connect to the TiDB server through a TLS connection.

If the certificate parameters are correct, TiDB outputs mysql protocol server secure connection is enabled to the logs on "INFO" level when started.

Configure the MySQL client to use TLS connections

The client of MySQL 5.7 or later versions attempts to establish a TLS connection by default. If the server does not support TLS connections, it automatically returns to unencrypted connections. The client of MySQL earlier than version 5.7 uses the non-TLS connections by default.

You can change the connection behavior of the client using the following --ssl-mode parameters:

  • --ssl-mode=REQUIRED: The client requires a TLS connection. The connection cannot be established if the server side does not support TLS connections.
  • In the absence of the --ssl-mode parameter: The client attempts to use a TLS connection, but the encrypted connection cannot be established if the server side does not support encrypted connections. Then the client uses an unencrypted connection.
  • --ssl-mode=DISABLED: The client uses an unencrypted connection.

MySQL 8.x clients have two SSL modes in addition to this parameter:

  • --ssl-mode=VERIFY_CA: Validates the certificate from the server against the CA that requires --ssl-ca.
  • --ssl-mode=VERIFY_IDENTITY: The same as VERIFY_CA, but also validating whether the hostname you are connecting to matches the certificate.

For MySQL 5.7 and MariaDB clients and earlier you can use --ssl-verify-server-cert to enable validation of the server certificate.

For more information, see Client-Side Configuration for Encrypted Connections in MySQL.

Enable authentication

If the ssl-ca parameter is not specified in the TiDB server or MySQL client, the client or the server does not perform authentication by default and cannot prevent man-in-the-middle attack. For example, the client might "securely" connect to a disguised client. You can configure the ssl-ca parameter for authentication in the server and client. Generally, you only need to authenticate the server, but you can also authenticate the client to further enhance the security.

  • To authenticate the TiDB server from the MySQL client:

    1. Specify the ssl-cert and ssl-key parameters in the TiDB server.
    2. Specify the --ssl-ca parameter in the MySQL client.
    3. Specify the --ssl-mode to VERIFY_CA at least in the MySQL client.
    4. Make sure that the certificate (ssl-cert) configured in the TiDB server is signed by the CA specified by the client --ssl-ca parameter; otherwise, the authentication fails.
  • To authenticate the MySQL client from the TiDB server:

    1. Specify the ssl-cert, ssl-key, and ssl-ca parameters in the TiDB server.
    2. Specify the --ssl-cert and --ssl-key parameters in the client.
    3. Make sure the server-configured certificate and the client-configured certificate are both signed by the ssl-ca specified by the server.
  • To perform mutual authentication, meet both of the above requirements.

By default, the server-to-client authentication is optional. Even if the client does not present its certificate of identification during the TLS handshake, the TLS connection can be still established. You can also require the client to be authenticated by specifying REQUIRE x509 when creating a user (CREATE USER), or modifying an existing user (ALTER USER). The following is an example of creating a user:

CREATE USER 'u1'@'%' REQUIRE X509;

Check whether the current connection uses encryption

Use the SHOW STATUS LIKE "%Ssl%"; statement to get the details of the current connection, including whether encryption is used, the encryption protocol used by encrypted connections and the TLS version number.

See the following example of the result in an encrypted connection. The results change according to different TLS versions or encryption protocols supported by the client.

SHOW STATUS LIKE "Ssl%";
+-----------------------+-------------------------------------------------------> | Variable_name | Value > +-----------------------+-------------------------------------------------------> | Ssl_cipher | TLS_AES_128_GCM_SHA256 > | Ssl_cipher_list | RC4-SHA:DES-CBC3-SHA:AES128-SHA:AES256-SHA:AES128-SHA2> | Ssl_server_not_after | Apr 23 07:59:47 2024 UTC > | Ssl_server_not_before | Jan 24 07:59:47 2024 UTC > | Ssl_verify_mode | 5 > | Ssl_version | TLSv1.3 > +-----------------------+-------------------------------------------------------> 6 rows in set (0.0062 sec)

For the official MySQL client, you can also use the STATUS or \s statement to view the connection status:

mysql> \s ... SSL: Cipher in use is TLS_AES_128_GCM_SHA256 ...

Supported TLS versions, key exchange protocols, and encryption algorithms

The TLS versions, key exchange protocols and encryption algorithms supported by TiDB are determined by the official Go libraries.

The crypto policy for your operating system and the client library you are using might also impact the list of supported protocols and cipher suites.

Supported TLS versions

  • TLSv1.2
  • TLSv1.3

You can use the tls-version configuration option to limit the TLS versions that can be used.

The actual TLS versions that can be used depend on the OS crypto policy, MySQL client version and the SSL/TLS library that is used by the client.

Supported key exchange protocols and encryption algorithms

  • TLS_RSA_WITH_AES_128_CBC_SHA
  • TLS_RSA_WITH_AES_256_CBC_SHA
  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_128_GCM_SHA256
  • TLS_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
  • TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_GCM_SHA256
  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256

Reload certificate, key, and CA

To replace the certificate, the key or CA, first replace the corresponding files, then execute the ALTER INSTANCE RELOAD TLS statement on the running TiDB instance to reload the certificate (ssl-cert), the key (ssl-key), and the CA (ssl-ca) from the original configuration path. In this way, you do not need to restart the TiDB instance.

The newly loaded certificate, key, and CA take effect on the connection that is established after the statement is successfully executed. The connection established before the statement execution is not affected.

Monitoring

Since TiDB v5.2.0, you can use the Ssl_server_not_after and Ssl_server_not_before status variables to monitor the start and end dates of the validity of the certificate.

SHOW GLOBAL STATUS LIKE 'Ssl\_server\_not\_%';
+-----------------------+--------------------------+ | Variable_name | Value | +-----------------------+--------------------------+ | Ssl_server_not_after | Nov 28 06:42:32 2021 UTC | | Ssl_server_not_before | Aug 30 06:42:32 2021 UTC | +-----------------------+--------------------------+ 2 rows in set (0.0076 sec)

See also