SaltStack states for Let's Encrypt certificates on Debian with Nginx
Jul 18, 2018
Recently I’ve configured Let’s Encrypt certificates for a staging HTTPS
server for one of our clients. That was amazingly easy to do. I remember checking the ACME protocol
client tools in the very beginning of Let’s Encrypt initiative. Back then the tools were, of course,
very immature: hard to install and configure, and they only worked in interactive mode. It’s all in
the past now.
Basically, I took this great blog
post
and codified it in SaltStack
states. SaltStack is an
automatic configuration management tool similar to
Puppet and
Ansible. It’s quite simple and
declarative, yet it scales up to larger infrastructure. Our sysadmins love it.
Below is the annotated YAML of my solution.
That adds the jessie-backports Debian package repository, and installs the
Dehydrated ACME client from it. Starting with Debian Stretch (v9) it’s
not necessary to add the backports
repo.
Then, the section above can be reduced to just this:
The salt://web-server/conf/example.com nginx configuration file:
Which is then referenced from the salt://web-server/init.sls:
The salt://web-server/conf/acme-challenge.http.location.inc file is nothing but:
Now the tricky bit. The /etc/nginx/conf.d/ssl.inc referenced in the
salt://web-server/conf/example.com will in the end contain the path to the certificate file, and
the path to the secret server key file. We don’t have those initially, before the ACME challenge
takes place. Thus, we need some “transitional” certificate and key to make nginx start and serve the
ACME challenge Web location over HTTP.
The final part is the certificate renewal cron job:
The chronic tool is a part of the moreutils Debian package.
It runs a command quietly unless it fails. Setting the MAILTO environment variable for cron makes
sure all the failures are e-mailed to webmaster@example.com. The
cron job configured above will run every Sunday at 04:02.