Adding SSL to Ubuntu / Apache2 / Ruby on Rails

Thursday, August 27, 2009 3:39:51 PM (Pacific Daylight Time, UTC-07:00)
by Adam Brand
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/apache2 folder. 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 -l in 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:
<VirtualHost *:443>
  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
</VirtualHost>
…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.rb and 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_request or RAILS_ENV == ‘test’.

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