I often get asked how to set up and use SSL with MySQL, especially on Windows – I think largely because the manual step-by-step is more geared towards Linux users (though this “how-to” is valid for all – anyone can copy/paste the commands after changing the paths).
So I’ve compiled a concise, yet comprehensive, how-to that I wanted to share with everyone out there who wants to set this up quickly and efficiently.
And for those who haven’t done it, setting up SSL can often seem intimidating, so I want to dispell that myth while I’m at it, and show you how quick and easy it can be to set up SSL for MySQL.
For one, I should mention that I’m using a version where SSL is ‘available’, just ‘DISABLED’ (some versions can be compiled w/out ssl support – so those would not work):
mysql> show global variables like 'have_%ssl'; +---------------+----------+ | Variable_name | Value | +---------------+----------+ | have_openssl | DISABLED | | have_ssl | DISABLED | +---------------+----------+
This is normal, and what you want to see if you’ve not already set up SSL.
Next, I like to store the SSL files I generate in their own directory, so I created a subdir named ‘certs’ in the MySQL $basedir. But by all means, store these wherever you wish.
Third, you need to have OpenSSL installed/available on your machine. Many have this already, certainly most Linux anyway (check with “where openssl” on Win or “which openssl” on Linux). (These latter commands assume you have it in the $PATH too.)
If you do not have it, you can download it from here:
http://www.slproweb.com/…/Win32OpenSSL.html <-- Windows http://www.openssl.org/source/ <-- Linux (And note my commands below assume either 'openssl' in the $PATH or that you're in the directory where the 'openssl' binary/exe is located.) Now that that’s out of the way, you’re basically looking at a 5 step process:
- Create CA Certificates (following 2 commands create 2 files: ca-cert.pem and ca-key.pem):
openssl genrsa 2048 > "C:/Program Files/mysql/mysql-5.5.16/certs/ca-key.pem" openssl req -new -x509 -nodes -days 3600 -key "C:/Program Files/mysql/mysql-5.5.16/certs/ca-key.pem" > "C:/Program Files/mysql/mysql-5.5.16/certs/ca-cert.pem"
- Create Server Certificates (following 2 commands create 3 files: server-cert.pem, server-key.pem, and server-req.pem):
openssl req -newkey rsa:2048 -days 3600 -nodes -keyout "C:/Program Files/mysql/mysql-5.5.16/certs/server-key.pem" > "C:/Program Files/mysql/mysql-5.5.16/certs/server-req.pem" openssl x509 -req -in "C:/Program Files/mysql/mysql-5.5.16/certs/server-req.pem" -days 3600 -CA "C:/Program Files/mysql/mysql-5.5.16/certs/ca-cert.pem" -CAkey "C:/Program Files/mysql/mysql-5.5.16/certs/ca-key.pem" -set_serial 01 > "C:/Program Files/mysql/mysql-5.5.16/certs/server-cert.pem"
- Create Client Certificates (following 2 commands create 3 files: client-cert.pem, client-key.pem, and client-req.pem):
openssl req -newkey rsa:2048 -days 3600 -nodes -keyout "C:/Program Files/mysql/mysql-5.5.16/certs/client-key.pem" > "C:/Program Files/mysql/mysql-5.5.16/certs/client-req.pem" openssl x509 -req -in "C:/Program Files/mysql/mysql-5.5.16/certs/client-req.pem" -days 3600 -CA "C:/Program Files/mysql/mysql-5.5.16/certs/ca-cert.pem" -CAkey "C:/Program Files/mysql/mysql-5.5.16/certs/ca-key.pem" -set_serial 01 > "C:/Program Files/mysql/mysql-5.5.16/certs/client-cert.pem"
- Create SSL User(s):
GRANT ALL PRIVILEGES ON *.* TO 'ssluser'@'localhost' IDENTIFIED BY 'ssluser' REQUIRE SSL;
- Update my.cnf and restart mysqld (add following 3 options to [mysqld] section of my.cnf file)
[mysqld] ssl-ca = "C:/Program Files/MySQL/mysql-5.5.16/certs/ca-cert.pem" ssl-cert = "C:/Program Files/MySQL/mysql-5.5.16/certs/server-cert.pem" ssl-key = "C:/Program Files/MySQL/mysql-5.5.16/certs/server-key.pem"
After restart, connect via SSL with your newly created SSL user (this is the minimum you need to specify – note the “–ssl-key=”, as-is .. refer to prev. post and related bug for further discussion on that if interested):
mysql -ussluser -pssluser -P3430 --ssl-key=
You can verify with the ‘status’ command once connected (note the SSL “cipher in use is DHE-RSA-AES256-SHA” means SSL is being used):
mysql> status -------------- mysql Ver 14.14 Distrib 5.5.16, for Win32 (x86) Connection id: 11 Current database: Current user: ssluser@localhost SSL: Cipher in use is DHE-RSA-AES256-SHA Using delimiter: ; Server version: 5.5.16-log MySQL Community Server (GPL) Protocol version: 10 Connection: localhost via TCP/IP Server characterset: latin1 Db characterset: latin1 Client characterset: cp850 Conn. characterset: cp850 TCP port: 3430 Uptime: 35 min 26 sec Threads: 1 Questions: 24 Slow queries: 0 Opens: 33 Flush tables: 1 Open tables: 0 Queries per second avg: 0.011
If you’re knowledgeable abut SSL (and MySQL), or if you’ve read my prior post discussing SSL, you’ll know you do not need all of the files I created above (8 in total).
In fact, for the most basic SSL setup, (“gateway SSL”, we’ll say), you only technically need these 3 files: ca-cert.pem, server-cert.pem, and server-key.pem.
But, why not create all you’d ever need, since it’s only a couple commands, and then you’re set in case you want to move beyond the “gateway SSL” setup into an even more secure SSL setup.
If you’re interested in the even-more-secure SSL setups, you’ll want to read up on the REQUIRE X509, REQUIRE ISSUER, REQUIRE SUBJECT, and REQUIRE CIPHER specifications on the following page:
As always, hope this helps.