Rails, SSL, Ubuntu, Apache2 with Phusion on Ubuntu

Here are all the commands for setting up your Rails application to server requests over SSL -on Ubuntu, of course.

There are great resources and tutorials at these websites.

http://www.tc.umn.edu/~brams006/selfsign.html

http://www.tc.umn.edu/~brams006/selfsign_ubuntu.html

https://help.ubuntu.com/7.10/server/C/httpd.html#https-configuration

The first thing, of course, is that you need OpenSSL installed.

apt-get install openssl

Once you have it installed, you can use this program to generate certificates. The generation process is interactive. It will prompt you for your name, company details, domain etc.  It will also prompt for a passphrase for your certificate. Remember this because you’ll be prompted for it when restarting your webserver. If your doing this to test things out, you can make stuff up. If you are doing this for real, and will eventually want to have a certificate authority (CA) validate your generated certs, this information needs to be accurate. This is the purpose of a CA, to validate the identity of companies using certificates!

openssl genrsa -des3 -out server.key 1024
openssl rsa -in server.key -out server.key.insecure
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

The program will output certificate files. I assumed you were in your home directory when you generated them. It doesn’t really matter where they are located, but for purposes of organization, let’s move them to a location that makes sense.

cp server.crt /etc/ssl/certs
cp server.key /etc/ssl/private

We’ll need to install two modules for apache to use Rails over SSL. If you don’t have them installed already, run  these commands.

sudo a2enmod ssl
sudo a2enmod headers

The headers module for apache lets us pass the https:// protocol to our Rails application so that it knows to use https.

The next step involves creating a VirtualHost that is listening on port 443. Port 443, is the standard port that https:// runs on.

#create your virtual host on port 443

NameVirtualHost *:443

<VirtualHost *:443>

  ServerName secure.example.com
  DocumentRoot /var/www/secure_website/public
  SSLEngine On
  RequestHeader set X_FORWARDED_PROTO "https"
  #***note*** some tuts mention the +CompatEnvVars options here... ignore it b/c it doesn't work
  SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
  #you'll recog these paths, where we stored the certs here
  SSLCertificateFile /etc/ssl/certs/server.crt
  SSLCertificateKeyFile /etc/ssl/private/server.key
  #force app into production mode...
  RailsEnv production
</VirtualHost>

You’ll also need to tell Apache to listen on port 443, if SSL module is loaded. This logic should be included out of the box. Take a look in /etc/apache2/ports.conf. If you don’t see Listen 443, wrapped in a conditional if mod statement… add Listen 443 to that file.

Force a complete reload of Apache so your certs and modules will be loaded.

/etc/init.d/apache2 force-reload
/etc/init.d/apache2 restart

You’ll want to restart your Rails application as well.

cd path/to/rails/root/app
#if using phusion passenger
touch tmp/restart.txt

Now visit your website https://my-ssl.example.railswebsite.com (or whatever it is) and confirm that it is working. You’ll be forced to add an exception to your browsers security checks for the domain that is running a self signed certificate. Add the exception and test out your Rails application.

  • am

    Thanks a lot! The point about enabling the headers mod in apache is not mentioned on almost any other how to site. Really good and to the point article to get it working !

  • Faisal

    Hi,
    I am first time doing apache settings and facing difficulties. Can you tell where we need to create “virtual host on port 443″? Also is there any need for passenger?

  • bseanvt

    Passenger is only necessary if you want to deploy Rails applications. It is a
    module for apache that loads the ruby interpreter. When a request comes in it
    ferries it to ruby/rails and your app does its work and hands back a response.

    There are other ways to deploy Rails (nginx, mongrel, unicorn… etc) but
    apache w/ passenger is one of the easiest. along with the advantage of being able to deploy
    php apps alongside rails apps too.

    If you are using Ubuntu then the apache configuration stuff is under

    /etc/apache2

    VirtualHost files go in the sites-available directory
    /etc/apache2/sites-available

    create a file there (you can name it anything and
    the extension doesn’t matter either)

    /etc/apache2/sites-available/my-website.conf

    you then have to symlink this file to the sites-enabled
    directory, also in /etc/apache2/, like so…

    ln -s /etc/sites-available/my-website.conf /etc/sites-enabled/my-website.conf

    the reason for this is it makes it easier to disable a site by
    removing the symlink rather than needing to either delete the file completely
    or commenting out the contents of the file. it’s a little confusing at first,
    but it is a great way to manage multiple sites.

    you can then edit the /etc/sites-available/my-website.conf file and add the virtual host directive to it.

    once you’ve made changes you have to reload apache with the command

    apache2ctl configtest (will tell you if there are any errors)
    apache2ctl restart ( run this if there are no errors)

  • bseanvt

    Creating a virtual host for serving secure traffic on port 443 with https. You have to have a security certificate (self signed or signed from a CA) in order for this to work. If you don’t and just want normal traffic it’s something like


    ServerName my-wesite.com
    DocumentRoot /var/www/my-website/public
    RailsEnv production

  • bseanvt

    oops… my code chars got stripped. here it is

    <VirtualHost *:80>
    ServerName my-wesite.com
    DocumentRoot /var/www/my-website/public
    RailsEnv production
    <VirtualHost>

  • Praveen Kumar Sinha

    :) it helped me.. easy and quick

    Thanks
    Praveen