Skip to content

Last updated: 2026-06-25

MySQL TLS/SSL Configuration Guide

This guide provides recommended TLS/SSL settings for MySQL to encrypt connections between clients and the database server. Encrypting database traffic prevents eavesdropping and man-in-the-middle attacks on sensitive data.

Prerequisites

  • MySQL 8.4 LTS or later (MySQL 8.0 reached end of life in April 2026)
  • OpenSSL 1.1.1 or later
  • SSL certificates (server certificate, private key, and CA certificate)

MySQL 8.4+ ships with TLS support enabled by default and auto-generates certificates on first startup. These self-signed certificates should be replaced with properly issued certificates for production use.

Generating Certificates

MySQL 8.4+ automatically generates self-signed certificates on first startup if none exist. To generate certificates manually, use openssl commands or obtain certificates from a trusted CA for production use.

For production, use certificates from a CA such as Let's Encrypt, or your organization's internal CA.

Server Configuration

Add the following settings to your MySQL configuration file under the [mysqld] section.

Path note: Debian/Ubuntu: /etc/mysql/mysql.conf.d/mysqld.cnf. RHEL: /etc/my.cnf.d/mysql-server.cnf (MySQL Community) or /etc/my.cnf. The main config (/etc/mysql/my.cnf or /etc/my.cnf) includes drop-in directories.

Protocol Versions

Restrict connections to TLS 1.2 and TLS 1.3 only:

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

Cipher Suites

Configure strong cipher suites for TLS 1.2:

[mysqld]
ssl_cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305

For TLS 1.3 cipher suites (MySQL 8.0.16+):

[mysqld]
tls_ciphersuites=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

Certificate Files

[mysqld]
ssl_ca=/etc/mysql/ssl/ca.pem
ssl_cert=/etc/mysql/ssl/server-cert.pem
ssl_key=/etc/mysql/ssl/server-key.pem

Require Encrypted Connections

Force all client connections to use TLS. Without this, clients can still connect without encryption:

[mysqld]
require_secure_transport=ON

Complete Server Configuration

[mysqld]
# TLS protocol versions
tls_version=TLSv1.2,TLSv1.3

# TLS 1.2 cipher suites
ssl_cipher=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305

# TLS 1.3 cipher suites
tls_ciphersuites=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

# Certificate files
ssl_ca=/etc/mysql/ssl/ca.pem
ssl_cert=/etc/mysql/ssl/server-cert.pem
ssl_key=/etc/mysql/ssl/server-key.pem

# Require encrypted connections
require_secure_transport=ON

Client Configuration

Configure MySQL clients to use TLS by adding settings to the [client] section:

[client]
ssl_mode=REQUIRED
ssl_ca=/etc/mysql/ssl/ca.pem

Available ssl_mode values:

  • REQUIRED - Connect with encryption, but don't verify the server certificate
  • VERIFY_CA - Connect with encryption and verify the server certificate against the CA
  • VERIFY_IDENTITY - Connect with encryption, verify the CA, and verify the server hostname matches the certificate (recommended)

For maximum security, use VERIFY_IDENTITY:

[client]
ssl_mode=VERIFY_IDENTITY
ssl_ca=/etc/mysql/ssl/ca.pem

Mutual TLS (mTLS)

Standard TLS encrypts the connection and lets the client verify the server's certificate. Mutual TLS goes further: the server also verifies a certificate presented by the client. MySQL implements this through per-user REQUIRE clauses that control what each account must present to connect. This is optional; it is most useful for service accounts and automated clients where you can manage client certificates centrally.

Require a specific user to connect over TLS (encryption only, no certificate verification):

ALTER USER 'appuser'@'%' REQUIRE SSL;

To require the user to also present a valid client certificate signed by the server's CA:

ALTER USER 'appuser'@'%' REQUIRE X509;

For the strictest enforcement, require a specific certificate subject or issuer:

ALTER USER 'appuser'@'%' REQUIRE SUBJECT '/CN=appuser/O=Example Corp';

Client Configuration for mTLS

Clients connecting to an account with REQUIRE X509 must provide a certificate and key:

