Tuesday, January 12, 2010

Rails, Apache, Passenger, and SSL

I had a Ruby on Rails project that I wanted to test using SSL. This is how I configured it to work with SSL, Apache, Passenger, and my app.

You will need:
- OS X Snow Leopard
- Apache (the version that comes with Leopard is fine)
- Passenger
- the Passenger Pref Pane (optional, but useful)
- your application, running successfully locally. Your "application path" is your RAILS_ROOT here (i.e., the folder that contains app, config, etc.).

Note that this might work on other versions of OS X, or on other similar OSes, but I haven't tried it.

Install Prerequisites
This is just about getting the software you need. If you have any of these, just skip that step.
1. Install Passenger from here http://www.modrails.com/. Just download and follow the README.
2. Install the Passenger PrefPane from here: http://github.com/alloy/passengerpane or here http://www.fngtps.com/passenger-preference-pane. Just download and follow the README. Note that this is 32 bit, so when you access the prefpane, it will restart System Preferences in 32 bit mode. If this annoys you, skip this step. It's your choice whether you install this for just you (runs in user mode), or for everyone (needs an admin password to change configuration).
3. Your application can be running about anywhere. Make sure the full path to your RAILS_ROOT is world executable. For example, my application is in ~cpowell/projects/csh, so I ran the following in a terminal:
chmod o+x ~cpowell/projects/
You can see if this is right by doing
ls -l ~cpowell/projects/csh
and looking for this output:
CMP:~ cpowell$ ls -l ~cpowell/projects/
total 0
drwxr-xr-x 19 cpowell staff 646 Jan 10 20:34 csh

Add Your Application to Passenger and Apache
This will let Apache (with your Passenger) serve your application.
1. Open System Preferences
2. click on the Passenger icon. This will display a dialog that says "To use the "Passenger" preferences pane, System Preferences must quit and reopen." Click OK.
3. Click on the plus sign to add an application
4. In the address, you can call it basically whatever you like. I use the .local ending just because that's an easy Mac convention. In my case, I called it csh.local
5. Put the path to your Rails project in the Folder. In my case, it's ~cpowell/projects/csh.
6. Choose development or production config. This one is purely up to you; I use development because I'm just testing, but you can choose production if you prefer.
7. In the main System Preferences page, click Sharing, and then select "Web Sharing". This is what OS X calls Apache.
8. Select the Web Sharing checkbox to start Apache.

At this point you should be able to open a browser and go to http://csh.local and see your application. (Substitute the address you chose, of course.)

Configure SSL
Once you have this running, we can add SSL support, if we need it.
Add an SSL vhost to your passenger config.
1. Open your passenger apache config. It's probably in /etc/apache2/passenger_pane_vhosts/csh.local.vhost.conf (substitute your application name). You'll need sudo for this. It will have a virtual host entry for port 80.
2. Add a virtual host for port 443 that looks like this. Note the paths to your application, to your certificates, and to the ssl log. All those paths should exist.
ServerName cloudswitch-home.local
DocumentRoot "/Users/cpowell/projects/csh/public"
RailsEnv development
Order allow,deny
Allow from all
Order allow,deny
Allow from all
SSLEngine on
SSLProtocol all -SSLv2
SSLCertificateFile /Users/cpowell/projects/csh/server.crt
SSLCertificateKeyFile /Users/cpowell/projects/csh/server.key
SSLVerifyClient optional_no_ca
SSLOptions +ExportCertData
SSLOptions +StdEnvVars
SSLOptions +StdEnvVars
SetEnvIf User-Agent ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog /var/log/apache2/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
3. Generate a self-signed certificate according to these instructions (http://www.tc.umn.edu/~brams006/selfsign.html). Use section 1A or 1B, your call.
4. Put those generated certificates and key in the locations you indicated in your passenger vhost.
5. Enable SSL in Apache by uncommenting this line:
Include /private/etc/apache2/extra/httpd-ssl.conf
6. In the /private/etc/apache2/extra/httpd-ssl.conf file, get rid of the vhost for port 443. We have to do this because otherwise it will conflict with the port 443 vhost we just set up in the passenger config. To do this, get rid of everything below:
## SSL Virtual Host Context
7. restart apache

Note that if you have difficulties here, check out the logs in /var/log/apache2 to help troubleshoot.

Try It
Open a browser and go to https://csh.local. You should see your application.


  1. Followed instructions, but apache not starting unless I remove "Order allow, deny and Allow for all". If I remove these lines apache starts but no https.

    Please help

  2. pcasa, send over your logs with and without the error and I'll be happy to take a look. Send them to catherine at abakas (the blog domain).

  3. Nice article, helped me a lot :-)

  4. Thanks for the clear and concise instructions--this really helped!