Last Updated on December 30, 2024 by Thiago Crepaldi
In this article we are going install Let’s Encrypt SSL certificates on a Synology NAS, but with a twist! The certificates are actually issued by pfSense, which is in the edge of our Internet setup, and then reused by Synology NAS too.
Configure pfSense
In short, you have to use pfSense to issue a certificate for Synology, copy the certificate to the Synology storage and then configure DSM to use it. As an additional step, we will configure a cron schedule so that the certificates are copied and reinstalled periodically to prevent manual reconfiguration when the Let’s Encrypt certificate expire.
Assuming you have followed the tutorial to create the certificate for your Synology device on your pfSense, we have to export it on pfSense so that we can import it on DSM.
On your pfSense, go to System >> Certificate Manager >> Certificates. You should see a list of certificates, including all issued by Let’s Encrypt. Find the one that was created for the Synology, click on Export certificate to download a file with *.crt extension and then click on Export key to download a file with *.key extension. That is all you need from your pfSense.
Chained router consideration
You might be wondering what we have to do to make this work, when your Synology NAS is behind two routers as described in this post. Fortunately, we have to do nothing about it. Everything should work out of the box, as devices behind the chained routers have direct access to the devices connected to both routers. The reciprocal is not true, however, meaning that devices connected to the first router (the one closest to the Internet) can’t connect to the devices behind the second router.
Configure Synology NAS
Synology DSM comes with a self-signed certificate. We are going to manually install a Let’s Encrypt certificate and then automate the renewal process through scheduled tasks.
Import Let’s Encrypt certificate from pfSense
Now that you have your Certificate (*.crt file) and Key (*.key file), go to your Synology UI, login and click on Control Panel >> Security >> Certificates and click on Add.
A wizard will be presented. As the first step, choose Add a new certificate and click on Next.
In the next screen, fill in a meaningful Description (e.g. Let’s Encrypt certificate from pfSense), choose on Import a certificate and check Set as default certificate to replace the existing self-signed certificate and go to the Next step.
On the Private key field, click on Browse and select the *.key file exported from pfSense. For the Certificate field, click on Browse and select your *.crt file. Leave Intermediate certificate blank and click on OK to finish.
You should see your certificate now installed on your Synology. Click on Configure, make sure your new certificate is selected for all Services and click on Ok button to save. Refresh your browser to see your new SSL certificate in action!
Automate certificate renewal
IMPORTANT DISCLAIMER: If you visited this post before, you noticed that the actual scripts that do the copying and installation of the Let’s Encrypts certificates are not in here anymore. Instead, I am using my Homelab Utility Belt repo which has this and other scripts. If you want to learn how they do their magic, look at their code here. The idea is to abstract away such complexities and make easier for automate common tasks!
Create a share folder on Synology
You must have noticed that you used certificates stored on your local computer to install on your Synology. This is fine for a first time setup, but as Let’s Encrypt expires every 90 days, we need to automate the renewal process.
Still on your Synology, go to Control Panel >> Shared Folder and click on Create. This will present a new wizard, which should be filled in as follows:
- Name: LetsEncrypt
- Description: Let’s Encrypt certificates from pfSense
- Location: Here in you select the best volume. Volume 1 is the default.
- Hide this shared folder in “My network places”: checked
- Hide sub-folders and files from user without permissions: checked
- Enable Recycle bin: checked
- Restrict access to administrators only: checked
In the Next screen, you have to uncheck the Encrypt this shared folder. Click on Next button and uncheck both Enable data checksum for advanced data integrity and Enable shared folder quota. Once more click on Next to get to the summary screen and click on Apply and then on OK to finish.
Import Let’s Encrypt certificate to the Synology Shared folder on a schedule
With a shared-folder in place, we are going to create a scheduled tasks that will first copy the SSL certificates from pfSense into Synology’s shared folder and then install it over the current Let’s Encrypt certificate and restart DSM. Go to System >> Task Scheduler >> Create >> Scheduled task >> User-defined script and do as follows:
General
- Task: Copy Let’s Encrypt Certificate from pfSense
- User: Select root as user and make sure it has SSH key installed that allows access to pfSense
Schedule
- Run on the following days: Pick one day of the week at your choice
- First run time: Again, pick your own time, preferably when your are sleeping and the device is powered on
- Frequency: Every day
Task settings
User-defined script: use the following template to create one folder inside your shared-folder for each certificate
########################################################
# THIS IS THE ONLY PLACE YOU NEED TO EDIT
########################################################
LETSENCRYPT_SHARE="/volume1/LetsEncrypt"
CERTIFICATE_NAME="SynologyLE"
PFSENSE_PORT="22"
PFSENSE_USER="synouser"
PFSENSE_HOSTNAME="mypfsense.lan.example.com"
########################################################
# YOU DO NOT HAVE TO WORRY ABOUT THE CODE BELOW
########################################################
# Downloading LetsEncrypt certificate importer scripts
cd ${LETSENCRYPT_SHARE}
CERT_INSTALLER_SCRIPT="install_letsencrypt_cert_from_pfsense.sh"
CERT_COPY_SCRIPT="copy_letsencrypt_cert_from_pfsense.sh"
wget https://raw.githubusercontent.com/thiagocrepaldi/homelab-utility-belt/main/synology/install_letsencrypt_cert_from_pfsense.sh -O ${CERT_INSTALLER_SCRIPT}
wget https://raw.githubusercontent.com/thiagocrepaldi/homelab-utility-belt/main/synology/copy_letsencrypt_cert_from_pfsense.sh -O ${CERT_COPY_SCRIPT}
# Import a new Synology certificate
bash ${CERT_COPY_SCRIPT} -s ${LETSENCRYPT_SHARE} -n ${CERTIFICATE_NAME} -p ${PFSENSE_PORT} -u ${PFSENSE_USER} -h ${PFSENSE_HOSTNAME}
bash ${CERT_INSTALLER_SCRIPT} -s ${LETSENCRYPT_SHARE} -n ${CERTIFICATE_NAME}
# Remove scripts to egt new versions next time
rm -f ${CERT_INSTALLER_SCRIPT} ${CERT_COPY_SCRIPT}
After clicking OK your task will be created. Test it by selecting it, clicking on Run and after a few seconds (Synology web server will restart), go to File Station and check your certificate copied into your new shared folder. You can also check your web browser now uses the new certificate. That is it!
Hi , really nice idea but Your script to replace cert not working because it not contain proper path to copy certs from /volume1/LetsEncrypt/certname , It dos nothing in this case 🙂
Hi Lukasz, the certificate should be copied from pfSense in this step
However, there was a bug (now fixed) in the second schedule. I didn’t set SOURCE_CERT to the full path of the cert on the Synology, so that it would be installed on the DSM.
Please try again and let mer know how it goes!
Hi, that is what i was mentioned about , the path of Source_cert hadn’t been set.
Now it works good.
But if you have some certs which you are use on your synology, they will be replaced by this one from source_cert. I thing better solution is to update only certs you’ve imported not all of them.
Btw thanks for idea.
Lukasz, for some reason it only worked using the root account. First i used another admin account within the NAS but it was only possible to extract the files from pfsense using the NAS root account. There must be some differences even if all admin accounts are defined to be administrators. Perhaps Thiago have some idea (i guess he have)
I am glad it worked for you and yes, you are right. My scripts assumes all Synology services will use the LetsEncrypt certificate. You can tailor it to your need.
One thing that I would like to do through the script is register a Certificate to a particular Service, just like we can through the Web UI. unfortunately I didnt manage to do it yet, but it seems to be related to `synocrtregister` and `synocrtunregister` CLI binaries
For the scheduled job, you have to use root account. Is that part that you were referring to? In the section “Installing LetsEncrypt certificate at Synology DSM on a schedule” I specify “User: root” to indicate that. If that is not the case, let me know and I can try to help you.
First off, thanks so much for the guide. I was able to make it down to the last section Installing LetsEncrypt certificate at Synology DSM on a schedule before running into an issue. My task is
# Full path to the new certificate (*.pem)
SOURCE_CERT=/volume1/LetsEncrypt/server_name/cert.pem
# Existing certificates are replaced below
DEFAULT_CERT_ROOT_DIR=”/usr/syno/etc/certificate”
DEFAULT_ARCHIVE_CERT_DIR=”${DEFAULT_CERT_ROOT_DIR}/_archive”
DEFAULT_ARCHIVE_CERT_NAME=${DEFAULT_ARCHIVE_CERT_DIR}/$(cat ${DEFAULT_ARCHIVE_CERT_DIR}/DEFAULT)
EXISTING_CERT_FOLDERS=$(find /usr/syno/etc/certificate -path */_archive/* -prune -o -name cert.pem -exec dirname ‘{}’ \;)
for _dir in ${EXISTING_CERT_FOLDERS} ${DEFAULT_ARCHIVE_CERT_NAME}; do
echo “Replacing certificates from ${_dir}”
_certs=$(find ${_dir} -name “*.pem”)
for _cert in ${_certs}; do
echo “Replacing ${_cert} with ${SOURCE_CERT}”
cp -f ${SOURCE_CERT} ${_cert}
done
done
# Restart web server
synoservice –restart nginx
synoservice –restart nmbd
synoservice –restart avahi
After running this task and I check the cert, it actually appears to revert back to the synology cert. The only way for me to fix it is to go back in via ip address, go to certs and re upload the crt and key files.
If it helps, I am running opnsense, took me a while to find the files. The files do copy over and I was able to validate my cert.pem from opnsense using https://www.sslshopper.com/certificate-decoder.html.
Hi enoch, the very first time you have to install the certificates manually. For the renewals, synology already points to the Let’sEncrypt files, so replacing them should be enough. One thing that I noticed is that sometimes a NAS reboot is needed to really apply the change… just restarting the services doesn’t work.
Was that your issue?
Excellent post. Thanks a million for sharing it. Saved me a great deal of time.
Good information! This saved me a great deal of time and research.
Please note the correction below to make this work.
The script is replacing all .pem files with the contents from SOURCE_CERT file.
Change the following line from:
_certs=$(find ${_dir} -name “*.pem”)
to:
_certs=$(find ${_dir} -name “cert.pem”)
This change will only replace the cert.pem files with the contents from SOURCE_CERT file; and will no longer overwrite the private key and certificate chain.
Hello Vernon, thank you for the feedback! When copying over the.all.pem from pfSense ACME’s folder, the PEM file has the certificate, private key and certificate chain embedded on it, right? So replacing all three shouldn’t cause problems. Did you have a different experience?
By the way, I have create a “homelab-utility-belt” github repo which will have all this scripts and I will update all posts to use them. It will be easier for all to get newer/corrected versions of these scripts!
Instead of Task Scheduler, the pfSense Acme Certificates package allows you to automatically run a script after a certificate is renewed. Navigate to: Acme Certificates -> Certificates -> Edit Certificate -> Actions list.
The only problem with this method is if your Synology happens to be unavailable in the moment and the script fails.
Hi Kevin, yes. That is possible. One reason to use a Synology is availability, as you mentioned. A second is that pfSense’s shell script is more limited. You may not have tools you may want for this and other automation!
Hi, what about if i have several certificates. When i use the script it replaces the previous cert. The added copies/installed cert seems to replace the standard cert by default etc. Any ideas ?
Hi,
Can you elaborate a bit on these settings?
————–
LETSENCRYPT_SHARE=”/volume1/LetsEncrypt”
CERTIFICATE_NAME=”SynologyLE”
PFSENSE_PORT=”22″
PFSENSE_USER=”synouser”
PFSENSE_HOSTNAME=”mypfsense.lan.example.com”
————
* I have made the shared folder.
* I changed the CERTIFICATE_NAME to my domainname (for which I have the Lets Encrypt setup as you described in your other How-To (thanks for that BTW!)
* I don’t know exactly what to use in PFSENSE_USER. I tried the username I use to log into pfSense
* The PFSENSE_HOSTNAME I changed to “pfsense..com”
The result is that I dont see any files appear in the shared folder.
I can SSH into the Synology with the ‘SSH Lets_encrypt@’ just fine.
Hi Thiago,
Great site, enjoying working my way through your posts. Im trying to implement this one and getting a few different errors as below. Any suggestions? I’ve already followed the previous posts to install SSL certs on pfSense, import to Synology, and test they work, as well as transferring SSH keys (no passphrase set).
Task Scheduler has completed a scheduled task.
Task: Update SSL Certificate
Start time: Mon, 06 Sep 2021 18:04:10 GMT
Stop time: Mon, 06 Sep 2021 18:04:11 GMT
Current status: 0 (Normal)
Standard output/error:
–2021-09-06 18:04:10– https://raw.githubusercontent.com/thiagocrepaldi/homelab-utility-belt/main/synology/install_letsencrypt_cert_from_pfsense.sh
Resolving raw.githubusercontent.com… 185.199.111.133, 185.199.109.133, 185.199.108.133, …
Connecting to raw.githubusercontent.com|185.199.111.133|:443… connected.
HTTP request sent, awaiting response… 200 OK
Length: 1301 (1.3K) [text/plain]
Saving to: ‘install_letsencrypt_cert_from_pfsense.sh’
0K . 100% 55.5M=0s
2021-09-06 18:04:11 (55.5 MB/s) – ‘install_letsencrypt_cert_from_pfsense.sh’ saved [1301/1301]
–2021-09-06 18:04:11– https://raw.githubusercontent.com/thiagocrepaldi/homelab-utility-belt/main/synology/copy_letsencrypt_cert_from_pfsense.sh
Resolving raw.githubusercontent.com… 185.199.108.133, 185.199.110.133, 185.199.111.133, …
Connecting to raw.githubusercontent.com|185.199.108.133|:443… connected.
HTTP request sent, awaiting response… 200 OK
Length: 1125 (1.1K) [text/plain]
Saving to: ‘copy_letsencrypt_cert_from_pfsense.sh’
0K . 100% 36.0M=0s
2021-09-06 18:04:11 (36.0 MB/s) – ‘copy_letsencrypt_cert_from_pfsense.sh’ saved [1125/1125]
Executing: program /usr/bin/ssh host [host redacted], user [user redacted], command scp -v -f /conf/acme/Synology*
OpenSSH_8.2p1, OpenSSL 1.1.1k 25 Mar 2021
debug1: Authenticator provider $SSH_SK_PROVIDER did not resolve; disabling
debug1: Connecting to [host redacted] [IP redacted] port [port redacted].
debug1: Connection established.
debug1: identity file /root/.ssh/id_rsa type -1
debug1: identity file /root/.ssh/id_rsa-cert type -1
debug1: identity file /root/.ssh/id_dsa type -1
debug1: identity file /root/.ssh/id_dsa-cert type -1
debug1: identity file /root/.ssh/id_ecdsa type -1
debug1: identity file /root/.ssh/id_ecdsa-cert type -1
debug1: identity file /root/.ssh/id_ecdsa_sk type -1
debug1: identity file /root/.ssh/id_ecdsa_sk-cert type -1
debug1: identity file /root/.ssh/id_ed25519 type -1
debug1: identity file /root/.ssh/id_ed25519-cert type -1
debug1: identity file /root/.ssh/id_ed25519_sk type -1
debug1: identity file /root/.ssh/id_ed25519_sk-cert type -1
debug1: identity file /root/.ssh/id_xmss type -1
debug1: identity file /root/.ssh/id_xmss-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.2
debug1: Remote protocol version 2.0, remote software version OpenSSH_7.9
debug1: match: OpenSSH_7.9 pat OpenSSH* compat 0x04000000
debug1: Authenticating to [host redacted]:[port redacted] as ‘[user redacted]’
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: curve25519-sha256@libssh.org
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: [key redacted]
debug1: read_passphrase: can’t open /dev/tty: No such device or address
Host key verification failed.
Replacing certificates from /usr/syno/etc/certificate/smbftpd/ftpd
Replacing /usr/syno/etc/certificate/smbftpd/ftpd/cert.pem with /volume1/LetsEncrypt/Synology.all.pem
cp: cannot stat ‘/volume1/LetsEncrypt/Synology.all.pem’: No such file or directory
Replacing /usr/syno/etc/certificate/smbftpd/ftpd/privkey.pem with /volume1/LetsEncrypt/Synology.all.pem
cp: cannot stat ‘/volume1/LetsEncrypt/Synology.all.pem’: No such file or directory
Replacing /usr/syno/etc/certificate/smbftpd/ftpd/fullchain.pem with /volume1/LetsEncrypt/Synology.all.pem
cp: cannot stat ‘/volume1/LetsEncrypt/Synology.all.pem’: No such file or directory
Replacing certificates from /usr/syno/etc/certificate/system/default
Replacing /usr/syno/etc/certificate/system/default/cert.pem with /volume1/LetsEncrypt/Synology.all.pem
cp: cannot stat ‘/volume1/LetsEncrypt/Synology.all.pem’: No such file or directory
Replacing /usr/syno/etc/certificate/system/default/privkey.pem with /volume1/LetsEncrypt/Synology.all.pem
cp: cannot stat ‘/volume1/LetsEncrypt/Synology.all.pem’: No such file or directory
Replacing /usr/syno/etc/certificate/system/default/fullchain.pem with /volume1/LetsEncrypt/Synology.all.pem
cp: cannot stat ‘/volume1/LetsEncrypt/Synology.all.pem’: No such file or directory
Replacing certificates from /usr/syno/etc/certificate/_archive/M0zsHo
Replacing /usr/syno/etc/certificate/_archive/M0zsHo/cert.pem with /volume1/LetsEncrypt/Synology.all.pem
cp: cannot stat ‘/volume1/LetsEncrypt/Synology.all.pem’: No such file or directory
Replacing /usr/syno/etc/certificate/_archive/M0zsHo/privkey.pem with /volume1/LetsEncrypt/Synology.all.pem
cp: cannot stat ‘/volume1/LetsEncrypt/Synology.all.pem’: No such file or directory
Replacing /usr/syno/etc/certificate/_archive/M0zsHo/fullchain.pem with /volume1/LetsEncrypt/Synology.all.pem
cp: cannot stat ‘/volume1/LetsEncrypt/Synology.all.pem’: No such file or directory
install_letsencrypt_cert_from_pfsense.sh: line 33: synoservice: command not found
install_letsencrypt_cert_from_pfsense.sh: line 34: synoservice: command not found
install_letsencrypt_cert_from_pfsense.sh: line 35: synoservice: command not found
Hi Eric, PFSENSE_USER refers to a user (other than admin) created by you on your pfSense user management page so that you can ssh into your pfSense. PFSENSE_HOSTNAME is the URL of your pfSense.
The goal of this post is to copy (using SSH) Let’sEncrypt certificates issued by pfSense into Synology and then install them
Hi Andy, It seems you are using DSM 7, in which synoservice is no longer available. I just fixed the homelab-utility-bel script to handle both DSM 6 and 7. Try again and let me know how it goes.
Hi Anders, you just need to edit the script to copy the new certificate over your specific services
Happy New Year Thiago!
Havent had time to fix my issue but the missing step was how to fix the ssh key for the Synology root. Keys were fixed using other admin accounts but as you know it isnt possible to ssh into the Synology anymore, thus the root ~/.ssh folder was empty. I simply just copied the generated ssh files into root and now it works. As you describe the task schedule within DSM runs through root. It is of course and obvious reason but since im a noob and as nothing was mentioned in you description i coulnt make it work until now. Thanks anyway for all your efforts in this matter! 🙂
Hi Thiago,
Thanks for that. I went to have another go at this and see that LetsEncrypt SSL certificates are currently not working (using the pfSense method) due to the change in intermediary? Are you having this issue also?
Thanks
Andy
Hi Andy, I can renew all my certificates using DNS method. Which domain validation method are you using? LetsEncrypt will deprecate a bunch of certificates issued by TLS-ALPN-01 in two days. Maybe that is what is hitting you.
If that is your case, try manually renovating your certificates and try again.
Thanks Thiago, I thought it was related to this, but must have jumped the gun (the certificates are now working and I didnt change anything). While I have you – Im trying to figure out how I apply the ssh keys I generated to root on Synology. What am I missing here please? I can apply them to other admin accounts I have created but root says ‘no’ due to a public key mismatch (I havent loaded a public key for root so not sure what I may have done wrong).
What is your DSM version? Since DSM 6.0, ssh access to root user was disabled. You can always create another user and add them to the /etc/sudoers file to grant root access to the minimal amount of stuff you need.
Thanks Thiago,
I’m running DSM 7 and am finding it’s a bit unstable at the moment (loses connection regularly while in the DSM UI). I tried following the Synology instructions to get to root but sudo doesn’t seem to be available to my admin account. Not sure if it’s because the Synology instructions are wrong/out of date or something else.
Will keep playing around and may try a reinstall as a last resort.
Ao you need is to add a file at /etc/sudoers.d (e.g /etc/sudoers.d/shutdown) with the user/permission/command you need. Something like “user_name ALL=(ALL) NOPASSWD: /sbin/poweroff, /sbin/reboot, /sbin/shutdown”