1. Generate your server.crt and server.key first.

For local development, a self-signed certificate is adequate. For production, we can buy from Thawte, Verisign, the CArtels, etc.

% openssl genrsa -des3 -out server.key 1024
% openssl req -new -key server.key -out server.csr
% openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Notes: Ensure that you use x509 because if we use the other one (PK something), then apache2 complains that it can’t load it, invalid tags.

The certificate (server.crt) should have the proper tags (BEGIN and END) as shown below.

-----BEGIN CERTIFICATE-----
MIIDBjCCAe4CCQDCzcL5z8chBzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
......+OAFfG2MvIeawg==
-----END CERTIFICATE-----

2. Setup your Apache2 properly

– Ensure that you have mod_ssl loaded

LoadModule ssl_module libexec/apache22/mod_ssl.so

– Enusure that you are listening to 80 and 443.

Listen 80
Listen 443

Very Important Note: Please note that if you are not listening to these ports you might get “Connection Refused” messages. Please make sure that your Listen directives match your directives.

<VirtualHost 192.168.10.1:80>
   ServerAdmin rupert@2rmobile.com
   ServerName foo.2rmobile.com
   ServerAlias foo.2rmobile.com
 
   DocumentRoot "/path/to/rails/app/public"
   <Directory "/path/to/rails/app/public">
      #Options Indexes MultiViews
      AllowOverride None
      Order allow,deny
      Allow from all
   </Directory>
 
   CustomLog /var/log/httpd/myapp.log combinedio
   LogLevel warn
</VirtualHost>
 
<VirtualHost 192.168.10.1:443>
   ServerAdmin rupert@2rmobile.com
   ServerName foo.2rmobile.com
   ServerAlias foo.2rmobile.com
 
   DocumentRoot "/path/to/rails/app/public"
   <Directory "/path/to/rails/app/public">
      #Options Indexes MultiViews
      AllowOverride None
      Order allow,deny
      Allow from all
   </Directory>
 
   CustomLog /var/log/httpd/myapp.log combinedio
   LogLevel warn
 
   SSLEngine on
   SSLCertificateFile /path/to/certs/server.crt
   SSLCertificateKeyFile /path/to/certs/server.key
</VirtualHost>

Restart! Hopefully, apache2 will load with ssl support. If not, do some googling.

% /usr/local/etc/rc.d/apache22 restart #freebsd
Performing sanity check on apache22 configuration:
Syntax OK
Stopping apache22.
Waiting for PIDS: 89044.
Performing sanity check on apache22 configuration:
Syntax OK
Starting apache22.
% tail -f /var/log/apache2/httpd-access.log
...."Apache/2.2.15 (FreeBSD) mod_ssl/2.2.15 OpenSSL/0.9.8q DAV/2 PHP/5.2.14 with Suhosin-Patch Phusion_Passenger/3.0.11 (internal dummy connection)"

3. Configure Rails3.0.10 for rack/ssl support.
Read this http://collectiveidea.com/blog/archives/2010/11/29/ssl-with-rails/. If you’re on Rails3.1? you didn’t read this http://collectiveidea.com/blog/archives/2010/11/29/ssl-with-rails/..

Gemfile

gem 'rack-ssl', :require => 'rack/ssl'

production.rb

require 'rack/ssl'
 
Cws::Application.configure do
  config.middleware.insert_before ActionDispatch::Cookies, Rack::SSL
  #config.middleware.insert_before ActionDispatch::Cookies, Rack::SSL, :exclude => proc { |env| env['HTTPS'] != 'on' }
 
  # Settings specified here will take precedence over those in config/application.rb
 
  # The production environment is meant for finished, "live" apps.
  # Code is not reloaded between requests
  config.cache_classes = true
 
  # Full error reports are disabled and caching is turned on
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true
 
  # Specifies the header that your server uses for sending files
  config.action_dispatch.x_sendfile_header = "X-Sendfile"
 
  # For nginx:
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
 
  # If you have no front-end server that supports something like X-Sendfile,
  # just comment this out and Rails will serve the files
 
  # See everything in the log (default is :info)
  # config.log_level = :debug
 
  # Use a different logger for distributed setups
  # config.logger = SyslogLogger.new
 
  # Use a different cache store in production
  # config.cache_store = :mem_cache_store
 
  # Disable Rails's static asset server
  # In production, Apache or nginx will already do this
  config.serve_static_assets = false
 
  # Enable serving of images, stylesheets, and javascripts from an asset server
  # config.action_controller.asset_host = "http://assets.example.com"
 
  # Disable delivery errors, bad email addresses will be ignored
  # config.action_mailer.raise_delivery_errors = false
 
  # Enable threaded mode
  # config.threadsafe!
 
  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation can not be found)
  config.i18n.fallbacks = true
 
  # Send deprecation notices to registered listeners
  config.active_support.deprecation = :notify
 
  config.action_mailer.default_url_options = { :host => 'whatever' }
end

If you want to have http and https working on both sites, then you can use

config.middleware.insert_before ActionDispatch::Cookies, Rack::SSL, :exclude => proc { |env| env['HTTPS'] != 'on' }

4. Test time!
– On Safari, ensure you blow away your cache.

Safari > Reset
Safari > Empty Cache

If you go to your http://server.website.com/ then it should redirect https://server.website.com/

Note:
– If you see a “Connection Refused” or ERROR bad URI or ERROR bad Request-Line, then ensure that it’s not an apache2 misconfiguration! I got apache2 listening to 80 only but have two virtual hosts. Not easy to see especially if you have the virtual hosts included.

– In Google Chrome, if you get a green icon lock then it fine.
trusted.png