MySQL offers native support for connecting via SSL. By default this is available in AWS RDS MySQL instances. Using this connection method effectively encrypts all data going back and forth between the client and the server. This prevents eavesdropping (aka packet sniffing). This is especially important in relation to cloud hosting, where traffic sniffing may be possible by other customers. There are other ways to protect the traffic (ssh tunnels, VPN), and I discuss the pro’s and con’s of these below.
I wanted to find out how much of a performance hit MySQL’s SSL mode caused so I did a benchmark which you can read about here. The performance penalty is pretty high – 20% and up, OUCH!
Documentation for using SSL natively with MySQL:
Application Layer Changes:
Connecting to MySQL in SSL mode requires extra connection options. On the command line this is as simple as adding the –ssl_ca option which points to the *.pem file. In the case of X.509 certificates, –ssl_cert and –ssl_key are also required. Note that RDS does not currently support X590 client certs for connecting.
This translates into minor application level code changes. In addition the SSL cert files will need to be stored on the application server.
Some documentation links:
- PHP – myssqli->ssl_set()
- Java – MySQL Connector/J JDBC Driver
- Python – MySQL Connector
- Ruby on Rails – Setting up Rails with MySQL SSL
- C# / .NET – MySQL Connector/NET
For more information: Using SSL with MySQL
Changes to GRANT statements:
MySQL supports a GRANT statement modifier ‘REQUIRE SSL‘ which will need to be applied to the application layer database accounts. This requires the appuser account to connect with SSL.
GRANT SELECT, INSERT, UPDATE, DELETE ON database.* TO 'appuser'@'appserver'IDENTIFIED BY '****' REQUIRE SSL;
Similarly to require the client to have a valid certificate, the ‘REQUIRE X509’ statement can be used:
GRANT SELECT, INSERT, UPDATE, DELETE ON database.* TO 'appuser'@'appserver'IDENTIFIED BY '****' REQUIRE X509;
Alternate Methods of Securing Data Transport:
Protecting data transport between the db server and the app server can also be done using ssh tunneling with something like autossh or a VPN. While ssh tunnels are a little ghetto, a VPN is really the best option. Both these approaches delegate the encryption to the network layer making it transparent to the application layer. This sort of work is handled by the dev ops / networking / sys admin team. Setting up a secured connection correctly so it is highly available takes skill and is not cheap. This is data security we are talking about, something to take very seriously!
With AWS RDS, ssh tunnels and a VPN are not feasible since MySQL is provided as a service. With RDS the underlying network and platform details are not accessible. It is not clear if the AWS Virtual Private Cloud (VPC) solution offers protection against traffic sniffing in relation to an EC2 app server connecting to an RDS database. With the 20% minimum performance hit from enabling SSL, that gives your team a lot to consider.
Why care about encrypting traffic between the app server the db server?
In many cases, the connection between the application server and the database server can be unencyrpted.
The most common starter case is an application connecting to localhost for its database. No need to worry about encryption there since everything is on the same box.
Going to a two tier or n-tier model where the application servers and the database servers reside on different hosts, the traffic may or may not need to be encrypted between them. If the hosts are all in the same rack sharing the same secured switch, or the traffic is on a trusted network, then there is no threat of packet sniffing.
This all changes the second you deploy to AWS or other cloud provider. Traffic between hosts goes across the cloud provider’s internal network. A cloud provider’s network is something you as a customer do not control, and in fact share with every other customer. When the underlying network is a shared resource, traffic sent between your servers should always be encrypted since you don’t know who might be listening.
It could be argued that unimportant data like system logs or metrics can be sent unencrypted. I agree, but it should be evaluated on a case by case basis. Customer names, email addresses, account numbers, or other personally identifying information (passwords?!) do end up in log messages from time to time.