Getting acme.sh to renew certs via cronjob on FreeBSD

In the past, I’ve written about using acme.sh to automatically generate SSL certificates and distribute them to the required locations. I do this in a single central location, and the websites and mail servers grab their new certs from a webserver.

At the time of writing, I was using FreeBSD 11.1 and acme.sh 2.7.4, supplied by the FreeBSD port, in a jail.

Nagios warned me that one of my Let’s Encrypt certificates was up for renewal.

SSL WARNING - Certificate 'certs.example.org' expires in 28 day(s) (2017-10-02 19:38 +0000/UTC). 

I was wondering why acme.sh had not renewed the cert automagically.

I checked the crontab for acme:

$ sudo crontab -l -u acme
# 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=dan@langille.org

25 9 * * * /usr/local/sbin/acme.sh --cron --home "/var/db/acme" > /dev/null

Yeah, that looked good to me. I added –debug for more information and removed the redirect to /dev/null. The email which arrived showed me:

[Sun Sep  3 21:18:00 UTC 2017] Lets find script dir.
[Sun Sep  3 21:18:00 UTC 2017] _SCRIPT_='/usr/local/sbin/acme.sh'
[Sun Sep  3 21:18:00 UTC 2017] _script='/usr/local/sbin/acme.sh'
[Sun Sep  3 21:18:00 UTC 2017] _script_home='/usr/local/sbin'
[Sun Sep  3 21:18:00 UTC 2017] Using config home:/var/db/acme
https://github.com/Neilpang/acme.sh
v2.7.4
[Sun Sep  3 21:18:00 UTC 2017] Using config home:/var/db/acme
[Sun Sep  3 21:18:00 UTC 2017] ===Starting cron===
[Sun Sep  3 21:18:00 UTC 2017] Using config home:/var/db/acme
[Sun Sep  3 21:18:00 UTC 2017] _stopRenewOnError
[Sun Sep  3 21:18:00 UTC 2017] di='/var/db/acme/*.*/'
[Sun Sep  3 21:18:00 UTC 2017] Not directory, skip: /var/db/acme/*.*/
[Sun Sep  3 21:18:00 UTC 2017] ===End cron===

There’s the problem. It is not find any any certs. If I try that manuallly, I get:

$ ls -l /var/db/acme/*.*/
ls: /var/db/acme/*.*/: No such file or directory

The config home is wrong.

I changed the crontab to this instead:

$ sudo crontab -l -u acme
# 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=dan@langille.org

7 22 * * * /usr/local/sbin/acme.sh --cron --accountconf /var/db/acme/.acme.sh/account.conf
# > /dev/null

NOTE: recently I have changed the above cronjob to:

7 22 * * * /usr/local/sbin/acme.sh --cron --home /var/db/acme/.acme.sh

re: Author’s advice.

That account.conf file is in the standard location for the FreeBSD port. I am not sure if I could remove the –accountconf parameter altogether. Clearly, –home was incorrect and was a leftover from my copy/paste from the documents.

Now the cronjob ran, and went through the usual renewal process. However, it failed with:

Verify error:DNS problem: NXDOMAIN looking up TXT for _acme-challenge.certs.example.org

I looked at the NS records for the domain in question and noticed that one of them was not mine; it was third party. I removed that name server reference by using my domain service provider’s interface. After that, a whois example.org no longer showed that NS record. This was followed up by deleting the NS from the zone file.

The next run of acme.sh was successful and a new cert was issued. Over the next 24 hours, that cert will propagate to my certification distribution website, and from there, the website in question will eventually notice it, pull it down, and install it, via anvil.

I will be watching that process, and so will Nagios.

Hope this helps.

EDIT: 2017-09-05

I noticed a problem on the client, where I am using cert-puller. The cert-puller.conf file did not specify the certificate in question. That is, the certificate was in use, but it was not specified in the configuration file. That situation arose because said certificate is for the website which distributes certificates for my clients. Thus, it was originally installed by hand.

I amended /usr/local/etc/anvil/cert-puller.conf but because I did not also run cert-puller -s and then update the sudoers file, the next attempt to update failed:

Sep  5 15:12:00 web01 sudo:    anvil : command not allowed ; TTY=unknown ; PWD=/var/db/anvil ; USER=root ; COMMAND=/bin/cp -a /var/db/anvil/certs.example.org.fullchain.cer /usr/local/etc/ssl/certs.example.org.fullchain.cer.tmp
Sep  5 15:12:00 web01 sudo:    anvil : command not allowed ; TTY=unknown ; PWD=/var/db/anvil ; USER=root ; COMMAND=/bin/mv /usr/local/etc/ssl/certs.example.org.fullchain.cer.tmp /usr/local/etc/ssl/certs.example.org.fullchain.cer

I also had to do some chown anvil:anvil magic on the existing file, and a chmod to get it all writable by the anvil user and readable by Apache.

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

Leave a Comment

Scroll to Top