I’ve been trying to setting up DDNS for my QNAP NAS with SSL connection. I don’t want to use the QNAP Cloudlink DDNS service because I wanted to use QVPN service to globally gate all traffic going out from QNAP. And that disables the QNAP Cloudlink service from getting the real IP address for my NAS.

The basic logic goes along this tutorial: How to set up a free dynamic hostname with SSL cert using Google Domains, except the following moving parts:

Below is my NAS setup:

  1. QNAP running QVPN client, all outgoing traffic behind VPN provider.
  2. DD-WRT router running EntWare, with cron script running as DDNS client.
  3. getssl running as another cron job on the router, automatically renews certificates and upload them to QNAP NAS and restarts the web server on NAS.

The main issues I faced was to configure getssl to upload and run the correct commands to update my QNAP NAS, and below are the key code snippets that made QNAP use my DDNS certificates instead of its default QNAP certificates:

# per-domain getssl.cfg
# Need to create this directory on QNAP manually first, otherwise getssl will
# fail.
ACL=('ssh:admin@<qnap>:/home/httpd/.well-known/acme-challenge')
...
# Location for all your certs, these can either be on the server (full path name)
# or using ssh/sftp as for the ACL
DOMAIN_CERT_LOCATION="ssh:admin@<qnap>:/etc/stunnel/getssl.cert.def"
DOMAIN_KEY_LOCATION="ssh:admin@<qnap>:/etc/config/stunnel/getssl.key.def"

And below is the cron job that I’m setting up to run every day:

#!/usr/bin/env bash
# Let's Encrypt automatic renew cron script.
getssl <your-domain-here> && \
ssh admin@<qnap> \
'/etc/init.d/stunnel.sh generate_cert_key && /etc/init.d/stunnel.sh restart'

And now I see that QNAP’s “Security” administration page show the Let’s Encrypt certificate instead of QNAP’s default one: