Let's Encrypt with acme-client(1)

I recently went through the process to convert my website to https only, and wanted to document and share the process I used.

My setup:

Step 1 - Add ACME Challenge to nginx

Let's Encrypt will sign your certificate if you can demonstrate that you control the domain. It does this by issuing the client software with a challenge, in this case to provision a HTTP resource under http://domain/.well-known/acme-challenge/. For more information about how Let's Encrypt works, visit https://letsencrypt.org/how-it-works/.

You will need to add the followign to nginx.conf to point it to the directory that acme-client(1) is using to satisfy Let's Encrypt challenges. This goes within the server section that is listening for http traffic (typically on port 80):

                ...INSERT THIS WITHIN NGINX.CONF SERVER BLOCK LISTENING FOR HTTP (ON PORT 80)

                # Lets encrypt
                location ^~ /.well-known/acme-challenge/ {
                        alias /usr/local/www/acme/;
                }

                ...REMAINDER OF NGINX CONFIG FOR WEBSITE HERE

Restart nginx with:

# service nginx restart

Step 2 - Create and sign new X509 certificate

After this, acme-client(1) can generate a new Let's Encrypt account key and certificate, get them signed, and install them with the following command:

# acme-client -vNn example.com www.example.com

This will give verbose output and perform the following:

Step 3 - Configure nginx to use https and re-direct http traffic

Now that you have a signed certificate, re-configure nginx.conf to instead listen for HTTPS connections on port 443, and re-direct HTTP connections to HTTPS. Note that you must keep the directory alias for responding to Let's Encrypt challenges on HTTP port 80.

        server {
                listen          80;
                server_name     example.com www.example.com;

                # Lets encrypt
                location ^~ /.well-known/acme-challenge/ {
                        alias   /usr/local/www/acme/;
                }

                # Redirect other HTTP connections to HTTPS
                location / {
                        return  301 https://example.com$request_uri;
                }
        }

        server {
                listen                  443 ssl;
                server_name             example.com www.example.com;
                ssl_certificate         /usr/local/etc/ssl/acme/fullchain.pem;
                ssl_certificate_key     /usr/local/etc/ssl/acme/private/privkey.pem;

                ... MOVE REMAINDER OF NGINX CONFIG FOR WEBSITE HERE
        }

Restart nginx with:

# service nginx restart

Step 4 - Configure periodic re-validation of certificate

Configure the acme-client(1) to perform weekly re-validation of the certificate with Let's Encrypt using periodic(8).

Add the following to /etc/periodic.conf (create the file if it does not exist):

weekly_acme_client_enable="YES"

# To specify the domain name(s) to include in the certificate
weekly_acme_client_domains="example.com www.example.com"

#To specify the .well-known/acme-challenge directory (full path)
weekly_acme_client_challengedir="/usr/local/www/acme"

#To set additional acme-client arguments (see acme-client(1))
weekly_acme_client_args="-bv"

#To run a specific script for the renewal (ignore previously set variables)
#allows generating/renewing multiple keys/certificates
#weekly_acme_client_renewscript="/usr/local/etc/acme/acme-client.sh"

#To run a script after the renewal to deploy changed certs
#weekly_acme_client_deployscript="/usr/local/etc/acme/deploy.sh"

Test it with:

# /usr/local/etc/periodic/weekly/000.acme-client.sh

Step 5 - Test website with SSL Labs

In a web browser, go to http://example.com/ and confirm it re-directs to https://example.com/ and the browser trusts the certificate.

Now visit https://www.ssllabs.com/ssltest/ to see how your website scores, and close any security flaws as necessary.

Two of the common fixes that need to be applied are:

BenWoods/LetsEncrypt (last edited 2017-01-22 11:17:46 by BenWoods)