August 27, 2009

Adding SSL to Ubuntu / Apache2 / Ruby on Rails

There are many sources on Google for configuring SSL with Ubuntu, Apache2, and Ruby on Rails, but there isn’t one that I feel is straightforward and comprehensive. So here is the skinny on how to get SSL going in your Rails app on Apache 2 / Ubuntu.

For this case, we are assuming you are getting a certificate from GoDaddy (not a self-signed cert), but you can get your cert from any certificate authority and the steps should be the same.

I’ll use www.yourdomain.com as the example domain we want to secure.

NOTE: The blog column width has wrapped some of the command lines, so be mindful of
that.

Set Up Your Cert Directory

There are four crypto-related files for SSL that need a home: 1) the CSR (you send
to GoDaddy), 2) the private key (which you keep), 3) the actual cert sent to you by
GoDaddy, and 4) the intermediate certificate (GoDaddy will send you).
If you have Ubuntu, you probably have an /etc/apache2folder.
So create a folder in there called ssl.

Create Your Private Key

You need openssl for this, so first do:

sudo apt-get install openssl

Then you actually make your private key, like this:

sudo openssl genrsa -des3 -out www.yourdomain.com.key
1024

It will ask you for a password. You’ll remove this later but for now
just type something you will remember. This key you will keep locally (don’t send
it to GoDaddy).

Create Your CSR

This is the file you’ll actually send to GoDaddy to get your certificate:

sudo openssl req -new -key www.yourdomain.com.key
-out www.yourdomain.com.csr

Get Your Cert and Intermediate Cert

Now you go through Godaddy’s (or your certificate authority’s) process for getting
your certificate and their intermediate certificate. You’ll send them your CSR to
get these. Drop them in your /etc/apache2/ssl folder.

Remove the Password from Your Private Key

This step is optional, but if you don’t do it Apache won’t start automatically on
reboot (it will prompt for a password).

sudo mv www.yourdomain.com.key www.yourdomain.com.passkey

sudo openssl rsa -in www.yourdomain.com.passkey -out www.yourdomain.com.key

 

Set Appropriate Permissions on Your Key Files

You don’t want random people to snag your keys. At this point if you do an ls
-lin the /etc/apache2/ssl folder you should
see that the files are owned by root. Now we just need to change the permissions so
only root can read them:

sudo chmod 400 /etc/apache2/ssl/*

Prep Apache by Installing Mods

Your Apache install probably doesn’t have mod_ssl or mod_headers installed, so you
will need to do:

sudo a2enmod ssl

sudo a2enmod headers

Adjust Site Config File in Apache

Assuming your site is already operational with http, you should have a config file
already under /etc/apache2/sites-available (like default). Edit that file so that
it looks like:

lt;VirtualHost *:443gt;

ServerName www.yourdomain.com

ServerAlias www.yourdomain.com

DocumentRoot /var/apps/yourapp/public

SSLEngine On

SSLCertificateFile /etc/apache2/ssl/www.yourdomain.com.crt

SSLCertificateKeyFile /etc/apache2/ssl/www.yourdomain.com.key

SSLCertificateChainFile /etc/apache2/ssl/gd_bundle.crt

#For RoR “Mongrel”

RequestHeader set X-Forwarded-Proto “https”

#Hack for IE

SetEnvIf User-Agent “.*MSIE.*” nokeepalive ssl-unclean-shutdown

lt;/VirtualHostgt;

…you of course will need to put in your domain where applicable and also
put the name of your key files in there as well.

Restart Apache

These changes don’t take effect until you restart apache, so do:

sudo /etc/init.d/apache2 restart

Adjust Your Rails App

Now we need to adjust your rails app so that it supports SSL. Edit your /app/controllers/application_controller.rband
add this at the bottom:

def ssl_required?

true

end

 

If you wanted to get fancy, you could add in some code there
to return false if local_requestor RAILS_ENV
== ‘test’.

That’s it! Hope this saves someone else some web research!