Configuring WEBrick to use SSL in Rails 3

| | Comments (14) | TrackBacks (0)

The other day my project took on the task of upgrading our (fairly new) rails application from Rails 2.3.5 to Rails 3. Everything was going great until we got to the part of actually trying to run our application under WEBrick.

Our application has some services that it connects to that require secure connections so in order to comply and still develop we had modified the WEBrick configuration under 2.3.5 to make it run under SSL. This turned out to be very easy to accomplish with 2.3.5, we just cracked open the script/server file and added the appropriate SSL options that WEBrick already knows about.

Rails 3 proved to be a little bit more difficult to modify. This is due to the fact that the script folder only contains a rails script now and all of the old scripts are now contained deep in the rails build. I didn’t really want to crack open rails and start modifying (especially not when it is only for development), so I was looking for another option. I spent a few days searching the internet with no luck. Today I came into work and after 6+ hours and some pair programming a solution was figured out. You can find the solution that we came up with below, and if there is a more elegant solution out there I would love to hear about it.

All you have to do to get WEBrick running in SSL is modify the script/rails file and add the following lines (above the APP_PATH variable declaration):

require 'rubygems'
require 'rails/commands/server'
require 'rack'
require 'webrick'
require 'webrick/https'

module Rails
    class Server < ::Rack::Server
        def default_options
            super.merge({
                :Port => 3000,
                :environment => (ENV['RAILS_ENV'] || "development").dup,
                :daemonize => false,
                :debugger => false,
                :pid => File.expand_path("tmp/pids/server.pid"),
                :config => File.expand_path("config.ru"),
                :SSLEnable => true,
                :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
                :SSLPrivateKey => OpenSSL::PKey::RSA.new(
                       File.open("path/to/key").read),
                :SSLCertificate => OpenSSL::X509::Certificate.new(
                       File.open("/path/to/crt").read),
                :SSLCertName => [["CN", WEBrick::Utils::getservername]]
            })
        end
    end
end

14 Comments

Thanks a lot, that worked! Just saved me these hours of experimentation :)

Ricky Nelson said:

Chris, were you able to get this to work for both https and http queries? It seems to only accept https queries for me using your script. When I send http queries I get an error:

[2011-02-08 08:45:11] ERROR OpenSSL::SSL::SSLError: SSL_accept returned=1 errno=0 state=SSLv2/v3 read client hello A: http request
/usr/local/Cellar/ruby/1.9.2-p136/lib/ruby/1.9.1/openssl/ssl-internal.rb:164:in `accept'

But it works just fine for https queries. I'm on OS X 10.6.6 with rails v3.0.3 and ruby v1.9.2p136.

Chris Rohr Author Profile Page said:

Evgeniy, Glad I could help!

Chris Rohr Author Profile Page said:

Ricky,

I have not tried this with both due to the fact that our entire system was https. However, I can try to take a look and see if I can get it working. If you happen to find a solution please let me know as well. I'm sure that I just have it set to do one or the other not both.

Kunjan said:

Hi,

Can you tell me the file name where you are referring script/rails file? And what modifications required in that file?

And in which file APP_PATH variable is declared?

I am new to Rails so please guide me in right direction.

Your answer is very important for me.

Thanks,

Chris Rohr Author Profile Page said:

Kunjan,

The file name is rails and it is in the script folder under your main project (This is only for Rails 3). In that file you will see the APP_PATH variable defined. Just copy and paste the code in the post above that declaration. You will need to replace the "/path/to/key" and "/path/to/crt" with the actual paths to those files for your application.

Hope this helps,
Chris

Neeti said:

Chris, Could you pls. post/mail me the server script that you were using with Rails 2.3.5? I have to use SSL with Rails 2.3.8 app and I cant possibly upgrade to Rails 3 at this point of time. Would appreciate your help.
Thanks

Alan said:

Anyone ever figure out the dual http/https version of this? I'm in the same boat as Ricky above and really need both protocols for development ... Appreciate any help.

Chris Rohr Author Profile Page said:

Alan, I think if you can figure out how to run WEBrick on multiple ports then you can configure each port to be either SSL or not. I haven't been able to find a way to run WEBrick that way.

Alan said:

That's just what I've done.

I call your modified script rails_ssl and launch it on port 3001 alongside a default WEBrick on 3000. Took some monkey patching of ssl_requirement but I think I've got the setup I need now.

Thanks.

Taylor said:

Chris,

Any ideas on how to specify an intermediate certificate? I can't seem to find a listing of options for WEBrick or Rack.

Thanks.

Taylor said:

You found my post :) Maybe it will help the next person.

Leave a comment

0 TrackBacks

Listed below are links to blogs that reference this entry: Configuring WEBrick to use SSL in Rails 3.

TrackBack URL for this entry: http://www.nearinfinity.com/mt/mt-tb.cgi/1608