KB: WEBrick SSL Configuration

WEBrick SSL Configuration

Contents

Overview

This article assumes that you are working with an existing Ruby on Rails application and that you will be using a self-signed certificate.

Create a Self-signed Certificate

1. In a directory of your choosing, create an RSA Private Key:

openssl genrsa -des3 -out server.key 1024

2. Create a certificate signing request (CSR):

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

3. Remove the passphrase:


cp server.key server.key.org
openssl rsa -in server.key.org -out server.key

4. Create the self-signed certificate, follow the prompts and remember to set the CN to “localhost”:

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Install the Private Key and Certificate

1. In your Rails application under the config directory, add a new directory named certs:

mkdir /home/krdavis/projects/openeprs/config/certs

2. Copy the private key and certificate to the new certs directory:


cp server.crt /home/krdavis/projects/openeprs/config/certs
cp server.key /home/krdavis/projects/openeprs/config/certs

Create a Secure Server Script

The following code does not modify script/server. The secure server code will be placed in script/server_secure. This can be useful if secure and non-secure instances of WEBrick need to be run simultaneously e.g. to verify redirects when using the ssl_requirement plugin.

This configuration uses a self-signed certificate. This means the first time a browser accesses the application at https://localhost:3001, an invalid certificate error will be raised. A certificate exception can be added via the browser to suppress this message.

Create script/server_secure:


#!/usr/bin/env ruby

require File.dirname(__FILE__) + '/../config/boot'

require 'webrick'
require 'webrick/https'

puts "=> Booting WEBrick..."

OPTIONS = {
  :port         => 3001,
  :ip           => "127.0.0.1",
  :environment  => (ENV['RAILS_ENV'] || "development").dup,
  :server_root  => File.expand_path(RAILS_ROOT + "/public/"),
  :pkey         => OpenSSL::PKey::RSA.new(
                      File.open(RAILS_ROOT + "/config/certs/server.key").read),
  :cert         => OpenSSL::X509::Certificate.new(
                      File.open(RAILS_ROOT + "/config/certs/server.crt").read),
  :server_type  => WEBrick::SimpleServer,
  :charset      => "UTF-8",
  :mime_types   => WEBrick::HTTPUtils::DefaultMimeTypes,
  :debugger     => false
}

ENV["RAILS_ENV"] = OPTIONS[:environment]
RAILS_ENV.replace(OPTIONS[:environment]) if defined?(RAILS_ENV)

require RAILS_ROOT + "/config/environment"
require 'webrick_server'
OPTIONS['working_directory'] = File.expand_path(RAILS_ROOT)

class SSLDispatchServlet < DispatchServlet
  def self.dispatch(options)
    Socket.do_not_reverse_lookup = true
    server = WEBrick::HTTPServer.new(
      :Port             => options[:port].to_i,
      :ServerType       => options[:server_type],
      :BindAddress      => options[:ip],
      :SSLEnable        => true,
      :SSLVerifyClient  => OpenSSL::SSL::VERIFY_NONE,
      :SSLCertificate   => options[:cert],
      :SSLPrivateKey    => options[:pkey],
      :SSLCertName      => [ [ "CN", WEBrick::Utils::getservername ] ]
    )

    server.mount('/', DispatchServlet, options)
    trap("INT") { server.shutdown }

    server.start
  end
end

puts "=> Rails application started on https://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
puts "=> Ctrl-C to shutdown"

SSLDispatchServlet.dispatch(OPTIONS)

Note: In OPTIONS, :pkey and :cert point to the private key and certificate that were created earlier and copied to config/certs.

Start the SSL enabled WEBrick by running the following command from the root of the Rails application:

script/server_secure

which will produce the following output:


=> Booting WEBrick...
=> Rails application started on https://127.0.0.1:3001
=> Ctrl-C to shutdown
[2008-12-25 16:25:17] INFO  WEBrick 1.3.1
[2008-12-25 16:25:17] INFO  ruby 1.8.7 (2008-08-11) [i686-linux]
[2008-12-25 16:25:17] INFO  
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            ca:11:ce:7e:d0:88:3d:d1
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=US, ST=MT, L=Billings, O=ZuniSoft, OU=Development, CN=localhost/emailAddress=info@zunisoft.com
        Validity
            Not Before: Dec 13 17:06:43 2008 GMT
            Not After : Dec 12 17:06:43 2013 GMT
        Subject: C=US, ST=MT, L=Billings, O=ZuniSoft, OU=Development, CN=localhost/emailAddress=info@zunisoft.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:b2:62:67:f8:99:f8:a7:a8:ae:0c:25:fe:c7:71:
                    91:b2:de:49:1c:97:02:7f:24:fa:27:bf:f1:90:72:
                    4b:85:15:90:75:8e:21:a0:28:f8:ba:60:28:22:91:
                    33:8c:c9:8d:9a:d9:2d:5f:af:d7:5f:d4:a7:fa:da:
                    ca:c2:b1:8e:cb:c6:14:9a:41:1e:fc:79:bf:b0:57:
                    52:8e:a7:82:4f:2b:4c:6a:02:c0:94:cc:db:58:ac:
                    47:6e:3d:d9:52:95:64:72:50:b3:67:7c:af:d2:f0:
                    3f:fb:c8:2b:b0:5d:81:21:7e:3c:23:88:a4:08:6e:
                    f8:09:c8:bc:6e:37:e8:6e:c3
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha1WithRSAEncryption
        82:5e:f7:a7:e8:1d:58:08:d3:0a:c3:77:d0:b5:ce:12:ef:97:
        16:1e:c5:00:8c:a0:5b:9a:0f:a9:39:90:8d:2b:bf:97:bb:a3:
        09:2c:df:68:dd:84:e0:15:72:67:f8:95:9b:08:11:67:34:d9:
        01:33:b9:53:ce:d4:b7:d1:e8:64:b5:3d:9c:f8:7f:69:ec:50:
        aa:67:e2:cb:87:26:49:28:de:27:b6:09:0b:cc:f6:15:8d:9c:
        7d:03:ad:f1:80:41:b8:53:6c:a3:d0:28:8c:ab:dd:78:3a:ce:
        70:42:f1:08:79:40:3a:16:9d:0c:aa:d6:04:a0:09:6c:8e:c7:
        ff:95
[2008-12-25 16:25:17] INFO  WEBrick::HTTPServer#start: pid=2393 port=3001

To Top

Please follow and like us:

6 Replies to “KB: WEBrick SSL Configuration”

  1. Never miiiinnnnnddd. Figured it out. In definition of OPTIONS :environment i needed to change 'development' to 'production'. Thanks anyway. You might leave the solution there for the next noobie to fall for that.

  2. The above almost works perfectly. Here's my situation now after implementing the cert setup and using script above:

    Works fine on my development machine using https, where the host is 'localhost' (port 3001). On the application server, however, https port 3001, i get the message below. It is connecting because the public/index.html comes up fine using https (port 3001). But the access to the controller gives:

    x.x.66.67 – – [04/Mar/2010:17:28:43 MST] "GET /tags HTTP/1.1" 500 948
    https://x.x.x.x:3001/ -> /tags

    'tags' is the name of my model, the request for this error is
    https://x.x.x.x:3001/tags

    Any ideas? I'm guesing the redirect to/from the login is using http, and that's where the internal server error is coming from, but i really don't know.

Leave a Reply

Your email address will not be published. Required fields are marked *