[client]
ssl_mode=VERIFY_IDENTITY
ssl_ca=/etc/mysql/ssl/ca.pem
ssl_cert=/etc/mysql/ssl/client-cert.pem
ssl_key=/etc/mysql/ssl/client-key.pem

Or on the command line:

mysql -h db.example.com -u appuser -p \
    --ssl-ca=/etc/mysql/ssl/ca.pem \
    --ssl-cert=/etc/mysql/ssl/client-cert.pem \
    --ssl-key=/etc/mysql/ssl/client-key.pem

See RFC 8446 ยง4.3.2 for the TLS Certificate Request specification, and Wikipedia: Mutual authentication for a general overview.

Replication TLS

To encrypt replication traffic between primary and replica servers, configure the replica to use TLS:

CHANGE REPLICATION SOURCE TO
    SOURCE_SSL = 1,
    SOURCE_SSL_CA = '/etc/mysql/ssl/ca.pem',
    SOURCE_SSL_CERT = '/etc/mysql/ssl/client-cert.pem',
    SOURCE_SSL_KEY = '/etc/mysql/ssl/client-key.pem',
    SOURCE_SSL_VERIFY_SERVER_CERT = 1;

The older CHANGE MASTER TO syntax was removed in MySQL 8.4. Use CHANGE REPLICATION SOURCE TO exclusively.

Security Notes

The cipher suite and protocol configuration in this guide addresses the following known TLS vulnerabilities:

  • POODLE (CVE-2014-3566, 2014): SSL 3.0 is disabled. TLS_FALLBACK_SCSV was added in OpenSSL 1.0.1j / 1.0.2 (October 2014); SSL 3.0 disabled by default in OpenSSL 1.1.0 (August 2016).
  • BEAST (CVE-2011-3389, 2011): Mitigated by recommending TLS 1.2 as the minimum; AEAD-only ciphers eliminate the CBC padding oracle.
  • CRIME (CVE-2012-4929, 2012): TLS compression is off by default in OpenSSL 1.1.0+; do not enable it.
  • Lucky13 (2013): AEAD-only cipher list eliminates CBC padding timing side-channels entirely.
  • FREAK (CVE-2015-0204, 2015): EXPORT-grade ciphers are excluded from the cipher string. Removed from OpenSSL 1.1.0 (August 2016).
  • LOGJAM (CVE-2015-4000, 2015): Short-key DHE is excluded; only ECDHE key exchange is recommended.
  • Sweet32 (CVE-2016-2183, 2016): 3DES is excluded from the cipher string.
  • ROBOT (2017): Static RSA key exchange is excluded; only ECDHE is recommended.
  • Downgrade attacks: TLS_FALLBACK_SCSV prevents protocol version rollback.
  • Renegotiation injection (CVE-2009-3555, 2009): Secure renegotiation is enforced by default in OpenSSL 0.9.8m+; TLS 1.3 removes renegotiation entirely.

The following are not addressable through TLS configuration alone:

  • Heartbleed (CVE-2014-0160, 2014): A memory disclosure bug in OpenSSL 1.0.1 through 1.0.1f. Fixed in OpenSSL 1.0.1g (April 7, 2014). Addressed by patching OpenSSL, not by TLS configuration.
  • BREACH (CVE-2013-3587, 2013): Not applicable. BREACH targets HTTP-level response compression; the MySQL wire protocol does not involve HTTP.
  • DROWN (CVE-2016-0800, 2016): Requires SSLv2 to be enabled on any server sharing the same private key. Ensure SSLv2 is disabled on all services that use the same certificate and key pair.

Verification

After restarting MySQL, verify TLS is active:

mysql -u root -p -e "SHOW VARIABLES LIKE '%ssl%';"
mysql -u root -p -e "SHOW VARIABLES LIKE 'tls_version';"

Check the current connection's encryption status:

mysql -u root -p -e "SHOW SESSION STATUS LIKE 'Ssl_cipher';"

This should return a cipher name like TLS_AES_256_GCM_SHA384 confirming the connection is encrypted.


Related Guides

View all Databases guides →

Configured TLS? Now Monitor It.

Generator Labs alerts you before certificates expire, get revoked, or fail chain validation, across HTTPS, SMTPS, IMAPS, LDAPS, and more.

Certificate Monitoring →