Public
Snippet $21 authored by Jabis Sevón

Letsencrypt guide for a single certificate handling server, with multiple OS servers using webroot authentication

Edited
le-guide.md

Unofficial Letsencrypt guide for single client & multiple servers

My setup with multiple different Server OS with fairly recent Nginx frontends, and a single Debian Lenny/Wheezy/Jessie tripbreed challenge handling server, also with an nginx frontend

So in short we have a lot of servers, a few different "web management consoles", mixed OS servers, and of course mixed amount of web facing services that require certificates.

Question arises, how could we leverage these wonderful free certs provided by Letsencrypt, while minimizing the needed time to make everything just work?

Let's put the whole webroot signing process to a neat form:

  • I'm now assuming you installed your letsencrypt/certbot to /opt/le-<block> where <block> is a representative of a batch of clients, not necessarily sharing the same domain, but same certificate.
  • First you would want to make sure you have listening endpoint in your client-running(cert challenge server) available via for example cert.<block>.tld on port 80 so that the letsencrypt client can read from;
  # Certificate listening server filename: /usr/local/nginx/conf.d/cert.<block>.tld.conf **(NOTE: can be /etc/nginx/sites-available/cert.<block>.tld.conf for debian default installations )**  
  server {
    listen 80;
    server_name cert.<block>.tld;
    include /usr/local/nginx/conf/le-<block>.conf; #This is the path to the below include file  
    server_tokens off; # Don't show the nginx version numbers dudes  
    return 301 https://$host$request_uri;  
  }
  • now of course you need to make the above le-<block> configuration to point to the actual letsencrypt root where the challenge files will appear for this certain block of domains:
  # Actual location block filename: /usr/local/nginx/conf/le-<block>.conf 
  location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain"; # challenge files are expected in text/plain
    root         /opt/le-<block>;  
  }
  location = /.well-known/acme-challenge/ {
    return 404; # we don't want file listings
  }
  • Now compose the /etc/letsencrypt/configs/<block>.conf for the domains you want, starting from the primary domain
  # the domain(s) we want to get the cert for, separated with a comma **without** a trailing space;
  domains = primary.tld,www.primary.tld,another.xyz,andanother.abc
  # Choose key size how needed - default 2048
  rsa-key-size = 4096
  # Use staging server for getting test cert
  server = https://acme-staging.api.letsencrypt.org/directory
  #server = https://acme-v01.api.letsencrypt.org/directory
  # this address will receive renewal reminders
  email = your@email.com
  # Uncomment to turn off the ncurses UI when running the conf with a cronjob
  #text = True
  # authenticate by placing a file in the webroot (under .well-known/acme-challenge/) and then letting
  # LE fetch it
  authenticator = webroot
  webroot-path = /opt/le-<block>/
  • Ok now you should call /opt/le-<block>/letsencrypt-auto certonly -c /etc/letsencrypt/configs/<block>.conf --dry-run for the first time
  • While you're waiting for the script results letsencrypt creates a challenge file to /opt/le-<block>/<token> and -> When the letsencrypt server receives the request to authenticate the webroot for <token> with all the domains listed in the /etc/letsencrypt/configs/<block>.conf file we created earlier, dispatches a http-request to all of those domains for challenge file verification.
  • If even one of the domains fails you will have an appropriate error message telling that the domain.xyz failed for reason X
  • now if your servers are scattered around the planet for your <block> of domains - very much like mine are - you'll need to add the following little include configuration to the respective servers' configurations, like
  # Server `primary.tld` , `www.primary.tld` etc residing in filename: /usr/local/nginx/conf/le-<block>.conf 
  location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    proxy_pass http://cert.<block>.tld:80; # This is your above certificate block server, note you just pass it without any additional headers you'd use normally - this means absolutely no x-whatever headers - just plain proxy_pass  
  }
  • with of course the inclusion appearing in the respective server-blocks;
  server {
    server_name primary.tld www.primary.tld;
    include /usr/local/nginx/conf/le-<block>.conf; # ^ see above 
    location ...
  }
  • After some serious Nginx service reloading, you should run the first letsencrypt-auto ...-command again - and voila - there should be no more errors.
  • After Dry run finishes without errors, I'd try the batch with only the staging server, just to see the certificates appearing in /etc/letsencrypt/live/primary.tld/*.pem and only after satisfied, switch to the live server, and deploy the certs to the originating servers.
  • NOTE: the files in this path are actually symlinks - so in some cases where you need to utilize the certificates without root access ( like for example gitlab ) you'll have to ls -la /etc/letsencrypt/live/primary.tld/*.pem to see the actual file paths and possibly copy the actual files to where you use them and chown and/or chmod them appropriately