jdog
jdog

Reputation: 10759

How to run an SSL cert on localhost for Ruby on Rails app?

Running Ruby 1.9.3, Rails 4.2.10 and using Thin server on development.

My app is using SSL on Heroku. Need to run SSL on my local Mac.

I followed this tutorial.

https://www.botreetechnologies.com/blog/enable-ssl-for-rails-development-environment-two-minutes

Here is my Procfile:

web: bundle exec rails server thin start -p 3001 -e development --ssl --ssl-verify --ssl-key-file server.key --ssl-cert-file server.crt

Here is the error I am received in trace

Invalid request: Invalid HTTP format, parsing fails.
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/thin-1.6.4/lib/thin/request.rb:84:in `execute'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/thin-1.6.4/lib/thin/request.rb:84:in `parse'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/thin-1.6.4/lib/thin/connection.rb:39:in `receive_data'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/eventmachine-1.0.8/lib/eventmachine.rb:193:in `run_machine'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/eventmachine-1.0.8/lib/eventmachine.rb:193:in `run'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/thin-1.6.4/lib/thin/backends/base.rb:73:in `start'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/thin-1.6.4/lib/thin/server.rb:162:in `start'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/rack-1.6.4/lib/rack/handler/thin.rb:19:in `run'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/rack-1.6.4/lib/rack/server.rb:286:in `start'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/railties-4.2.4/lib/rails/commands/server.rb:80:in `start'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/railties-4.2.4/lib/rails/commands/commands_tasks.rb:80:in `block in server'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/railties-4.2.4/lib/rails/commands/commands_tasks.rb:75:in `tap'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/railties-4.2.4/lib/rails/commands/commands_tasks.rb:75:in `server'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/railties-4.2.4/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
    /Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/railties-4.2.4/lib/rails/commands.rb:17:in `<top (required)>'
    script/rails:6:in `require'
    script/rails:6:in `<main>'

UPDATE:

Though my procfile contains information about cert. I manually start my THIN rails server via terminal like this.

bundle exec rails server thin start -p 3001 -e development

So not sure if it is using the Procfile?

UPDATE 2 ========

Tried to use bundle exec thin start -p 3001 --ssl Had force_ssl set to false

Server starts

jn$ bundle exec thin start -p 3001 --ssl
/Users/jn/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/thin-1.6.4/lib/thin/backends/base.rb:103: warning: epoll is not supported on this platform
Using rack adapter
Thin web server (v1.6.4 codename Gob Bluth)
Maximum connections set to 1024
Listening on 0.0.0.0:3001, CTRL+C to stop

Try to hit https://localhost:3001 and server stops with error

libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: Encryption not available on this event-machine
Abort trap: 6

===== UPDATE 3: ======

Tried Puma.io failed same issue (cant establish a secure connection). Tried Puma-dev failed to even recognize .dev URl Tried manually adding cert and key again same issue (cant establish a secure connection).

App loads our app signin form at http://localhost:3000. As soon as I log in the app loads the correct user account page using http then about 1 second later page is redireted to the same user account page but https which says 'can't establish a secure connection'. Have no idea why the browser is forcing me to https? Nothing in the app is set to https that I can "Find/Replace".

Generated a new secret_key as think it was short 20 characters in stead of 30. Pasted into secret_key.rb restarted server. Same ssl issue.

Upvotes: 7

Views: 7234

Answers (5)

Tara
Tara

