diff options
-rw-r--r-- | Gemfile | 2 | ||||
-rw-r--r-- | Gemfile.lock | 3 | ||||
-rw-r--r-- | config/environments/production.rb | 7 | ||||
-rw-r--r-- | config/general.yml-example | 5 | ||||
-rw-r--r-- | config/varnish-alaveteli.vcl | 40 | ||||
-rw-r--r-- | doc/INSTALL.md | 28 | ||||
-rw-r--r-- | lib/configuration.rb | 1 |
7 files changed, 86 insertions, 0 deletions
@@ -43,6 +43,8 @@ gem 'syslog_protocol' gem 'newrelic_rpm' # erubis is required by rails_xss. Both erubis and rails_xss can be removed after upgrading to Rails 3. gem 'erubis' +# rack-ssl won't be needed on upgrade to Rails 3.1 as something like it is baked in +gem 'rack-ssl' group :test do gem 'fakeweb' diff --git a/Gemfile.lock b/Gemfile.lock index 27f574f4f..55b574c2c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -99,6 +99,8 @@ GEM pg (0.13.2) polyglot (0.3.3) rack (1.1.6) + rack-ssl (1.3.3) + rack rake (0.9.2.2) rbx-require-relative (0.0.9) rdoc (3.12.1) @@ -190,6 +192,7 @@ DEPENDENCIES newrelic_rpm pg rack (~> 1.1.0) + rack-ssl rails! rake (= 0.9.2.2) rdoc diff --git a/config/environments/production.rb b/config/environments/production.rb index 84a8f5965..097944196 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -17,3 +17,10 @@ config.action_controller.perform_caching = true # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false config.action_mailer.delivery_method = :sendmail # so is queued, rather than giving immediate errors + +require 'rack/ssl' +if ::Configuration::force_ssl + config.middleware.insert_after ActionController::Failsafe, ::Rack::SSL + # For Rails 3.x this will need to change to + #config.middleware.insert_before ActionDispatch::Cookies, ::Rack::SSL +end diff --git a/config/general.yml-example b/config/general.yml-example index 6bf54f400..5005fda77 100644 --- a/config/general.yml-example +++ b/config/general.yml-example @@ -12,6 +12,11 @@ SITE_NAME: 'Alaveteli' # Domain used in URLs generated by scripts (e.g. for going in some emails) DOMAIN: '127.0.0.1:3000' +# If true forces everyone (in the production environment) to use encrypted connections +# (via https) by redirecting unencrypted connections. This is *highly* recommended +# so that logins can't be intercepted by naughty people. +FORCE_SSL: true + # ISO country code of country currrently deployed in # (http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) ISO_COUNTRY_CODE: GB diff --git a/config/varnish-alaveteli.vcl b/config/varnish-alaveteli.vcl index 77350a8c8..5dd0ac83c 100644 --- a/config/varnish-alaveteli.vcl +++ b/config/varnish-alaveteli.vcl @@ -115,3 +115,43 @@ sub vcl_fetch { } } +# We need to separately cache requests originating via http and via https +# since we are serving very slightly different content in each case + +# Varnish 2.x version of vcl_hash +#sub vcl_hash { +# set req.hash += req.url; +# if (req.http.host) { +# set req.hash += req.http.host; +# } else { +# set req.hash += server.ip; +# } +# +# # Include the X-Forward-Proto header, since we want to treat HTTPS +# # requests differently, and make sure this header is always passed +# # properly to the backend server. +# if (req.http.X-Forwarded-Proto) { +# set req.hash += req.http.X-Forwarded-Proto; +# } +# +# return (hash); +#} + +# Varnish 3 version of vcl_hash +sub vcl_hash { + hash_data(req.url); + if (req.http.host) { + hash_data(req.http.host); + } else { + hash_data(server.ip); + } + + # Include the X-Forward-Proto header, since we want to treat HTTPS + # requests differently, and make sure this header is always passed + # properly to the backend server. + if (req.http.X-Forwarded-Proto) { + hash_data(req.http.X-Forwarded-Proto); + } + + return (hash); +} diff --git a/doc/INSTALL.md b/doc/INSTALL.md index 3a911cbc8..816b79066 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -378,6 +378,34 @@ Under all but light loads, it is strongly recommended to run the server behind an http accelerator like Varnish. A sample varnish VCL is supplied in `../conf/varnish-alaveteli.vcl`. +It's strongly recommended that you run the site over SSL. (Set FORCE_SSL to true in +config/general.yml). For this you will need an SSL certificate for your domain and you will +need to configure an SSL terminator to sit in front of Varnish. If you're already using Apache +as a web server you could simply use Apache as the SSL terminator. A minimal configuration +would look something like this: + +<VirtualHost *:443> + ServerName www.yourdomain + + ProxyRequests Off + ProxyPreserveHost On + ProxyPass / http://localhost:80/ + ProxyPassReverse / http://localhost:80/ + RequestHeader set X-Forwarded-Proto 'https' + + SSLEngine on + SSLProtocol all -SSLv2 + SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM + + SSLCertificateFile /etc/apache2/ssl/ssl.crt + SSLCertificateKeyFile /etc/apache2/ssl/ssl.key + SSLCertificateChainFile /etc/apache2/ssl/sub.class2.server.ca.pem + SSLCACertificateFile /etc/apache2/ssl/ca.pem + SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown +</VirtualHost> + +Notice the line "RequestHeader" that sets the X_FORWARDED_PROTO header. This is important. This ultimately tells Rails that it's serving a page over https and so it knows to include that in any absolute urls it serves. + Some [production server best practice notes](https://github.com/mysociety/alaveteli/wiki/Production-Server-Best-Practices) are evolving on the wiki. diff --git a/lib/configuration.rb b/lib/configuration.rb index d1da45fcf..f155ed7a4 100644 --- a/lib/configuration.rb +++ b/lib/configuration.rb @@ -18,6 +18,7 @@ module Configuration :EXCEPTION_NOTIFICATIONS_FROM => '', :EXCEPTION_NOTIFICATIONS_TO => '', :FORCE_REGISTRATION_ON_NEW_REQUEST => false, + :FORCE_SSL => true, :FORWARD_NONBOUNCE_RESPONSES_TO => 'user-support@localhost', :FRONTPAGE_PUBLICBODY_EXAMPLES => '', :GA_CODE => '', |