This site runs best with JavaScript enabled.

Wildcard Let's Encrypt SSL Cert on Synology NAS

Wildcard Let's Encrypt SSL Cert on Synology NAS Wildcard Let's Encrypt SSL Cert on Synology NAS

Thanks to this post on vdr.one I was able to set up a wildcard Let's Encrypt Cert on my Synology NAS.

The problem is I have to manually renew every 3 months which involves setting a new TXT record on my DNS and remembering the steps to renew.

After more research, I found a way to automate the renewal of my wildcard DNS. It does require a DNS server with API access. It turns out there are lots of options on the acme.sh wiki.

It would be nice if I could use GoDaddy or NameCheap, where I have most of my domains, but this particular domain is hosted with iwantmyname. It looks like there is no support in acme.sh for iwantmyname, but iwantmyname does have an API for adding a TXT record.

Luckily, acme.sh has provided a solution to use my own API, so that is what I'll do!

First, let's log into the NAS via ssh and install acme.sh

sudo -i
wget https://github.com/Neilpang/acme.sh/archive/master.tar.gz
tar xvf master.tar.gz
cd acme.sh-master/
./acme.sh --install --nocron --home /usr/local/share/acme.sh --accountemail "letsencryptemail@sample.com"

Now we'll create the script that will created our TXT record on iwantmyname. (If you use some other DNS service that is already supported, you can skip this step and replace dns_iwmn with whatever DNS service you are using.)

touch /usr/local/share/acme.sh/dnsapi/dns_iwmn.sh
chmod +x /usr/local/share/acme.sh/dnsapi/dns_iwmn.sh
vim /usr/local/share/acme.sh/dnsapi/dns_iwmn.sh

I added the following to this script:

#!/usr/bin/env sh

# Guide: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide

#Usage: dns_iwmn_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_iwmn_add() {
  local fulldomain=$1
  local txtvalue=$2
  _info "Using iwantmyname"
  _debug fulldomain "$fulldomain"
  _debug txtvalue "$txtvalue"
  curl -u "$IWMN_EMAIL:$IWMN_PASSWORD" "https://iwantmyname.com/basicauth/ddns?hostname=$fulldomain&type=txt&value=$txtvalue"
}

#Usage: fulldomain
#Remove the txt record after validation.
dns_iwmn_rm() {
  local fulldomain=$1
  _info "Using iwantmyname"
  _debug fulldomain "$fulldomain"
  curl -u "$IWMN_EMAIL:$IWMN_PASSWORD" "https://iwantmyname.com/basicauth/ddns?hostname=$fulldomain&type=txt&value=delete"
}

Now, let's run the following the command to issue the wildcard cert:

export CERT_DOMAIN="*.mydomain.tld"
export IWMN_EMAIL="iwantmynameemail@sample.com"
export IWMN_PASSWORD="iwantmyname-password"
/usr/local/share/acme.sh/acme.sh --issue -d $CERT_DOMAIN --dns dns_iwmn \
  --certpath /usr/syno/etc/certificate/system/default/cert.pem \
  --keypath /usr/syno/etc/certificate/system/default/privkey.pem \
  --fullchainpath /usr/syno/etc/certificate/system/default/fullchain.pem \
  --capath /usr/syno/etc/certificate/system/default/chain.pem \
  --dnssleep 20 \
  --config-home "/path/to/save/acmeconfigs/"

I found that after renewing a cert that my main domain pointing to my control panel worked, but all my other reverse proxy subdomains were still pointing to the expired certificate. After digging around I found the /usr/syno/etc/certificate/ReverseProxy directory. I added the following to my script:

cd /usr/syno/etc/certificate/ReverseProxy/
ls -d $PWD/* | xargs -n 1 cp -v /usr/syno/etc/certificate/system/default/*.pem

This basically copies my renewed cert to each of my reverse proxy certificates directories.

So the full script now looks like this:

export CERT_DOMAIN="*.mydomain.tld"
export IWMN_EMAIL="iwantmynameemail@sample.com"
export IWMN_PASSWORD="iwantmyname-password"
/usr/local/share/acme.sh/acme.sh --issue -d $CERT_DOMAIN --dns dns_iwmn \
  --certpath /usr/syno/etc/certificate/system/default/cert.pem \
  --keypath /usr/syno/etc/certificate/system/default/privkey.pem \
  --fullchainpath /usr/syno/etc/certificate/system/default/fullchain.pem \
  --capath /usr/syno/etc/certificate/system/default/chain.pem \
  --dnssleep 20 \
  --config-home "/path/to/save/acmeconfigs/" && \
cd /usr/syno/etc/certificate/ReverseProxy/ && \
ls -d $PWD/* | xargs -n 1 cp -v /usr/syno/etc/certificate/system/default/*.pem && \
cd -

Now I just run this script regularly by adding the following to /etc/crontab to keep the cert renewed:

0 2 */10 * *  root  /path/to/cert_install.sh >/dev/null 2>&1

NOTE: When I add a new reverse proxy, I need to copy the wildcard cert to the new reverse proxy directory. Because I don't know what the directory name is exactly, I just put the snippet above (added again below) in a script named update-reverse-proxies.sh and it will copy the wild copy the cert to all the reverse proxies again.

cd /usr/syno/etc/certificate/ReverseProxy/
ls -d $PWD/* | xargs -n 1 cp -v /usr/syno/etc/certificate/system/default/*.pem

💥👊

Share article
Dustin Davis

Dustin Davis is a software engineer, people manager, hacker, and entreprenuer. He loves to develop systems and automation. He lives with his wife and five kids in Utah.