Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to connect to Amazon RDS via SSL?

Tags:

I'm trying to set up an SSL connection to a MySQL database hosted via Amazon RDS. I'm confused as to how to connect.

According to Amazon's documentation, I need to download a CA certificate called "rds-ca-2015-root.pem" and use it in my SSL connection. I set the database user that I am connecting with to require SSL.

In PHP, I include the code below to initiate the connection:

$mysqli = mysqli_init();
mysqli_options($mysqli, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);
$mysqli->ssl_set(NULL, NULL, "/path/to/pem", NULL, NULL);
$mysqli->real_connect("host", "username", "password", "name", 3306, NULL, MYSQLI_CLIENT_SSL);

However, no matter which path I specify as the third parameter in ssl_set() (even if the path is invalid), an SSL connection is successfully established. The third parameter just can't be set to NULL.

I verify this by running this query: SHOW STATUS LIKE 'Ssl_cipher';. The output verifies that the connection is encrypted (Ssl_cipher => AES256-SHA).

Could someone please explain to me how this works? I am confused as to why the connection continues to work successfully when the path is incorrect. How is the RDS server being verified?

like image 790
Jack Humphries Avatar asked Aug 05 '15 05:08

Jack Humphries


People also ask

Does AWS RDS use SSL?

Amazon RDS for MySQL supports encrypted SSL/TLS connections to the database instances. Starting today, you can enforce SSL/TLS client connections to your RDS for MySQL database instance for enhanced transport layer security.

How do I get an RDS SSL certificate?

To get a certificate bundle that contains both the intermediate and root certificates, download from https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem.


2 Answers

The RDS documentation actually explains why this is happening, and suggests that you don't even need the CA cert:

Amazon RDS began updating the SSL certificates on all DB instances on March 23, 2015, but did not initiate a reboot of the instances. No operational impact or downtime is incurred when these updates are performed, and in many situations we will perform the update in your maintenance window. Amazon RDS will not update the certificate for your instances if you have already performed the update. Also note that Amazon RDS is not updating the certificates in AWS GovCloud (US) and the China (Beijing) regions.

Regardless of whether you manually update the certificate or Amazon RDS updated the certificate, the DB instance must be rebooted for the new certificate to take effect. You can decide when you want to manually reboot the DB instance, but you must update the certificate and reboot the instance before the old certificate (rds-ca-2010) expires on April 3, 2015.

You can check the certificate authority (CA) being used by your DB instance using the Amazon RDS console. The CA is listed under the Security and Network section of your DB instance details. If your instance shows rds-ca-2015, then the new certificate has been successfully applied. You still need to reboot your database instance and update your client application to use the new SSL certificate.

If the Amazon RDS console shows your instance CA as rds-ca-2010, then the new certificate has not been applied to your database instance yet. Use the instructions following to update the SSL certificate on your database instances.

The 3rd parameter is essentially being ignored by the client. I'm betting by setting the 3rd param to NULL, there is no point in calling mysqli::ssl_set() if all the params are null.

Try removing that function call altogether.

like image 122
Ian Avatar answered Sep 19 '22 12:09

Ian


As best I can tell - if you ask for or require an SSL connection to RDS MySQL you will get one - regardless of whether the local copy of the certificate is valid or readable.

I am using the following config in Drupal and regardless of where or what I put in the cert path I get an SSL connection:

$databases['default']['default'] = [
  'database' => 'drupal_db',
  'username' => 'db_user',
  'password' => 'db_password',
  'host' => 'hostname',
  'port' => '3306',
  'driver' => 'mysql',
  'prefix' => '',
  'pdo' => array(
      PDO::MYSQL_ATTR_SSL_CA => '/etc/ssl/certs/rds-combined-ca-bundle.pem',
      PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
  ),  
];

However, if I set the MYSQL_ATTR_SSL_VERIFY_SERVER_CERT value to "false" I get a connection error and Drupal fails. So far I have not been able to find any explanation of why this won't validate the certificate an/or how to make it successfully do so!

like image 32
bcaverly Avatar answered Sep 16 '22 12:09

bcaverly