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!