Running HTTPS in your Rails Development Environment

Posted by mhagedorn on September 29th, 2009 filed in Rails

If you are building a rails application that requires SSL for parts of your site, you are probably going to use the SSL requirement plugin. But that alone isn’t going to allow you to run your code in development. You can easily see this after you enable the SSL Requirement plugin (suddenly nothing will work). Your single mongrel instance is going to need some help in order to be able process https requests! I wanted a simple way to allow my rails development process to continue normally and still have https protected code.

Its not hard to set this up (ok its a bit tedious), but as Mike Subelsky noted in his blog post, its not really written up elsewhere in one compact recipe. I wanted to take a slightly different approach than what Mike took, in that I wanted to disturb the default OSX install as little as possible. Since OSX includes an apache webserver, the idea is that you have that webserver proxy all the SSL details and then pass off control to your development instance running on localhost:3000. The built-in instance of apache can be turned on and off in OSX by going to the Sharing control panel in your System Preferences. If you mark the checkbox named “Web Sharing” apache is on and running, and off if the checkbox is off. You can verify this by turning it on then browsing to http://localhost, you should see an apache screen.

Step 1 – Configuring SSL Encryption

Note that this recipe is a condensed version of what is found here, but I have cut out all the commentary. You will be using terminal for all the rest of this. Also I am using OSX Leopard * Shut down your local apache server either turn off web sharing or

sudo apachectl stop
  • Create a Working Directory

    mkdir ~/Desktop/KeyGen; cd ~/Desktop/Keygen

  • Create the RSA private key

    openssl genrsa -des3 -out server.key 1024

use a passphrase here as directed (and remember it :) )

  • Create the CSR (Certificate Signing Request)

    openssl req -new -key server.key -out server.csr

This signing request you will sign yourself (for development only of course). For this CSR enter ’127.0.0.1′ for the prompted “Common Name – i.e. for the appropriate server”

  • Create a Certificate Authority (CA) to sign the key

    openssl genrsa -des3 -out ca.key 1024
    

use a passphrase here again

  • Create a self-signed CA certificate using the key you just made

    openssl req -new -x509 -days 365 -key ca.key -out ca.crt

in the “Common Name” field enter your name, because you are the dummy certificate authority and you are the one signing it.

  • Download the latest mod_ssl distribution It can be found here. Look in the pkg.contrib subdirectory and copy the file sign.sh to your working directory. Then you have to make the file executable, and sign the csr.

    chmod +x sign.sh ;./sign.sh server.csr

Enter ‘yes’ for all the prompts, and you will have a directory full of files, representing the signed csr.

  • Put the signed files where apache can use them

    sudo mkdir /etc/apache2/ssl.key

Move all of the contents of your working directory to the ssl.key directory you just made.

sudo cp -r * /etc/apache2/ssl.key/
  • Remove the passphrase from the server key (DONT DO THIS FOR A PRODUCTION SYSTEM)

    cd /etc/httpd/ssl.key
    sudo cp server.key server.key.original
    sudo openssl rsa -in server.key.original -out server.key
    

Step 2 – Modify the Apache config files

  • First, back up the existing apache config file for safety

    cd /etc/apache2 sudo cp httpd.conf httpd.conf.backup

  • Then use your favorite editor to enable the appropriate LoadModule statements. (you are going to have to use sudo (‘sudo vi’) to open this file in order to save it). Search for a line that looks like this:

    LoadModule sslmodule libexec/apache2/modssl.so

and make sure that the # at the beginning of the line is not there (i.e. the comment indication), if it is there remove it. Likewise remove # from this line a bit farther down

Include /private/etc/apache2/extra/httpd-vhosts.conf

and this…

Include /private/etc/apache2/extra/httpd-ssl.conf
  • Back up your extra/httpd-ssl.conf

    sudo cp httpd-ssl.conf httpd-ssl.conf.original

  • Comment out the following line by putting a # at the beginning of it (we are putting this setting in the httpd-vhosts.conf file)

    Listen 443

  • Remove the Virtual Host

Then remove all the lines starting at

    <VirtualHost _default_:443>

and ending at

    </VirtualHost> 

We are going to define all our virtual host stuff in the httpd-vhosts.conf file, so its not needed here.

  • Back up your extra/httpd-vhosts.conf and edit it

    sudo cp httpd-vhosts.conf httpd-vhosts.conf.original

I pretty much deleted everything in my vhosts file and replaced it with the following content

Listen 443

SSLCertificateFile /etc/apache2/ssl.key/server.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/server.key

CustomLog logs/ssl_request_log  "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

<VirtualHost *:80>
 ServerName localhost
 ServerAlias 127.0.0.1

 ProxyPass / http://localhost:3000/
 ProxyPassReverse / http://localhost:3000
 ProxyPreserveHost on
</VirtualHost>

<VirtualHost *:443>
 SSLEngine On
 ServerName localhost
 ServerAlias 127.0.0.1

 ProxyPass / http://localhost:3000/
 ProxyPassReverse / http://localhost:3000
 ProxyPreserveHost on
 RequestHeader set X_FORWARDED_PROTO 'https'
</VirtualHost>

And thats it. Go to your Sharing control panel and turn on Web Sharing. You should see https requests being forwarded correctly to your rails application (assuming that its listening on the default mongrel port of 3000).


3 Responses to “Running HTTPS in your Rails Development Environment”

  1. mtstalker Says:

    In the last part under Step 1, I believe “cd /etc/httpd/ssl.key” should be “cd /etc/apache2/ssl.key”

    Also, in the first part under Step 2, my Apache httpd.conf file reads, “LoadModule sslmodule libexec/apache2/modssl.so”

    Thanks for posting this! I can’t quite get it to forward https requests to my Rails app, but I’ll keep trying.

  2. estoner Says:

    The CustomLog line in httpd-vhosts.conf causes Apache to die without much in the way of helpful errors, at least with a fairly stock Snow Leopard install.

    I recommend changing the CustomLog path from logs/sslrequest.log to /var/log/apache2/sslrequest_log.

  3. estoner Says:

    Excellent guide, BTW.

Leave a Comment

You must be logged in to post a comment.