Now that I have configured my webserver to pull down any new certificates, now it’s time to configure my clients to pull certificates from the webserver.
In my quest for a centralized Let’s Encrypt solution, I’ve created the FreeBSD port for acme.sh (an ACME client for Let’s Encrypt) and anvil, a tool for distributing and installing those certificates.
In previous blog posts, I’ve described various steps leading up to this:
- Creating a TXT only nsupdate connection for Let’s Encrypt
- Configuring my BIND/named DNS servers to operate from a hidden master via VPN for Let’s Encrypt
- acme.sh: getting free SSL certificates – installation configuration on FreeBSD
- Introducing anvil – Tools for distributing ssl certificates
- cert-shifter: copying certificates from acme.sh to a fresh directory
- anvil – copying the certificates to the website
In this post, I will describe how I configured cert-puller to download & install certificates, and then restart services.
Installing anvil
This will need to be done on every host which you want to install the certificates.
I installed anvil from a FreeBSD package:
pkg install anvil
The anvil package installs the anvil user:
$ grep anvil /etc/passwd anvil:*:217:217:anvil certificate dropper:/var/empty:/usr/sbin/nologin
The cert-puller script supplied by the anvil package will run as that user.
Configuration file
The cert-puller configuration file is /usr/local/etc/anvil/cert-puller.conf. Here are the default values. They are closely connected to the default values for the acme.sh port.
CERT_SERVER="https://certs.example.org/certs" MYCERTS="services.example.org" SERVICES="nginx"
Let’s look at each one of those values.
- CERT_SERVER – This is the URL to the webserver. The certificates will be available from this directory.
- MYCERTS – A space separated list of the domains to be downloaded and installed.
- SERVICES – The list of services to be restarted. e.g. apache
visudo
cert-puller uses sudo to copy files around. It does with without authentication but it can also show you exactly what commands it will run, provided the configuration file is correctly set up.
Here is what I was shown when I was setting up one of my Nagios servers:
[dvl@nagios02:~] $ cert-puller -s anvil ALL=(ALL) NOPASSWD:/bin/cp -a /var/db/anvil/ca.cer /usr/local/etc/ssl/ca.cer.tmp anvil ALL=(ALL) NOPASSWD:/bin/mv /usr/local/etc/ssl/ca.cer.tmp /usr/local/etc/ssl/ca.cer anvil ALL=(ALL) NOPASSWD:/bin/cp -a /var/db/anvil/nagios02.example.org.cer /usr/local/etc/ssl/nagios02.example.org.cer.tmp anvil ALL=(ALL) NOPASSWD:/bin/mv /usr/local/etc/ssl/nagios02.example.org.cer.tmp /usr/local/etc/ssl/nagios02.example.org.cer anvil ALL=(ALL) NOPASSWD:/bin/cp -a /var/db/anvil/nagios02.example.org.fullchain.cer /usr/local/etc/ssl/nagios02.example.org.fullchain.cer.tmp anvil ALL=(ALL) NOPASSWD:/bin/mv /usr/local/etc/ssl/nagios02.example.org.fullchain.cer.tmp /usr/local/etc/ssl/nagios02.example.org.fullchain.cer anvil ALL=(ALL) NOPASSWD:/usr/sbin/service apache24 graceful
I copied the above, ran sudo visudo, and pasted. Done.
You might also need to make some changes to your configuration files in case your certificate and key file names do not match what anvil provides.
Copy the .key file
anvil does not distribute key files. This is a design decision, based on security choices.
You must copy the .key file manually. You only need to do this once, when first configuring anvil.
The anvil crontab
Here is the crontab I installed in order to run cert-puller:
# use /bin/sh to run commands, overriding the default set by cron SHELL=/bin/sh # mail any output to here, no matter whose crontab this is MAILTO=you@example.org 44 14 * * * /usr/local/bin/cert-puller
Adjust the time to suit your situation.
The logging
After doing the above configuration, I watched /var/log/messages, where the following magically appeared:
Jul 16 14:44:00 nagios02 cert-puller: starting /usr/local/bin/cert-puller Jul 16 14:44:00 nagios02 cert-puller: fetching into /var/db/anvil Jul 16 14:44:00 nagios02 cert-puller: checking certs for nagios02.unixathome.org Jul 16 14:44:00 nagios02 cert-puller: nagios02.unixathome.org :: ca.cer Jul 16 14:44:00 nagios02 cert-puller: nagios02.unixathome.org :: nagios02.unixathome.org.cer Jul 16 14:44:00 nagios02 cert-puller: nagios02.unixathome.org :: nagios02.unixathome.org.fullchain.cer Jul 16 14:44:00 nagios02 cert-puller: looking for cert files: /usr/bin/find /var/db/anvil -type f Jul 16 14:44:00 nagios02 cert-puller: validating nagios02.unixathome.org.cer Jul 16 14:44:00 nagios02 cert-puller: nagios02.unixathome.org.cer does not exist and will be installed Jul 16 14:44:00 nagios02 cert-puller: installing nagios02.unixathome.org.cer Jul 16 14:44:00 nagios02 cert-puller: validating ca.cer Jul 16 14:44:00 nagios02 cert-puller: ca.cer does not exist and will be installed Jul 16 14:44:00 nagios02 cert-puller: installing ca.cer Jul 16 14:44:00 nagios02 cert-puller: validating nagios02.unixathome.org.fullchain.cer Jul 16 14:44:00 nagios02 cert-puller: nagios02.unixathome.org.fullchain.cer does not exist and will be installed Jul 16 14:44:00 nagios02 cert-puller: installing nagios02.unixathome.org.fullchain.cer Jul 16 14:44:00 nagios02 cert-puller: doing a graceful on apache24 Jul 16 14:44:00 nagios02 cert-puller: stopping /usr/local/bin/cert-puller
Done
That was it. I checked the certificate in my browser, and it was the newly minted one from Let’s Encrypt.
I hope you find this useful. I have yet to complete my full deployment, and I know I have more work to do on this project.