Update: There is a deployment hook now for deploying the issued certificates to your Synology NAS, which provides an even more elegant solution. Have a look at the acme.sh
wiki entry or at my blog post for details: https://lippertmarkus.com/2020/03/14/synology-le-dns-auto-renew/
Python script for automatically renewing Let's Encrypt certificates on Synology NAS using DNS-01 challenge. Also supports wildcard certificates.
More sophisticated way of the bash script in the acme.sh wiki (which helped me a lot!) with the following features/improvements:
- Automatically finds the main certificate folder under
/usr/syno/etc/certificate/_archive/
- Only replaces certificates with the correct domain name in the certificate subject instead of replacing all certificates of all apps. Using
openssl
already installed on Synology NAS for finding out certificate subject name. - Supports environments using multiple certificates as well as Synology Directory Server without causing problems
- Uses
rsync
already installed on Synology NAS to keep permissions like they should be - Automatically restarts nginx for DSM, Reverse Proxy and other system apps as well as normal applications as needed
- DSM on Synology NAS natively only supports issuing and renewing certificates via HTTP-01, but not the DNS-01 challenge of Let's Encrypt.
- If your NAS is not connected to the Internet, you don't want to open port 80 or you want to use wildcard certificates, you would need to use the DNS-01 challenge of Let's Encrypt.
- Although you can issue a certificate via the command line, import it via DSM and use it for the Synology apps, automatically renewing it is a bit tricky. Because every app has a seperate copy of the certificate you need to find all those locations and replace the certificate with the renewed one.
Various guides (e.g. this one) explain the manual way of importing and renewing the certificate. The only script to automate the renewal I found is described in the wiki of acme.sh. The provided bash script however has a few drawbacks in my opinion:
- You need to manually find the main certificate directory under
/usr/syno/etc/certificate/_archive/
. Although this is a one-time task, it can be time consuming if you have multiple certificates. - It replaces all certificates of all apps with the renewed certificate. E.g. if you have an app
App1
using a cert forexample1.com
and another appApp2
using a cert forexample2.com
and then use the bash script to renew the cert forexample2.com
you'll end up with both apps now having the cert forexample2.com
.
Detailed explanation will be available soon.
Short version:
-
Install
acme.sh
on your Synology NAS:sudo -i wget https://github.com/acmesh-official/acme.sh/archive/master.tar.gz tar xfv master.tar.gz cd acme.sh-master/ ./acme.sh --install --nocron --home /usr/local/share/acme.sh --accountemail "[email protected]" # ignore socat warning
-
Issue certificate like normally:
cd /usr/local/share/acme.sh # set environment variables and used dns according to your used DNS API before issuing, see https://github.com/acmesh-official/acme.sh/wiki/dnsapi ./acme.sh --issue -d "*.example.com" --dns dns_doapi --force # ... # copy cert files for importing via DSM, e.g. to a share cp -R /usr/local/share/acme.sh/*.example.com/ /volume1/myshare/mycert/
-
Import certificate via DSM and configure apps to use it.
-
Install and test the script:
mkdir /usr/local/share/le-renew wget -P /usr/local/share/le-renew/ https://raw.githubusercontent.com/lippertmarkus/synology-le-dns-auto-renew/master/renew.py python3 /usr/local/share/le-renew/renew.py *.example.com dns_doapi
If you're cautios you can set
DRY = True
at the beginning of the script to do a dry run without applying any changes to any files and without really renewing the cert. The output shows which files would be overwritten. -
Create a recurring task via DSM to run the script as root (don't directly set up a cronjob as the DSM security advisor will give you a warning).
✔✔✔ Found cert for *.example.com under /usr/syno/etc/certificate/_archive/aBcDef ✔✔✔
♦♦♦ RENEW CERT ♦♦♦
[Tue Mar 3 18:53:06 CET 2020] Renew: '*.example.com'
# ...
[Tue Mar 3 18:53:14 CET 2020] Installing cert to:/usr/syno/etc/certificate/_archive/aBcDef/cert.pem
# ...
♦♦♦ WORKING ON SYSTEM APPS ♦♦♦
🔧 Copying from /usr/syno/etc/certificate/_archive/aBcDef/ to /usr/syno/etc/certificate/ReverseProxy/9f6f23dc-90a1-4e08-a99b-f9a4ffe96ca7/
sending incremental file list
cert.pem
chain.pem
fullchain.pem
privkey.pem
sent 9.09K bytes received 88 bytes 18.35K bytes/sec
total size is 8.82K speedup is 0.96
♦♦♦ RELOADING NGINX ♦♦♦
nginx reloaded.
♦♦♦ WORKING ON OTHER APPS ♦♦♦
📀 VPNCenter
🔧 Copying from /usr/syno/etc/certificate/_archive/aBcDef/ to /usr/local/etc/certificate/VPNCenter/OpenVPN/
sending incremental file list
cert.pem
chain.pem
fullchain.pem
privkey.pem
sent 9.09K bytes received 88 bytes 6.12K bytes/sec
total size is 8.82K speedup is 0.96
🔧 Restarting VPNCenter
package VPNCenter restart successfully