21

I only found how to start puma using SSL:

$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'

However, there is no description about how to include an intermediate CA cert in the documentation. Could someone point me in the right direction? I am using Puma 1.6.3

Thanks!

omninonsense
  • 6,644
  • 9
  • 45
  • 66

5 Answers5

25

Combining certificate and bundle will work only if you use nginx.

Without nginx, you can use ca and verify_mode options:

rails s puma -b 'ssl://0.0.0.0:9292?key=path_to_key.key&cert=path_to_cert.crt&verify_mode=none&ca=path_to_root_bundle.crt'

Source: https://github.com/puma/puma/blob/master/lib/puma/binder.rb

Besi
  • 22,579
  • 24
  • 131
  • 223
Alexandre S
  • 266
  • 3
  • 4
9

Kinda late to the party but, I have another solution, you can see my post for more details.

First create the certificate for your localhost using mkcert

mkcert localhost

If you want to have another domain to work on HTTPS, just replace localhost to the one you want, like mkcert mylocalhost-with-a-cool-domain.com

After this, I created a local-certs folder under the config folder and pasted the cert and key there.

Now you should mark these cert as trusted, I’m working on a Mac computer, so not sure how to handle this particular part on Windows or on a Linux distro. Check out the post, it has screenshoots. In resume, you will need to drag the certificate created with mkcert to the Keychain Access.

Then in your puma config file, create one if you don't have it and name it puma.rb, you should have something like

workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['THREAD_COUNT'] || 5)
threads threads_count, threads_count

rackup      DefaultRackup
port        3001
environment ENV['RACK_ENV'] || 'production'

if ENV['RACK_ENV'] == 'development'

  # If you didn't place the cert and key under `local-certs` you should change this
  localhost_key = "#{File.join('config', 'local-certs', 'localhost-key.pem')}" 
  localhost_crt = "#{File.join('config', 'local-certs', 'localhost.pem')}"

  ssl_bind '0.0.0.0', 3000, {
    key: localhost_key,
    cert: localhost_crt,
    verify_mode: 'none'
  }
end

Then running bundle exec puma -C puma.rb or bundle exec rails s should do it :D

If anyone has a question, pls let me know. Hope it helps future readers!

MatayoshiMariano
  • 2,026
  • 19
  • 23
  • Can we set it up for any domain? rather than a specific one? – pjo336 May 18 '20 at 21:11
  • 2
    @pjo336 yep, just replace `localhost` to whatever you prefer. In my job, we have a couple of services like: `api.myjob.com`, `client.myjob.com`, `another_name.myjob.com`. If that's your case, you can just go and do `mkcert *.myjob.com` and use that certificate – MatayoshiMariano May 19 '20 at 15:58
  • @MatayoshiMariano using the wildcard will work for any subdomain on myjob.com, but not for the root domain at the same time. I have not yet figured out how to solve this with mkcert in setup with puma. – swiknaba Jan 30 '21 at 15:24
  • 1
    .. using the wildcard will work for any subdomain on myjob.com, but not for the root domain at the same time. For this, run `mkcert "*.myjob.com myjob.com`. Note the quotes around the wildcard version. --ment to update my comment, can't after 5min -.- – swiknaba Jan 30 '21 at 15:33
  • @swiknaba i didn't test it for the root domain, will have to check that and get back to you – MatayoshiMariano Feb 01 '21 at 12:54
  • 3
    For Rails 6.x you should use `if ENV['RAILS_ENV'] == 'development'` – Ccastillop May 02 '21 at 23:11
3

while we are using combo Nginx+PhusionPassenger as well. You cant specify Chain cert file in nginx either. The trick is to bundle all certs within one certificate and then set the new certificate file as a certificate in your server configuration. You will find more information in nginx documentation. Check SLL Certificate Chains section.

cat www.example.com.crt bundle.crt > www.example.com.chained.crt

Hope it helped.

Jozef Vaclavik
  • 539
  • 5
  • 7
3

rails s puma -b 'ssl://0.0.0.0:9292?key=certkey.key&cert=cert.crt&verify_mode=peer&ca=root_bundle.crt

Just make sure you set the verify_mode=peer.

Manuel
  • 836
  • 13
  • 30
Luis Maia
  • 31
  • 1
-8

It may be a better idea to use Phusion Passenger + Nginx for SSL support. This combo has widely available documentation and is very easy to setup because it's currently the most popular app server choice, and used by the likes of New York Times, Symantec, AirBnB, etc. Here's how you do it if you have Nginx with Phusion Passenger installed:

server {
    listen 443;
    server_name yourapp.local;
    ssl on;
    ssl_certificate ...;
    ssl_key ...;
    root /path-to-your-app/public;
    passenger_enabled on;
}
Hongli
  • 18,682
  • 15
  • 79
  • 107
  • 1
    DV for not answering the question. – LAW Jun 13 '13 at 22:50
  • 1
    It may not be the answer you're looking for, but it is a valid answer. If something doesn't work then it may be better to look at alternatives instead. – Hongli Jun 14 '13 at 23:23
  • 14
    The question is "How to configure Rails with Puma to use SSL?". I don't see how explaining a Phusion Passenger setup even remotely answers that. I assume OP is aware of the various server choices and chose Puma for whatever reason, as I was when I found this question. There have been good things said about Puma, and I specifically wanted to get it working so I could test it. So no, you telling me to go use something else isn't helpful at all. – LAW Jun 18 '13 at 17:20