Encrypted SSL/TLS sessions protect MySQL and MariaDB traffic from passive capture, keeping credentials and query results confidential on untrusted networks.
When a client connects over TCP, the database server negotiates TLS during the initial handshake. The server presents a certificate, the client validates it against a trusted CA, and the session keys encrypt all subsequent protocol packets.
Many modern packages ship with TLS support and sometimes auto-generated certificates, but encryption without certificate validation still permits silent interception by an attacker with network position. Certificate files must be readable by the database service, private keys must remain tightly permissioned, and an incorrect ssl-key or ssl-cert path can prevent mysqld from starting.
Steps to enable SSL/TLS on MariaDB or MySQL server:
- Open a terminal with sudo privileges.
- Create a directory for TLS material at /etc/mysql/ssl.
$ sudo install -d -m 0750 -o mysql -g mysql /etc/mysql/ssl
- Generate a private key for a local certificate authority at /etc/mysql/ssl/ca-key.pem.
$ sudo openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out /etc/mysql/ssl/ca-key.pem .....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*+++++ .....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*+++++
Store the CA private key offline when certificate signing is complete.
- Create a self-signed CA certificate at /etc/mysql/ssl/ca-cert.pem.
$ sudo openssl req -x509 -new -key /etc/mysql/ssl/ca-key.pem -sha256 -days 3650 -out /etc/mysql/ssl/ca-cert.pem Country Name (2 letter code) [AU]: US State or Province Name (full name) [Some-State]: California Locality Name (eg, city) []: SanFrancisco Organization Name (eg, company) [Internet Widgits Pty Ltd]: ExampleOrg Organizational Unit Name (eg, section) []: Database Common Name (e.g. server FQDN or YOUR name) []: ExampleOrg MySQL CA Email Address []:
Only the CA certificate (not the CA private key) belongs on client hosts for server validation.
- Generate a private key for the database server at /etc/mysql/ssl/server-key.pem.
$ sudo openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out /etc/mysql/ssl/server-key.pem .....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*+++++ .....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*+++++
- Create a server certificate signing request at /etc/mysql/ssl/server-req.pem.
$ sudo openssl req -new -key /etc/mysql/ssl/server-key.pem -out /etc/mysql/ssl/server-req.pem Country Name (2 letter code) [AU]: US State or Province Name (full name) [Some-State]: California Locality Name (eg, city) []: SanFrancisco Organization Name (eg, company) [Internet Widgits Pty Ltd]: ExampleOrg Organizational Unit Name (eg, section) []: Database Common Name (e.g. server FQDN or YOUR name) []: db.example.net Email Address []:
Hostname validation requires a subjectAltName; a Common Name alone is insufficient for VERIFY_IDENTITY in many TLS stacks.
- Create an OpenSSL extension file for the server certificate at /etc/mysql/ssl/server-ext.cnf.
$ sudo tee /etc/mysql/ssl/server-ext.cnf >/dev/null <<'EOF' [v3_server] basicConstraints=CA:FALSE keyUsage=digitalSignature,keyEncipherment extendedKeyUsage=serverAuth subjectAltName=DNS:db.example.net,IP:10.0.0.10 EOF
Replace the DNS and IP values with real database host details.
- Sign the server request to create /etc/mysql/ssl/server-cert.pem.
$ sudo openssl x509 -req -in /etc/mysql/ssl/server-req.pem -CA /etc/mysql/ssl/ca-cert.pem -CAkey /etc/mysql/ssl/ca-key.pem -CAcreateserial -out /etc/mysql/ssl/server-cert.pem -days 3650 -sha256 -extfile /etc/mysql/ssl/server-ext.cnf -extensions v3_server Certificate request self-signature ok subject=CN = db.example.net
- Generate a private key for an optional client certificate at /etc/mysql/ssl/client-key.pem.
$ sudo openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out /etc/mysql/ssl/client-key.pem .....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*+++++ .....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*+++++
Client certificates are optional unless accounts enforce REQUIRE X509 or specific certificate attributes.
- Create a client certificate signing request at /etc/mysql/ssl/client-req.pem.
$ sudo openssl req -new -key /etc/mysql/ssl/client-key.pem -out /etc/mysql/ssl/client-req.pem Country Name (2 letter code) [AU]: US State or Province Name (full name) [Some-State]: California Locality Name (eg, city) []: SanFrancisco Organization Name (eg, company) [Internet Widgits Pty Ltd]: ExampleOrg Organizational Unit Name (eg, section) []: Database Common Name (e.g. server FQDN or YOUR name) []: mysql-client Email Address []:
- Create an OpenSSL extension file for the client certificate at /etc/mysql/ssl/client-ext.cnf.
$ sudo tee /etc/mysql/ssl/client-ext.cnf >/dev/null <<'EOF' [v3_client] basicConstraints=CA:FALSE keyUsage=digitalSignature extendedKeyUsage=clientAuth EOF
- Sign the client request to create /etc/mysql/ssl/client-cert.pem.
$ sudo openssl x509 -req -in /etc/mysql/ssl/client-req.pem -CA /etc/mysql/ssl/ca-cert.pem -CAkey /etc/mysql/ssl/ca-key.pem -CAcreateserial -out /etc/mysql/ssl/client-cert.pem -days 3650 -sha256 -extfile /etc/mysql/ssl/client-ext.cnf -extensions v3_client Certificate request self-signature ok subject=CN = mysql-client
- Set ownership of the server key/certificate to the mysql user.
$ sudo chown mysql:mysql /etc/mysql/ssl/server-key.pem /etc/mysql/ssl/server-cert.pem
Keep client key material root-owned on the server, or copy it off-host for client use.
- Restrict permissions on private keys.
$ sudo chmod 600 /etc/mysql/ssl/ca-key.pem /etc/mysql/ssl/server-key.pem /etc/mysql/ssl/client-key.pem
- Set read permissions on certificate-related files.
$ sudo chmod 644 /etc/mysql/ssl/ca-cert.pem /etc/mysql/ssl/server-cert.pem /etc/mysql/ssl/client-cert.pem /etc/mysql/ssl/server-req.pem /etc/mysql/ssl/client-req.pem
- Add the TLS paths under the mysqld section in /etc/mysql/mysql.conf.d/mysqld.cnf.
[mysqld] ssl-ca=/etc/mysql/ssl/ca-cert.pem ssl-cert=/etc/mysql/ssl/server-cert.pem ssl-key=/etc/mysql/ssl/server-key.pem
MariaDB commonly uses /etc/mysql/mariadb.conf.d/50-server.cnf for server settings.
An incorrect ssl-key path or unreadable key file can prevent the database service from starting.
- Restart the mysql service.
$ sudo systemctl restart mysql
The service name is often mariadb on MariaDB packages.
- Check the service status for an active state.
$ sudo systemctl status mysql ● mysql.service - MySQL Community Server Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2025-12-08 09:41:12 UTC; 12s ago ##### snipped #####Use journalctl for startup errors: sudo journalctl -u mysql -b --no-pager.
- Confirm the server loaded the configured TLS files.
$ sudo mysql -e "SHOW VARIABLES WHERE Variable_name IN ('ssl_ca','ssl_cert','ssl_key');" +---------------+------------------------------+ | Variable_name | Value | +---------------+------------------------------+ | ssl_ca | /etc/mysql/ssl/ca-cert.pem | | ssl_cert | /etc/mysql/ssl/server-cert.pem | | ssl_key | /etc/mysql/ssl/server-key.pem | +---------------+------------------------------+A non-empty Ssl_cipher value confirms an encrypted session.
- Create a minimal test account that requires SSL.
$ sudo mysql -e "CREATE USER 'tlscheck'@'127.0.0.1' IDENTIFIED BY 'STRONG_PASSWORD_HERE' REQUIRE SSL;" Query OK, 0 rows affected
Replace STRONG_PASSWORD_HERE with a unique password.
- Verify a TLS cipher is negotiated for a TCP connection.
$ sudo mysql -h 127.0.0.1 --ssl-ca=/etc/mysql/ssl/ca-cert.pem -u tlscheck -p -e "SHOW STATUS LIKE 'Ssl_cipher';" Enter password: +---------------+-------------------------+ | Variable_name | Value | +---------------+-------------------------+ | Ssl_cipher | TLS_AES_256_GCM_SHA384 | +---------------+-------------------------+
Mutual TLS uses --ssl-cert plus --ssl-key with an account that enforces REQUIRE X509.
Account-level enforcement uses ALTER USER 'app'@'%' REQUIRE SSL;.
- Remove the test account.
$ sudo mysql -e "DROP USER 'tlscheck'@'127.0.0.1';" Query OK, 0 rows affected
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
Comment anonymously. Login not required.
