What are the steps you need to take to set up SSL on a Ruby on Rails app that is hosted on Apache2/Ubuntu?
NOTE: I moved this from a previous mistaken "community wiki" post.
The other day I was asked by some of our Rails devs to enable SSL on an application.
There are many sources on Google for configuring SSL with Ubuntu and Apache, and some on Rails, and a few with Ubuntu/Apache/Rails, but I wasn't able to find one that I feel was straightforward and comprehensive.
So after spending a bit of time figuring out the exact combination of steps needed to get SSL working on this popular configuration, I decided to make a ServerFault entry on how to get SSL going in your Rails app on Apache2 / Ubuntu.
Feel free to edit/add/comment based on your experiences!
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.
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.
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
RAILS_ENV == ‘test’.
That’s it! Hope this saves someone else some web research!