Securing Your Nginx Site With Let’s Encrypt & Acme.sh

Estimated reading time: 3 min

Introduction

This guide will show you how to set up Let’s Encrypt for Nginx on your Debian 8 instance. Let’s Encrypt is a free way to secure your web server using HTTPS. It will automatically renew your certificates, so after you install and configure it you’ll have a continually-secured web server. Although Let’s Encrypt doesn’t have a ready-made plugin for Nginx, we’ll use acme.sh to generate the certificate and renew it using a cron job.

Prerequisites

We’re assuming you already have a Debian 8 instance with Nginx running. If you don’t, you can follow our other tutorials for getting that setup. We’ll also be using acme.sh, a useful command line tool for dealing with Let’s Encrypt and the ACME protocol. We’ll refer to the current Nginx site as example.com, and assume it’s running out of /var/www/example.com

Step 1: Install Acme.sh

First, we need to install acme.sh, which we’ll use later to automate certificate handling. There are instructions on the Acme website, but the easiest thing to do is just run

curl https://get.acme.sh | sh

And let the installer run. You may see some warnings, but the installer should complete. You can test that it installed correctly by re-opening a terminal and running

acme.sh -

You should get the version information. You’re good to go!

Step 2: Configure Nginx

Now we need to set up Nginx to serve the certificate challenge. When we request a certificate from Let’s Encrypt, they go to our site and look for a challenge to ensure that we are the real owners. So when they arrive, we need to ensure Nginx can serve them the challenge!

We do that by setting a location directive in Nginx’s config. Open this file in your favourite text-editor:

nano /etc/nginx/includes/letsencrypt-webroot
location /.well-known/acme-challenge/ {
  alias /var/www/example.com/.well-known/acme-challenge/;
}

Then, in our main Nginx config file, we can include this location directive. Edit /etc/nginx/sites-enabled/default (or if you’re using a custom configuration, your main Nginx config file). Add the following line to include the above directive,

nano /etc/nginx/sites-enabled/default
server { 
  listen 80; 
  server_name example.com;
  # other config content here ... 
  # Let's Encrypt 
  webroot include includes/letsencrypt-webroot 
}

Step 3: Issue the Certificate

Now that we’ve got everything in order, the only thing left is to acquire the certificate! Run the following acme.sh command

acme.sh --issue -d www.example.com -d example.com -w /var/www/example.com

This will generate the certificates for both the root domain and the www subdomain, using the site directory we told Nginx about. If things went well, you should see the certificates and the associated files in your working directory.

If the command didn’t work, one common problem is with permissions. If you get an error saying acme couldn’t make the required files, make sure you have permissions set so that you can write to /var/www/example.com with the user you’re running the acme script as.

Step 4: Set Up HTTPS Serving

Once you’ve generated a certificate, Nginx needs to know about it before it can use it to secure your site. The full instructions are on the Nginx docs site and depend on your individual configuration. The basic idea, however, is to put the certificate in a known location and tell Nginx where it can be found.

To begin, create a Nginx certificates directory if it doesn’t already exist by running

mkdir -p /etc/nginx/certs/example.com

Then, move your certificate files that were created by acme.sh in step 3 into the new directory by running

mv *.pem /etc/nginx/certs/example.com

Finally, edit your Nginx config to point to the new certificate files

server {
  listen              443 ssl;
  ssl_certificate  /etc/nginx/certs/example.com/fullchain.pem;
  ssl_certificate_key /etc/nginx/certs/example.com/privkey.pem;
  ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers         HIGH:!aNULL:!MD5:
  ...
}

Run

sudo systemctl nginx configtest

 to ensure your syntax is correct and everything adds up. Then run

sudo systemctl nginx reload 

to use the new configuration.

Step 5: Auto-Renewing Certificates

We can set up acme.sh to run a cron job and automatically renew our certificates. With just one acme command, we can set up a cron job that will check if we need renewing, renew, and reload Nginx. The command is quite simple:

acme.sh --install-cert -d example.com --cert-file /etc/nginx/certs/example.com/cert --key-file /etc/nginx/certs/example.com/key --fullchain-file /etc/nginx/certs/example.com/fullchain  --reloadcmd "systemctl restart nginx.service"

To check if this worked, take a look at your crontab with

crontab -l

 and confirm that you can see the acme.sh entry.

Conclusion

You should now have a certificate issued with Acme.sh running in your Nginx server for your domain. Acme will check nightly to make sure your certificate is renewed on time and that your site stays secure!

Was this article helpful?
Dislike 7
Views: 28929

Reader Interactions

Leave a Reply

Your email address will not be published. Required fields are marked *