Hello there!

I'm Shubham Bansal

Hello there, I am Shubham Bansal.

I live in Chicago with my Wife and Daughter.

I like Programming, Reading, Travel and Squash. I am @shubhambansal on twitter.

Setting up HTTPS on a Rails application

If you are building a web application that is going and you are going to be These settings are only valid in case you are running Mac OSX 10.9 or higher.

#Installing Pow

First we would need to install Pow. Pow is zero configuration rack server.

Pow runs as your user on an unprivileged port, and includes both an HTTP and a DNS server. The installation process sets up a firewall rule to forward incoming requests on port 80 to Pow. It also sets up a system hook so that all DNS queries for a special top-level domain (.dev) resolve to your local machine.

All the instruction for installing Pow can be found on the website.

After running the installation script, all you have to do is setup a symlink to your application directory in your ~/.pow directory and everything should just work.

You should be able to access your application by going to the url:

  http://your-app-name.dev

In case you are having issues running Pow on Chrome, try accessing the application at the url using xip.io e.g.

  http://your-app-name.127.0.0.1.xip.io

There is a lot more discussion around this issue on this github thread.

At this point, if you try to access your application via HTTPS it doesn’t work. For that we would need Nginx.

#Installing Nginx

You can use homebrew to install Nginx on your Mac. Just run the following command.

  $ brew install nginx

##Generating an SSL certificate

Next we will need to generate an SSL certificate for our application and we will use OpenSSL for that. If you don’t have OpenSSL installed on your machine, you can use homebrew to install it.

  $ brew install openssl

Once OpenSSL is installed, go ahead and generate an SSL certificate using the following command.

  $ openssl req -new -nodes -keyout server.key -out server.csr

Once you run the command, it will ask you a few questions about the certificate which you can leave blank as we are going to be using this only for local development. This command will generate a private key server.key file and a certificate signing request server.csr file for us.

Next we will generate a certificate server.crt using the two files we created above using the following command.

  $ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

##Configuring Nginx

We would need to configure Nginx to use the certificate we just generated. If you installed Nginx using homebrew, it should be installed at /usr/local/etc/nginx. Move the server.crt and server.key into the Nginx installation directory.

After that, open the nginx.conf file located within the Nginx installation directory and look for the HTTPS configuration at the bottom of the file. It should be commented out by default. We would need to uncomment the HTTPS section of the file and make some changes to this configuration to get SSL working. Here is what the HTTPS config should look like in your application. The SSL config should look something like this.

  # HTTPS server #
  server {
    listen 443;
    server_name *.dev;
    ssl on;
    ssl_certificate server.crt;
    ssl_certificate_key server.key;
    ssl_session_timeout 5m;
    ssl_protocols SSLv2 SSLv3 TLSv1;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    location / {
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto https;
      proxy_redirect off;
      proxy_pass http://127.0.0.1;
    }
  }

We are trying to listen on port 443 which is the correct HTTPS port. The ssl_certificate points to the location of the crt file and the ssl_certificate_key is the location of the private key. Next we will change the location section of the config to setup Nginx as a reverse proxy.

You can also checkout my Nginx Configuration File

Once you have made the changes to your nginx.conf file, you can test your changes by running this command.

  $ sudo nginx -t

Volla!! If you go visit the HTTPS URL, you would get prompted with a warning that the certificate is not verified but that is fine as we generated a self signed certificate. Just accept the warning and you should be able to serve your application using HTTPS.

##Force SSL access across application

If you would like to serve your entire application via SSL, you can configure rails to do that. Just go to your environment specific config ( development.rb or test.rb or production.rb) and add the following config

 $ config.force_ssl = true

You could also add the config to the application.rb file to force SSL across all the environments. This is my preferred way of setting up SSL for all my applications as it is much easier to manage as well.

And that’s it.

You application will be served over HTTPS now.