letsencrypt/QNAP remote ssl cert update bash script

In my home environment, I was already using letsencrypt certs on my local webserver.  I also have a QNAP NAS device that I wanted to use the cert on.  Since letsencrypt certs have such a short valid period, it would be highly inconvenient to update the certs via the web UI by hand every time they expired.

My webserver is exposed to the internet, which makes it easier to just group in the NAS’s domain name with the certs that get renewed from the webserver due to the way letsencrypt renewals work.

After a bit of research, I found a way to remotely update the certs on the QNAP device via scp and ssh.   The script below is what I came up with for my own use.  With minor modifications, I hope that others may find it useful as well.  In order to use it, you need to already have the server it runs on (not your NAS device itself) setup for letsencrypt and have already registered a cert.   It will not update the NAS by default if the cert isn’t within 48 hours of expiration.  You can override this by passing the –force option.  It still won’t renew the cert, but it will restart the local httpd and update the NAS device’s cert.  You should only normally need to do this the first time.  I symlinked it into /etc/cron.daily so that it is completely hands off.

#!/bin/bash

#
#  Script to renew letsencrypt, restart httpd to pick up new certs, and apply new
#  cert to a QNAP NAS device.  User running script must have its public key added
#  to the nas admin account's authorized_keys file.
#
#  It is designed not to use the letsencrypt/certbot webserver plugins, as some
#  distros lack that capability.
#

# Path to letsencrypt/certbot
LE="/usr/bin/certbot"

# Email address
EMAIL="me@mydomain.com"

# Domains to grab cert for
DOMAINS="mydomain.org,www.mydomain.org,nas.mydomain.org"

# Path to letsencrypt cert files
CERTPATH="/etc/letsencrypt/live/mydomain.org"

# QNAP NAS hostname or IP
NASHOST="nas.mydomain.org"



openssl x509 -checkend 172800 -noout -in ${CERTPATH}/cert.pem
if [[ $? -eq 0 ]] && [[ "${1}" != "--force" ]]; then
        echo "Certificate will not expire in the next 48 hours.  Renewal not required."
else
        echo "Certificate will expire in under 48 hours.  Renewing cert and restarting services."
        /usr/bin/systemctl stop httpd
        ${LE} --text --email ${EMAIL} --keep-until-expiring --domains ${DOMAINS} --agree-tos --standalone certonly
        /usr/bin/systemctl start httpd

        echo "Setting cert on QNAP device and restarting required services"
        cat ${CERTPATH}/privkey.pem > /tmp/stunnel.pem
        cat ${CERTPATH}/cert.pem >>/tmp/stunnel.pem
        scp /tmp/stunnel.pem admin@${NASHOST}:/etc/stunnel/stunnel.pem &>/dev/null
        ssh admin@${NASHOST} chmod 600 /etc/stunnel/stunnel.pem &>/dev/null
        ssh admin@${NASHOST} /etc/init.d/Qthttpd.sh stop &>/dev/null
        ssh admin@${NASHOST} /etc/init.d/stunnel.sh restart &>/dev/null
        ssh admin@${NASHOST} /etc/init.d/Qthttpd.sh start &>/dev/null
        rm -f /tmp/stunnel.pem
fi
renewCerts.sh