Earlier in the year I wrote about getting Let’s Encrypt on my router where I grab a certificate from another system and drop it in a shared folder. That solution was…not ideal, and recently SMB shares stopped mounting on the router with some obscure CIFS error code. I suspect it has something to do with me disabling SMBv1 everywhere (for good reasons).
Turns out that whole drop it in a shared folder and retrieve it on the other system thing was overly complicated for nothing. The current solution I am using is much simpler: have the remote server use good old
scp to push the certificate to the router, then pipe the update script via
ssh to the router. This requires no scheduled script on the router, and the certificate is updated as soon as
certbot spits out a new certificate.
First, let’s head back to where we previously installed
/opt/dehydrated and edit our CloudFlare script. Note that at the time of writing, it looks like the official Certbot client is adding built-in support for CloudFlare, meaning the dehydrated method might no longer be necessary.
#!/usr/bin/env bash export CF_EMAIL='<cloudflare email>' export CF_KEY='<cloudflare key>' /opt/dehydrated/dehydrated \ --cron \ --domain router.example.com \ --challenge dns-01 \ --hook '/opt/dehydrated/hooks/cloudflare/hook.py' EPSILON=300 CERT=/opt/dehydrated/certs/router.example.com/fullchain.pem KEY=/opt/dehydrated/certs/router.example.com/privkey.pem TIMESTAMP=$(stat $CERT -c %Y) DIFF=$(expr $(date +%s) - $TIMESTAMP) if [ $DIFF -lt $EPSILON ]; then logger "certbot] A new cert has been created, uploading" scp -i /path/to/id_file $CERT [email protected]:/tmp/etc/cert.pem scp -i /path/to/id_file $KEY [email protected]:/tmp/etc/key.pem logger "[certbot] Triggering certificate update on remote" ssh -i /path/to/id_file [email protected] 'sh -s' < /opt/dehydrated/router.example.com.update.sh else logger "[certbot] Cert valid" fi
The contents of
router.example.com.update.sh being the same as the scheduled script that was previously running on the router, except that now it is triggered from the remote server.
#!/bin/sh logger "[certbot] New cert found, updating" tar -C / -czf /tmp/cert.tgz /tmp/etc/cert.pem /tmp/etc/key.pem nvram setfb64 https_crt_file /tmp/cert.tgz nvram commit logger "[certbot] Restarting httpd" service httpd restart rm /tmp/cert.tgz
root isn’t really ideal, but this is running from the local network so I guess that can be accepted.
Of course, even easier would be to run the
certbot client locally on the router via Entware/Optware if the router supports it, but this method only requires the remote server to have
scp so it could technically work for pushing certificates to a printer’s web admin server…