Reputation: 77

  1. First of all youll need to have easy-rsa

    sudo apt install easy-rsa
    
  2. Become root

    sudo su
    
  3. Go to the easy-rsa folder

    cd /usr/share/easy-rsa
    
  4. Copy example config file

    cp vars.example vars
    
  5. Open vars in your preferred text editor

    vi vars
    
  6. Uncomment these rows and fill in your values (CZ, Praha, Org. name...)

    set_var EASYRSA_REQ_COUNTRY "CZ"
    set_var EASYRSA_REQ_PROVINCE "Praha"
    set_var EASYRSA_REQ_CITY "Praha"
    set_var EASYRSA_REQ_ORG "Intel"
    set_var EASYRSA_REQ_EMAIL "ca@localhost"
    set_var EASYRSA_REQ_OU "Unit"
    
  7. Generate cert

    ./easyrsa init-pki (type yes if required)
    ./easyrsa build-ca (type password 2times, then type your server name)
    
  8. Copy cert to your home

    cp /usr/share/easy-rsa/pki/ca.crt ~ubuntu20/ (NOTE that ubuntu20 is my home, your will be different)
    sudo chmod +r ca.crt (run this command from user terminal (no root), it changes permissions from root to user.)
    
  9. Next command run from "/usr/share/easy-rsa" path. !! IMPORTANT !! local.max.support is my server name, choose your own

     ./easyrsa build-server-full local.max.support (type new password (2times) and then password we typed before)
    
  10. Redirect from port 3000 to 443 (HTTPS)

    sudo iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 443 -j REDIRECT --to-ports 3000
    
  11. Check if we make it correctly

    vi /etc/hosts
    
    127.0.0.1 localhost local.max.support (if your see this (with your server name), its probably correct.)
    

    Another test:

    ping local.max.support (If its responding GOOD JOB!)
    
  12. Import ca.crt from your home to the browser as a Authority. In Chrome: Settings -> privacy and security -> Security -> Manage certificates -> Authorities -> Import

  13. Move cert and key to your project /config

    cd /usr/share/easy-rsa/pki/certs_by_serial (here is your cert, rename it from "hash".pem to yourServerName.crt (In my case local.max.support.crt))
    
    cp local.max.support.crt ~ubuntu20/Desktop/centraldb-portal/config (COPY that file to your project /config)
    
    cd /usr/share/easy-rsa/pki/private (here is your key)
    cp local.max.support.key ~ubuntu20/Desktop/centraldb-portal/config (move key to your project)
    
  14. Change permissions from root to user (Open new user terminal)

    cd /Desktop/centraldb-portal/config (Go to your project config folder)
    sudo chmod +r local.max.support.crt (Change permissions)
    sudo chmod +r local.max.support.key (Change permissions)
    
  15. Run your HTTPS server

    bin/dev -b "ssl://127.0.0.1:3000?cert=./config/local.max.support.crt&key=./config/local.max.support.key"(type cert password), (don't forget to edit your .key, .crt files names)
    

Upvotes: 0

saqib
saqib

Reputation: 107

Open the terminal and follow these steps

  1. openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 365 -keyout localhost.key -out localhost.crt

  2. sudo nano /usr/local/share/ca-certificates/localhost.crt and copy text from
    gernate file localhost.crt save

  3. sudo update-ca-certificates

  4. add gem "thin"

  5. for run sever "thin start --ssl --ssl-key-file localhost.key --ssl-cert-file localhost.crt"

Upvotes: 0

jdog
jdog

Reputation: 10759

Updated the app to 2.3.1 which got puma-dev to work. Removed config.action_cable.disable_request_forgery_protection = true which was throwing an error.

Upvotes: 0

lacostenycoder
lacostenycoder

Reputation: 11216

UPDATE: Based on your last comment. You need to start your local server either with

foreman start -f Procfile

Or with

bundle exec thin start -p 3001 --ssl –-ssl-key-file ~/.ssl/localhost.key –-ssl-cert-file ~/.ssl/localhost.crt

However this Profile won't work in production. You might want to use an alternate Procfile-dev file in development

ORIGINAL:

In Procfile try hard coding the port use 3001 for ssl

web: bundle exec thin start -p 3001 --ssl –-ssl-key-file ~/.ssl/localhost.key –-ssl-cert-file ~/.ssl/localhost.crt

UPDATE 2: You shouldn't need a cert at all for local dev, you should be able to allow access via Chrome

bundle exec thin start -p 3001 --ssl  #this should work without any other arguments

Then you need to pass the port into the browser

https://localhost:3001

You might also try to comment out this in application.rb

#config.force_ssl = true

That should only be set in production.rb

As to why you can't install gem install foreman I'm not sure why you can't, it sounds like some kind of network problem on your machine, do you have a firewall blocking?

Upvotes: 0

Aref Aslani
Aref Aslani

Reputation: 1636

You can use puma-dev for local development. It makes HTTPS available without a hassle.

Puma-dev automatically makes the apps available via SSL as well. When you first run puma-dev, it will have likely caused a dialog to appear to put in your password. What happened there was puma-dev generates its own CA certification that is stored in ~/Library/Application Support/io.puma.dev/cert.pem.

Upvotes: 4

Related Questions