2021-02-08
Checking certificates for expiry time left to determine renewal
I recently almost had an expired certificate for a public service because I did some fiddling with the file and ended up with a file modified time which had no relationship to the certificate request time. Time to use the -checkend option I noticed in openssl x509 to test the actual certificates for upcoming expiry. So I redid the cronjob around dehydrated to do just that and had a cleanup. A candidate list of certificates to renew is created from certificates that are about to expire, certificates that have a changed certificate signing request and certificates for which there is only a signing request. That list is sorted and deduplicated and fed to calls to dehydrated. It's now one script for both certificates that are renewed via the http-01 method and for certificates that are renewed via dns-01. By now both methods work fine for me, it depends on the use of the name which is fitting. The updated script. Triggers are now on seconds left and not on days old.
#!/bin/sh cd $HOME AGERENEW=60 AGEERROR=67 # renew at less than 30 days left MINSECONDSLEFT=2592000 # error bij less than 23 days left ERRORSECONDSLEFT=1987200 RENEWABLESLIST=tmp/renewables.tmp RENEWABLESFINAL=tmp/renewables # httprenewables # clear list > $RENEWABLESLIST # time to renew find httprenewable -name \*crt | while read -r crt do csr=${crt%.crt}.csr # check for certificate needing renewal openssl x509 -in $crt -noout -checkend $MINSECONDSLEFT > /dev/null if [ $? -ne 0 ]; then echo $crt >> $RENEWABLESLIST fi # check for newer csr if [ ${csr} -nt ${crt} ]; then echo $crt >> $RENEWABLESLIST fi done # csr without crt find httprenewable -name \*csr | while read -r csr do crt=${csr%.csr}.crt if [ \! -f ${crt} ]; then echo $crt >> $RENEWABLESLIST fi done # deduplicate, just to not overload letsencrypt sort -u < $RENEWABLESLIST > $RENEWABLESFINAL cat $RENEWABLESFINAL | while read -r crt do csr=${crt%.crt}.csr if [ -f ${csr} ]; then echo Will renew $csr to $crt ./dehydrated/dehydrated -t http-01 -s $csr > tmp/certificate.crt if [ $? -eq 0 ]; then cp tmp/certificate.crt $crt rm tmp/certificate.crt fi else echo WARNING: $crt without $csr fi done # dnsrenewables # clear list > $RENEWABLESLIST # time to renew find dnsrenewable -name \*crt | while read -r crt do csr=${crt%.crt}.csr # check for certificate needing renewal openssl x509 -in $crt -noout -checkend $MINSECONDSLEFT > /dev/null if [ $? -ne 0 ]; then echo $crt >> $RENEWABLESLIST fi # check for newer csr if [ ${csr} -nt ${crt} ]; then echo $crt >> $RENEWABLESLIST fi done # csr without crt find dnsrenewable -name \*csr | while read -r csr do crt=${csr%.csr}.crt if [ \! -f ${crt} ]; then echo $crt >> $RENEWABLESLIST fi done # deduplicate, just to not overload letsencrypt sort -u < $RENEWABLESLIST > $RENEWABLESFINAL cat $RENEWABLESFINAL | while read -r crt do csr=${crt%.crt}.csr if [ -f ${csr} ]; then echo Will renew $csr to $crt ./dehydrated/dehydrated -t dns-01 -k /home/dehydrated/bin/dehydrated-nsupdate -s $csr > tmp/certificate.crt if [ $? -eq 0 ]; then cp tmp/certificate.crt $crt rm tmp/certificate.crt fi else echo WARNING: $crt without $csr fi done # now check for leftovers find httprenewable -name \*crt | while read -r crt do # check for certificate past due openssl x509 -in $crt -noout -checkend $ERRORSECONDSLEFT > /dev/null if [ $? -ne 0 ]; then echo ERROR: $crt expiring in less than $ERRORSECONDSLEFT seconds fi done find dnsrenewable -name \*crt | while read -r crt do # check for certificate past due openssl x509 -in $crt -noout -checkend $ERRORSECONDSLEFT > /dev/null if [ $? -ne 0 ]; then echo ERROR: $crt expiring in less than $ERRORSECONDSLEFT seconds fi done # cleanup rm $RENEWABLESLIST rm $RENEWABLESFINAL