Notes to self

Trusted SSL certificates with Let’s Encrypt and NGINX

letsencrypt.org is the new awesomeness that happened to SSL on the web. Forget over-priced trusted certificates or self-signed certs for your side & pro bono projects. Try trusted SSL in seconds for free instead :). If you choose to use Let’s Encrypt I want to show you what needs to be done on a pretty average Fedora VPS with NGINX server and how to avoid certbot errors like urn:acme:error:unauthorized and urn:acme:error:unknownHost.

Since I don’t plan to duplicate what’s already said on letsencrypt.org and certbot.eff.org so go read that first. In short Let’s Encrypt will generate certificate for your (sub)domains for free on the fly on your server using the program called certbot. But before that certbot has to actually check that your server is serving your domain and that you have access to it.

So before running certbot you will need to check that your DNS records are in tact. Go to your DNS settings and check A records:

# Example: these are A records for gettandem.com (redirect) and www.gettandem.com (main site)
www.gettandem.com	1800	A	46.101.250.40
gettandem.com	        1800	A	46.101.250.40

This says what (sub)domains point to which IP address. If you want to generate SSL that is valid for your redirects as well, do not forget A records for them! With correct DNS settings you should be already safe from getting urn:acme:error:unknownHost.

Secondly you will need for certbot to check you have root access on the server mentioned in the A record. In our case that will be by specifying --webroot and --webroot-path options. Depending on your server that path might be able to serve the generated file in question (in $WEBROOT/.well-known/*). If needed add a specific entry for this to NGINX:

server {
  ...
  location ~* ^/.well-known {
    root $YOUR_ROOT;
    allow all;
  }
  ...
}

You can easily check this by placing a random HTML file under this path and see if it will be served ($YOUR_ROOT can be your public assets directory for instance). That should eliminate another common error where the bot cannot access your server on the generated URL and so it is saying that you are unauthorized to place its file under yourserver.com/.well-known by raising urn:acme:error:unauthorized error.

If you feel confident that all is set, run the certbot:

$ sudo dnf install certbot -y
$ sudo certbot certonly --webroot -d domain.com -d sub.domain.com -m your@contact.mail --agree-tos --webroot-path $WEBROOT -n

-n is for non-interactive mode, so you can script this step.

If all is well, you should see something along this lines:

...
Generating key (2048 bits): /etc/letsencrypt/keys/0002_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0002_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/www.domain.com-0001/fullchain.pem. Your
   cert will expire on 2017-08-11. To obtain a new or tweaked version
   of this certificate in the future, simply run certbot-auto again.
   To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

The last step is obvious, replace your old NGINX SSL settings with the new one :).

E.g.:

server {
   ...
   ssl_certificate /etc/letsencrypt/live/www.domain.com-0001/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/www.domain.com-0001/privkey.pem;
   ...
}

And systemctl restart nginx!

Check out my book
Deployment from Scratch is unique Linux book about web application deployment. Learn how deployment works from the first principles rather than YAML files of a specific tool.
by Josef Strzibny
RSS