Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable SSL for a standalone Sinatra app?

I want to write a quick server app in Sinatra. It has to be self-contained (i.e. not use apache/nginx/passenger) but also has to support SSL.

Is there an easy way to enable SSL support for Sinatra (using WEBRick for example)?

like image 220
Jacob Avatar asked Mar 02 '10 09:03

Jacob


2 Answers

To do this with MRI ruby, use the following monkeypatch:

sinatra_ssl.rb:

require 'webrick/https'

module Sinatra
  class Application
    def self.run!
      certificate_content = File.open(ssl_certificate).read
      key_content = File.open(ssl_key).read

      server_options = {
        :Host => bind,
        :Port => port,
        :SSLEnable => true,
        :SSLCertificate => OpenSSL::X509::Certificate.new(certificate_content),
        :SSLPrivateKey => OpenSSL::PKey::RSA.new(key_content)
      }

      Rack::Handler::WEBrick.run self, server_options do |server|
        [:INT, :TERM].each { |sig| trap(sig) { server.stop } }
        server.threaded = settings.threaded if server.respond_to? :threaded=
        set :running, true
      end
    end
  end
end

Then, in your standalone application:

app.rb

require 'sinatra'
require 'sinatra_ssl'

set :port, 8443
set :ssl_certificate, "server.crt"
set :ssl_key, "server.key"

get "/" do
  "Hello world!"
end
like image 85
Jacob Avatar answered Oct 28 '22 02:10

Jacob


Use JRuby interpreter + jetty-rackup gem (http://github.com/geekq/jetty-rackup) Edit jetty-rackup file in the jetty-rackup gem and add a SslSocketConnector, some code to help you:

    security_connector = Jetty::Security::SslSocketConnector.new
    security_connector.set_acceptors(config[:acceptor_size])
    security_connector.port = config[:port]
    security_connector.confidential_port = config[:port]
    security_connector.keystore = keystore
    security_connector.password = config[:password]
    security_connector.key_password = config[:key_password].nil? ? config[:password] : config[:key_password]
    security_connector.truststore = truststore
    security_connector.trust_password = config[:trust_pasword].nil? ? config[:password] : config[:trust_pasword]
    server.add_connector(security_connector)

Sample config:

# Config
:acceptor_size: 10
:ssl: true
:keystore: keystore.jks
:password: your_pass
# :key_password: your_pass # if different
# :truststore: truststore.jks # if different
# :trust_pasword: your_pass # if different

Generating keystore.jks : http://docs.codehaus.org/display/JETTY/How+to+configure+SSL

like image 30
clyfe Avatar answered Oct 28 '22 02:10

clyfe