Ask A Question

Notifications

You’re not receiving notifications from this thread.

How do I use Let's Encrypt to get and automate SSL on ubuntu, nginx server

Thomas Bush asked in General

I was thinking maybe this could be a tutorial/guide request?

I always use the GoRails guides to setup my ubuntu, nginx, passenger servers(thanks!) I am having trouble figuring out how to use Lets Encrypt to get an ssl cert and automate renewal. I have seen quite a few tutorials and guides around the internet, but I must be missing something somewhere because they are not working for me.

Result

  • https: Safari server failed to respond error
  • http: still works.

Steps to install Lets Encrypt and create SSL

  • I install the agent via lets encrypt getting started guide.
  • I updated up my server block to included allow for /.well-known (included below)
  • ran certbot command to generate cert
    • ./certbot certonly -a webroot --webroot-path=/home/deploy/hexcom/current/public -d hexarmor.com -d www.hexarmor.com
  • I updated up my server block to listen on 443 and include cert keys (included below)
  • sudo service nginx reload

/etc/nginx/sites-available/default

server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        listen 443 ssl;

        #ssl on;
        ssl_certificate /etc/letsencrypt/live/hexarmor.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/hexarmor.com/privkey.pem;

        server_name hexarmor.com;

        passenger_enabled on;
        rails_env    production;
        root         /home/deploy/hexcom/current/public;

        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location ~ /.well-known {
                allow all;
        }
}
Reply

Heck yes. Let's Encrypt seems awesome, but then when I started poking around it was like okay well this seems a little more complicated than I originally thought.

I'll try setting this up for my personal blog and try to make a tutorial on it.

Reply

Thanks Chris! I would love to be able to use this for all my projects, and just standardize on config.force_ssl = true in prod. Can't wait!

Reply

Anyone using this? I have certbot-auto installed, and have attempted to set up auto renewal, but it does not appear to be working. My cert expires in 2 days so I would REALLY appreciate any help anyone could provide.

error:

WARNING:certbot.renewal:Attempting to renew cert from /etc/letsencrypt/renewal/MY-SITE.com.conf produced an unexpected error: Failed authorization procedure. www.MY-SITE.com (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://www.MY-SITE.com/.well-known/acme-challenge/CHALLENGE-STRING: "<!DOCTYPE html>
<html>
<head>
  <title>The page you were looking for doesn't exist (404)</title>
  <meta name="viewport" content", MY-SITE.com (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://MY-SITE.com/.well-known/acme-challenge/DIFFERENT-STRING: "<!DOCTYPE html>
<html>
<head>
  <title>The page you were looking for doesn't exist (404)</title>
  <meta name="viewport" content". Skipping.
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/MY-SITE.com/fullchain.pem (failure)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
1 renew failure(s), 0 parse failure(s)
Reply

So I ended up figuring this out, it was an improper path issue -- whoops -- as well as an addition to my nginx server block. Lesson learned, don't use relative paths for this. Could we add this to the Deploy ROR Guides? I think this would probably benefit a lot of people to just be secure by default. SSL can be tricky in my opinion and certbot simplifies this.

I have included the addition to the server block below.

/etc/nginx/sites-available/default

location ~ /.well-known {
  allow all;
}  

Next ssh into your server and execute the dry-run first to ensure everything is set up properly.

/home/deploy/certbot-auto renew -w /home/deploy/your-app/current/public --dry-run

If successful run the one off command to renew your current ssl.

/home/deploy/certbot-auto renew -w /home/deploy/your-app/current/public --quiet --no-self-upgrade

Future renewal

The other thing I came across that I found useful, I scheduled this in crontab, using whenever gem. This way you don't have to worry about it again. I preferred this approach over writing to crontab myself in that its now part of git/github, therefore this requirement is documented for other devs, or for myself 6 months from now.

Just in case anyone has a similar setup or is interested in this setup, I have included an example whenever task that would live in your schedule file below.

config/schedule.rb

every 1.day, :at => '3:21 am' do
  command "/home/deploy/certbot-auto renew -w /home/deploy/your-app/current/public --quiet --no-self-upgrade"
end
Reply

I realize I'm about a month late on replying to this thread, but I'm definitely going to add this to the guides.

It looks like the renew goes into the public folder in your app. Does this mean that if you do a new deploy with Capistrano it loses access to that file if you ever rebooted nginx or are you symlinking the directory that Let's Encrypt creates on your deploys?

Reply

I've just set this up one two separate apps. Everything is symlinked, so deploys don't effect it at all.

This guide is pretty good:
https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04

You'll have to change the webroot path to point to the rails app rather than a the basic html folder. The one other gotcha to look out for is if you're using CloudFlare. You need to specify the authenticator method to use webroot, or it won't authenticate. I believe this one does, but older articles haven't. You can read more on it here:
https://support.cloudflare.com/hc/en-us/articles/214820528-How-to-Validate-a-Let-s-Encrypt-Certificate-on-a-Site-Already-Active-on-CloudFlare

The tutorial should result in an A+ rating from the Qualys SSL Labs Report.

I think a guide on setting this up for rails specifically would be great. Maybe add it into the security series you keep talking about? Once you wrap your head around it you can get it setup and auto renewing in about 15 minutes.

Reply

Awesome, I just ran into a thing that I need to have SSL for a side project last night so I'm going to try using Let's Encrypt to get that setup. Can't wait to try it out!

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 81,842+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more.

    © 2024 GoRails, LLC. All rights reserved.