Mysql – Specify SSL for Heroku external MySQL database connection

herokumysqlruby-on-rails-3ssl

I'm running a Rails 3.2 app on the Cedar stack at Heroku.

I'm using Amazon RDS for my MySQL database, and I have the proper DATABASE_URL setup in the Heroku config vars.

How do I get Heroku to use SSL in its connection to Amazon RDS?

Normally this would be specified as a value in database.yml, but since Heroku generates database.yml for us, I'm not sure how to control this setting.

Thanks!

Best Solution

You can specify some mysql2 SSL params through the DATABASE_URL config. They will get added as items to the dynamic database.yml that is generated during the Heroku build process, and so they'll be passed when mysql2 connections are created.

The only param you need to pass for this to work is sslca (not to be confused with sslcapath).

1. Download the Amazon RDS CA certificate and bundle it with your app.

(Edit) Amazon will be rotating this certificate in March 2015. You'll need the new file from that page instead of this one.

curl https://s3.amazonaws.com/rds-downloads/mysql-ssl-ca-cert.pem > ./config/amazon-rds-ca-cert.pem

2. Add the file to git, and redeploy to Heroku.

3. Change DATABASE_URL to pass sslca:

heroku config:add DATABASE_URL="mysql2://username:password@hostname/dbname?sslca=config/amazon-rds-ca-cert.pem -a <app_id>

The relative path there is important—see below.

That's it! Now that you have SSL working, you may want to enforce that all connections with that user only allow SSL:

GRANT USAGE ON dbname.* TO 'username'@'%' REQUIRE SSL;

Troubleshooting

Make sure to pass a relative path to sslca! Otherwise, rake assets:precompile may break with an SSL error. If you receive an error like:

SSL connection error: ASN: bad other signature confirmation

or even just:

SSL connection error

...then there is likely something wrong with how the CA cert file is referenced.