Infinite Loop with Force_SSL

I ran into an issue where I keep getting infinite loops on views with force_ssl.  I’m using Nginx and found that I needed to adjust the config.

For me the settings were in /etc/nginx/sites-enabled/default.

I needed to add this in the @location part:

proxy_set_header X_FORWARDED_PROTO $scheme;

Here's how my file ended up looking:

server {
    listen   443;
    ssl on;
    ssl_certificate     /etc/ssl/xyz.crt;
    listen   80;
    root /home/rails/public;
    server_name _;
    index index.htm index.html;

    location / {
            try_files $uri/index.html $uri.html $uri @app;

#       location ~* ^.+\.     (jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rt    f|js|mp3|flv|mpeg|avi)$ {
location ~* ^.+\.    (jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|mp    3|flv|mpeg|avi)$ {
                    try_files $uri @app;

     location @app {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://app_server;
            proxy_set_header X_FORWARDED_PROTO $scheme;

Creating a CSR on Windows

In order to create a SSL Certificate, you need to generate a CSR, or Certificate Signing Request.  I ran into some issues when generating one from Windows, so I wanted to document the steps that I took.

  1. went to to download Win32 OpenSSL v1.0.0k
  2. installed OpenSSL
  3. I received an error regarding C++ during the install, so I installed Visual C++ 2008 Redistributables from the same page I downloaded OpenSSL
  4. Run a command prompt (cmd.exe from the search box in the Windows start menu)
  5. When I tried to run an OpenSSL command, I received an error that a file could not be found (WARNING: CAN’T OPEN CONFIG FILE: /USR/LOCAL/SSL/OPENSSL.CNF)
  6. As noted here, you have to set the environmental variable by typing this into the cmd: set OPENSSL_CONF=c:\[PATH TO YOUR OPENSSL DIRECTORY]\bin\openssl.cfg
  7. navigate to the bin directory
  8. enter your openssl command to generate your csr.  For me, it was:
    openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out myserver.csr
  9. this created key and csr files I could use for creating my SSL certificate

Setting Up SSL on AWS Bitnami Instance of Ruby on Rails (Apache)

Setting up SSL on the Bitnami instance of Ruby on Rails is easy.

  1. First, you’ll want to make sure that you’ve purchased your SSL certificates for your domain
  2. Next, log in to your EC2 instance
  3. place the .key and .crt files you have for your SSL certificate in your apps’s root directory
  4. go to your app’s root and move the files to the correct directory with

mv yourcrt.crt /opt/bitnami/apache2/conf/extra/yourcrt.crt

mv yourkey.key /opt/bitnami/apache2/conf/extra/yourkey.key

       5.  the httpd.conf file that the instance comes with already points to another file for the ssl configuration, so we’ll want to edit that file that is being used.

6.  enter “cd  /opt/bitnami/apache2/conf/extra”

7.  enter “pico httpd-ssl.conf” to edit the ssl configuration

8.  in the file (CNTL + X to save when you are done):

    • change the “DocumentRoot” to “home/bitnami/apps/yourapp/public” or where ever your app is
    • change the “ServerName” to
    • change the “ServerAdmin” to your email
    • change the “SSLCertificateFile” to “/opt/bitnami/apache2/conf/extra/yourcrt.crt”
    • change the “SSLCertificateKeyFile” to “/opt/bitnami/apache2/conf/extra/yourkey.key”

9.  stop and restart your server

apachectl -k stop

apachectl -k graceful

Your app should now be successfully set-up for SSL.

Making Devise Views Use SSL

I had trouble figuring out the best way to make Devise views secure.  Devise recommends making all pages secure since they use cookies, but I had some views that I could not make secure, so I needed to figure out how to make some views, including the Devise ones, secure.  Normally I would indicate force_ssl in the controller, but Devise is an installed gem that I didn’t want to mess with.

I found the answer after digging awhile, here.

#for Rails 3.1 and above, in config/environments/production.rb
config.to_prepare { Devise::SessionsController.force_ssl }
config.to_prepare { Devise::RegistrationsController.force_ssl }
config.to_prepare { Devise::PasswordsController.force_ssl }

Using SSL

Turning on SSL was a little more time consuming than I thought it would be – largely because of my naivete.  Here’s some of things I had to do to make it work.

  1. For Paperclip – for images from S3, I had to changes the parameters in has_attached_file to include ‘:s3_permissions => :private, ‘ .  This will give the S3 images a https in the url
  2. For the Recaptcha gem, add the option :ssl => true as an option to the recaptcha_tag, like so: <%= recaptcha_tags(:ssl => true) %>
  3. I had to change all external libraries I referenced for CSS or JS to https (in the url) or download a local copy and reference the local copy
  4. in each controller where a view that needed to be secured force_ssl :only => :new or force_ssl :only => [:new, :edit] for multiple actions

When you run into issues, maybe these tips will help:

  • if you’re using Chrome, Chrome will mark all pages insecure if you hit one that claims https, but has some insecure elements (so you may see a page that is secure, but it says insecure).  If you find this, pop open a new tab and paste the url in doubt
  • seek and destroy all elements that show in your source that are http instead https, except links
  • when a browser asks if you want to display insecure items, try saying no and see if you can see if there’s anything missing (in the case of it being javascript, you may not notice anything visually)