Setting up SSL https for Rails3
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
<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.