Setting up SSL for rails (and testing it on your mac) 3
I recently had to set up SSL for a Ruby on Rails app, and I thought I’d document my findings for the benefit of mankind… :-)
Actually configuring SSL on a production apache/mongrel ubuntu server is quite easy. Our rails-specialist hosts, Brightbox, have some excellent instructions on their wiki.
To get SSL working with rails, you need the ssl_requirement plugin. The readme file for this plugin is pretty self-explanatory, but here’s how to get started.
Install the plugin.
ruby script/plugin install ssl_requirementThen, near the top of your application controller, add the line:
include SslRequirementIn the application controller, you might also want to override the ssl_required? method, to make life easier in development mode or testing, and to apply some application-specific logic. (Note that if your SSL logic is dependent on other action-filters, you need to put the include line, above, after those filters). Here’s a simple example:
def ssl_required?
# (Comment this one line out if you want to test ssl locally)
return false if local_request?
# always return false for tests
return false if RAILS_ENV == 'test'
# some logic to see if we need ssl, for example:
if check_pricing_plan_feature("SSL")
return true
end
# otherwise, use the filters.
super
endNow in your individual controllers, you can add filters defining which actions need ssl. (If an action is defined as ‘ssl_required’, then you will be redirected to an ‘https’ version of the page). You can also use ‘ssl_allowed’ if the action can be used with OR without ssl.
ssl_required :log_in, :profileNow, the code I’ve included in the ‘ssl_required?’ override above lets you test locally without using SSL. But how can you be sure if it’s working properly before deploying? As Mike Subelsky wisely says, you need to “train like you fight”.
If you’re on a Mac, here’s how to test ssl ‘for real’:
1. Make sure you’ve got apache 2.x installed.
OS X Leopard comes with 2.2.8 I think. To find out, just run
httpd -v If you’ve got an older version than 2.0, you can get the latest from the apache site.
2. Create self-signed certificates.
Download (but don’t install) the latest version of mod_ssl (I used 2.8.31) – you’ll need a file from this download for the instructions below…
Follow the instructions on the apple site to create a self-signed cert. (The actual steps to perform only start under the heading “Configuring SSL”).
Note: When it talks about your /etc/httpd directory, use /etc/apache2 instead.
Stop following the instructions when it starts talking about stopping your apache server: (”...Stop your web server if you haven’t already, either by using the Sharing control panel or through the command line…”).
3. Configure apache.
i. Change to the apache configuration folder
cd /etc/apache2ii. Now edit your httpd.conf file:
sudo pico httpd.confiii. Find the Line that says “Listen 80” (around line 41), and below it add the lines:
Listen 443
SSLCertificateFile /etc/apache2/ssl.key/server.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/server.key(using the relevant paths to your new certificates)
iv. Find the<IfModule log_config_module>CustomLog /private/var/log/apache2/ssl_request_log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"(this isn’t strictly required but as Mike Subelsky suggested, it helps with debugging the apache setup)
v. Go to the bottom of the file and add the following just above the “
<VirtualHost *:80>
ServerName 127.0.0.1
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000
ProxyPreserveHost on
DocumentRoot "/users/me/documents/myproject/public"
</VirtualHost>
<VirtualHost *:443>
SSLEngine On
ServerName 127.0.0.1
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000
ProxyPreserveHost on
RequestHeader set X_FORWARDED_PROTO 'https'
DocumentRoot "/users/me/documents/myproject/public"
</VirtualHost>- the ServerName must be the servername for which you created the cert
- change the DocumentRoot to wherever your rails development environment lives.
4. Configure Rails.
Comment out the line in the application_controller (added earlier) that says:
return false if local_request?so you can test ssl conditions locally.
5. Start apache
You can start and stop apache with:
sudo httpd -k startand
sudo httpd -k stoprespectively.
... and you’re all set to enjoy SSL goodness on your mac.
Trackbacks
Use the following link to trackback from your own site:
http://www.ricroberts.com/trackbacks?article_id=setting-up-ssl-for-rails-and-testing-it-locally&day=25&month=09&year=2008
I'm Richard Roberts, a developer in the UK working with Ruby on Rails. I'm a founder of: 

i love you. thanks!
Good tutorial!
You may want to add a retry value to the ProxyPass lines, like:
ProxyPass / http://localhost:3000/ retry=0Otherwise apache will likely fail to connect to the rails-process for some time (default 30sec?) when you restart your webrick/mongrel..
oh, and another one:
while creating the the certificate and in the apache-modifications, replace 127.0.0.1 with rails.test put the following line into /etc/hosts:
In /etc/apache2/httpd.conf put the following lines before the two VirtualHost-Blocks already added:127.0.0.1 rails.testThis will cause apache to point to it’s default configuration and not use the two virtual-hosts if you don’t use rails.test as url. So you can still use your other stuff here (stinky PHP
CMS your Boss forces you to write plugins for ;)Optionally: Put http://rails.test/ as very first bookmark in your Safari Bookmarks Bar and hit CMD-1 to acess it quickly