Certificate from Let's Encrypt with Nginx and a non-root user

linux, letsencrypt

Let's Encrypt provides an automated method for requesting and renewing free SSL certificates that we can use to secure our websites, applications, APIs.

In this page, I explain how to automate the request and renewal of a SSL certificate, on a Ubuntu server running Nginx, with a script running with a non-root user.

First, create a user letsencrypt.

sudo adduser letsencrypt
sudo su - letsencrypt

I installed the acme.sh client at the root of the user home folder (/home/letsencrypt/).

git clone https://github.com/Neilpang/acme.sh.git
cd ./acme.sh
./acme.sh --install

In the home folder, I created a webroot folder that will contain files served by the web server to validate that I own the domain.

cd ~
mkdir webroot

Modify the Nginx configuration so that this folder is served over HTTP (and then restart Nginx).

# To add in the Nginx config file
# For example: /etc/nginx/sites-available/my-domain.com

server {
#...
location ^~ /.well-known/acme-challenge/ {
alias /home/letsencrypt/webroot/.well-known/acme-challenge/;
}
#...
}

Then, you can start issuing the certificate.

acme.sh --issue --log -d my-domain.com -w ~/webroot

Once the certificate is acquired, another step is necessary to generate certificates that can be used by Nginx, and reference them in the Nginx configuration.

mkdir -p certificates/my-domain.com

acme.sh --installcert -d my-domain.com \
--certpath /home/letsencrypt/certificates/my-domain.com/cert \
--keypath /home/letsencrypt/certificates/my-domain.com/key \
--fullchainpath /home/letsencrypt/certificates/my-domain.com/fullchain \
--reloadcmd "sudo systemctl reload nginx.service"
# Add this to the Nginx configuration
# For example, in /etc/nginx/sites-available/my-domain.com

server {
#...

# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /home/letsencrypt/certificates/my-domain.com/fullchain;
ssl_certificate_key /home/letsencrypt/certificates/my-domain.com/key;

#...
}

Finally, the letsencrypt user needs to be allowed to restart Nginx via the sudo command. The sudoers rights can be edited with the visudo command.

# User privilege specification
letsencrypt ALL= NOPASSWD: /bin/systemctl reload nginx.service

Check that the cron task has been installed.

crontab -l

14 0 * * * "/home/letsencrypt/.acme.sh"/acme.sh --cron --home "/home/letsencrypt/.acme.sh" > /dev/null

Sources used: