Synology Lets Encrypt

Synology DSM 7 with Lets Encrypt and DNS Challenge

BrianSnelgrove - August 15, 2021
Posted Under: Administration
This post outlines the steps I needed to get Let's Encrypt to work on a Synology device that has been upgraded to DSM 7 and is not accessible from the public internet.

 

Unless otherwise noted, all directions are for Debian based systems. Most steps will work for other distributions but some commands may need modifications.

Synology Fan (but not fan boy).

I have been a fan of Synology Network Attached Storage (NAS) devices for several years. I personally have one, I have installed one at a family members house, and deployed two of them for backup solutions in an enterprise environment. They have all proven to be reliable and very stable. For personal use they can be a bit expensive but in the enterprise environment they are down right cheap compared to the alternatives.

I have three complaints about the Synology devices: Surveillance Station  licenses are kinda expensive (but worth it for the features), the DSM 7 upgrade does not support DS Cloud (Android app I was using to back up my phone), and I hate the certificate errors you get when you access the DSM web interface. Unfortunately there is not much I can do about the first complaint. The second complaint was easily resolved with the use of either DS File or Synology Photos. The third complaint can also be addressed in multiple ways, that is why we are here right now!

SSL Certificates?

Secure Socket Layer (SSL) Certificates are what your browser uses to contact a website securely to protect usernames, passwords, credit cards, data, etc. There is a “self signed” certificate installed on the Synology devices by default. They DO provide security but your web browser complains about them and you have to click various buttons/links to continue to the website. Ask nearly any enterprise administrator about this annoyance and they will be used to self signed SSL certificates – they are all over the place in administrative tools. However for an end user it does not inspire confidence when they have to click through error messages to access a system that has important and potentially sensitive data on it. 

There IS a built in way to get a valid SSL certificate on a Synology device but it has one MAJOR drawback: your Synology device has to be accessible on ports 80 and 443 to the public internet OR you have to use the Synology DDNS service. For some users that may not be a big deal but I don’t imagine the majority of users will want their Synology device accessible to the public internet or have to use a strange URL (DeviceName.synology.me for example) to access their data. In my case ports 80 and 443 are blocked by my home Internet Service Provider so the first option is not available to me and I don’t like the second idea.

The solution I went with? Lets Encrypt will provide free SSL certificates and acmesh (https://github.com/acmesh-official/acme.sh) has provided a script that can be used without port 80 and 443 being open to the public internet. 

There has to be a catch.

Well, there kinda is. You will need a domain with a registrar that provides an Application Programming Interface (API) to update some information. There are LOTS of choices available but the process provided by acemsh supports: Cloudflare, DNSPod.cn, CloudXNS.com, GoDaddy.com, and several others. I personally use GoDaddy and already have a post (https://www.dr-b.io/post/DDNS-Using-GoDaddy) that involves the GoDaddy API. The other providers should work fine and most of this post should work with the others but I have only tested with GoDaddy. YMMV.

Where to start?

There are guides all over the internet (https://www.driscocity.com/synology-dsm-6-2-lets-encrypt-dns-challenge-route53/ and https://lippertmarkus.com/2020/03/14/synology-le-dns-auto-renew/ for example) that explain most of what I am about to go over but in my case it took a bit more work than they outline. While they are certainly worth a read I will try to bring attention to the steps I had to modify to get this working on my Synology DSM 7 system.

First, make sure you have a domain name registered with your registrar of choice (GoDaddy in my case) and get the API key and API secret that will be needed. For GoDaddy you can log into https://developer.godaddy.com and generate new API keys for this project. Make sure you create a production key and copy the secret before you close the window, you will not be able to retrieve the secret once you close the window. Once you have that you are ready to start!

Create a user in Synology DSM.

Log into your Synology device, click Control Panel, click User & Group, and click Create. I used certadmin as the username and give the user a good description. Make sure the user is a member of the administrators group (this is required for SSH access that we will be using in a moment) and the http group (this is required for the process to authenticate to DSM in the SSH session). The certadmin user only needs Read/Write access to the homes folder and you can deny access to all applications. NOTE: some other guides do not specify adding the user to the administrators and http groups, this is required! Once the user has been created go back to the Control Panel home and click Terminal & SNMP. Check Enable SSH service and click apply.

Now for the fun stuff!

You probably came here to figure out how to do something not read my ramblings, well here you go! Use a SSH client (https://www.putty.org is a good option for Windows but Linux users have a ssh client by default). If you are using putty enter the IP address or host name of your Synology device, make sure SSH is checked, and click open. You will be prompted with a security alert, it is OK to click Yes. You will then be prompted for the username (certadmin in my case). If you are using a Mac or Linux computer open a terminal window and use the built in SSH client by entering:

ssh certadmin@YOURHOSTorIPADDRESS

After continuing past the security warning you will be prompted for the password. Enter the password you created for the Synology user above (you may not see any input as you type) and press enter to log into the Synology device. Don't let a SSH session scare you; the command line is your friend!

The next few commands (copy/paste them one at a time if you want) will download the script, extract the zip file, move the files to a different folder, give the new user ownership of the files, and put you in the correct directory. Each of these commands should be on a single line. Most of these commands are borrowed from https://www.driscocity.com/synology-dsm-6-2-lets-encrypt-dns-challenge-route53/.

wget -O /tmp/acme.sh.zip https://github.com/acmesh-official/acme.sh/archive/master.zip

sudo 7z x -o/usr/local/share /tmp/acme.sh.zip

sudo mv /usr/local/share/acme.sh-master/ /usr/local/share/acme.sh

sudo chown -R certadmin /usr/local/share/acme.sh/

cd /usr/local/share/acme.sh

Now that we have the necessary files we will need to create a few variables for the script to work. Be sure to replace the following with your information!

export GD_Key="YOUR GODADDY KEY"
export GD_Secret="YOUR GODADDY SECRET"
export SYNO_Username="certadmin"
export SYNO_Password="YOUR CERTADMIN PASSWORD"
export SYNO_Certificate="Let's Encrypt"
export SYNO_Create=1

If you are not using GoDaddy as your domain registrar you can visit https://github.com/acmesh-official/acme.sh/wiki/dnsapi for the export commands needed for other registrars.

Use the following command to get the first certificate. Be sure to update your domain name!

./acme.sh --server letsencrypt --issue -d "*.YOURDOMAIN.NAME" --dns dns_gd --home $PWD

Other guides don’t include the --server argument that specifies letsencrypt. If you are using a different registrar you will need to reference the github page above to determine what to use for the --dns argument.

It will take about 1 minute for the process to complete. Don't worry, there is text on the screen that lets you know what is happening. This process just created and downloaded the certificate to your Synology device, it didn’t tell the Synology to start using it. That is done with this command:

./acme.sh -d "*.YOURDOMAIN.NAME" --deploy --deploy-hook synology_dsm --home $PWD

You should see some text indicating the script was able to log into your Synology device, getting the certificates, applying the certificates, and restarting the web server. If you log into your Synology device using https now you should see a valid certificate! Some guides indicate that you will have to go to the Control Panel, Security, Certificate to see the new certificate and apply it, in my case it was applied automagically. 

Now that you have a valid and working SSL certificate make sure your browsers use it! Log into the Synology device and go into the Control Panel and Login Portal. Check Automatically redirect HTTP connections to HTTPS for DSM desktop and click Save. Once you are sure things are working the way you want go back to the Control Panel and Terminal & SNMP to disable SSH access. Remember, disabling unneeded services is good security protocol!

Now what?

Well, you have the certificate installed and working but if you check the certificate you will see it is only valid for 90 days. It is easy enough to automatically renew the certificate by logging into the Synology going to the Control Panel and Task Scheduler. Click Create and select Scheduled Task and User-defined Script. Give the task a descriptive name and make sure certadmin is the selected user. Schedule the task to occur every day and enter the user-defined script in the Task Settings tab. In my case I used the following.

/usr/local/share/acme.sh/acme.sh --renew -d "*.YOURDOMAIN.NAME" --home /usr/local/share/acme.sh --server letsencrypt

There you have it!

Just a few relatively easy steps and you have a working valid SSL certificate on your Synology that will automagically renew itself before it expires. Now, get onto your next project!


Discussion - all postings are moderated

Daemonia - January 15, 2024
Thanks a lot for this ! Following the instructions, I was getting the following message : Enter OTP code for user 'certadmin': I managed to resolve by using : export SYNO_Device_ID=SynologyName

Brian - December 13, 2023
Jeff, using Ansible for this project is a creative solution! I am far from an Ansible expert but I do use it to manage around 40 Linux based digital signage systems and manage backups of 200+ Cisco switches. You mentioned Synology using a stripped down Linux version, that is one of the reasons I have been a bit hesitant to dive in too far. The Synology systems I have access to have production data on them and I can't afford to kill them!

Jeff Urlwin - December 12, 2023
Thank you for this. This was a great help. Because I'm sadistic, I also created an ansible script. Had to run it on 2 synology devices, thought I was helping myself be consistent :) Turns out, some extra pain due to running it on two devices, assuming "certadmin" has different passwords for each and having separate OTP settings for each as well... fun exercise, but unless I was running a fleet of them, I wouldn't do this again this way ... that plus Synology has a stripped down linux and didn't have things i thought i'd need... For the record, I don't think the OTP information is clear on the acme.sh site. Setup OTP on the web GUI. Then run the "deploy" portion of the script and it will prompt you for the OTP code generate the Device ID it needs and saves it. That's not as hard as it feels from the limited docs - and makes the ansible script harder as you have to prompt for the TOTP code...

Brian - December 9, 2023
Peter, I have seen a few other people have issues with IDN. Does your domain name have any non-ASCII characters in it? It looks like letsencrypt and acme both support IDNs but I don't have one to test with. If you do find a resolution post back here and I will update the article!

peter - December 9, 2023
Hi I am trying to do following steps but for command ./acme.sh --server letsencrypt --issue -d "*.mydomain.eu" --dns dns_wedos --home $PWD I've got the error: It seems that *.mydomain.eu is an IDN( Internationalized Domain Names), please install 'idn' command first. It was mentioned below, but I do not have idea how can I fixed. Any ideas?

Brian - June 13, 2023
Greg, that is entirely possible. I have not dug through the acme.sh script to see if/how it escapes special characters in passwords. I am glad you got the password issue figured out and it is working for you!

Greg P - June 13, 2023
There's definitely something weird with the acme.sh script and syno passwords that have special chars. I had a password that contained both ampersands and question marks, and while I was able to log into DSM, the acme.sh script kept failing and my account was getting protected which caused the deploy line to fail. Once I changed the password to remove these special chars everything worked fine. Maybe some bad escaping going on between the export line and the acme.sh script.

Brian - March 6, 2023
Hi Dee, I'm glad you found it useful! I know Let's Encrypt supports wildcards but I have never messed with them. Since the certs are free I haven't needed to use a wildcard to secure multiple virtual hosts on the same server. Unless there is a reason for I wildcard I would probably go with a single name based cert.

Dee Mehta - March 6, 2023
Hey Brian, Great write up! it helped a lot when I got my new NAS and wanted to put it behind a reverse proxy but still be able to get my certs. I have an issue with the renewal/task schedular script failing to work, looking through logs, it seems that there is an error after the certificate is renewed and it tries to apply it: /usr/local/share/acme.sh/acme.sh: eval: line 2401: unexpected EOF while looking for matching `'' /usr/local/share/acme.sh/acme.sh: eval: line 2402: syntax error: unexpected end of file [Mon Mar 6 10:50:29 GMT 2023] Deploy error. If I redo the whole process with non wildcard certificates, there's no issues. Have you experienced this? Thanks in advance

Brian - February 27, 2023
Mario, unfortunately I don't know any other solutions or how to install the requested module. If you do happen to find a solution, please feel free to post back here and I will update the article.

Mario - February 26, 2023
Thanks for the speedy reply Brian. Unfortunately pennycode translation does not modify my domain name at all ? But I tried it anyway, and I still get the same error. Would you happen to know how to carry out the request in the error message, and install the 'idn' command?. I have found lots of information on idn, but nothing on how to deal with it. Thanks for your help. Mario.

Brian - February 26, 2023
Hi Mario, it looks like this is an acme issue. IDNs contain non ASCII characters and causes problems with the let's encrypt process. Try changing the URL in the cert request command to punycode and see if it helps: https://www.punycoder.com/ Unfortunately, this is the only suggestion I can make since I don't own or have easy access to an IDN domain.

Mario - February 25, 2023
Hi, Thanks for the great work .... However, I seem to have struck a problem. When I run the command to download my first certificate, I get the following message ... [Sun Feb 26 11:42:14 AEDT 2023] It seems that “*.xxxxxx.com” is an IDN( Internationalized Domain Names), please install 'idn' command first. I am connecting via ssh from my Mac. I have done a lot of searching, but can not find any info on how to install the 'idn' command. Would you be able to assist with this? Thank.

Dominik - January 8, 2023
Thank you so much. the only thing is that the -- home was different for me: /var/services/homes/MY_USER/.acme.sh/

Brian - January 3, 2023
@justin - glad you found this useful!

Mr. JustinTime - January 3, 2023
Thank you Brian, this is the way I always wanted to automate the Synology SSL certificate. Nice job!

Fernando Pires - December 19, 2022
Não funcionou com o freedns, nem no-ip, falha minha em algum codigo possivelmente.

Brian - November 2, 2022
Thank you Raven! I think that command would only be needed if you want LE send you an email if your certificate has not been renewed before it is set to expire. While I did not run that command on my Synology device it does come in handy if there are issues renewing. I have a couple of production servers at work that have problems running the cron job and the emails remind me to renew the certificates before they expire.

raven - November 1, 2022
./acme.sh --register-account -m letsencrypt@forestraven.net --home $PWD This is missing before aquiring the certificate. Great guide, tough.

snairolf - August 1, 2022
There is now also a SYNO_DID that can be used for 2FA (https://lippertmarkus.com/2020/03/14/synology-le-dns-auto-renew/)

J. B. - July 22, 2022
@ashkii7: When you configured your 2FA, you were normally scanning a QR code for initialisation of your code generator. In that dialog on your Synology, there is a link called "Can't scan it?". When you click on that link, you can see the "Secret key" in plain text. You must use this key for the SYNO_TOTP_SECRET so acme.sh can generate the correct key. Be aware, when resetting the key you must also initialize your generator with the same key.

Brian - June 11, 2022
Steven, I believe a home directory for the certadmin user will be necessary. There are a few hidden files/folders in my /var/services/homes/certadmin folder; one of them is folder names ".acme.sh" and appears to be related to the acme cert renewal process.

Steven Petrillo - June 10, 2022
Does the certadmin account need to have a home directory in order for this to work? When I login to the certadmin account via SSH its telling me: Could not chdir to home directory /var/services/homes/certadmin: No such file or directory

Brian - April 30, 2022
Hi Binh, Lets Encrypt can be used to provide SSL certificates for multiple host names and domains on a single web server using virtual hosts. I believe Synology uses nginx for its web server and I know nginx supports multiple virtual hosts but I don't know how much customization Synology has done to their nginx instance or how you would set up the different virtual hosts. Unfortunately, this is a bit beyond the scope of this guide (and my knowledge of the Synology nginx implementation).

Binh Nguyen - April 29, 2022
thnks for the tutor sir. Will i do the same for other domain ?

Brian - April 23, 2022
Andre, I am glad you found the article helpful! When the renew command runs it should replace the existing certificate and you do not need to import it again. The --deploy-hook argument *should* take care of importing the certificate and restarting the web server. I personally have not seen the interrupted message but Lets Encrypt provides certificates that are valid for 90 days and, unless you force renewal, will provide a new certificate about 28 days before your current certificate expires. I would let the system run for about 2.5 months and see if you have the new certificate. If not, it may be time for some additional troubleshooting.

Andre - April 23, 2022
Thanks Brian for this great article. I have two questions regarding the certificate renewal via task. Everything else works great: Do I have to import the renewed certificate again? Currently I have only the renew command in my scheduled task on my synology. But this does not replace the current certificate right? Also my task ends with status „interrupted“, I guess because the renewal is only possible after some weeks. How did you solve that? Thanks again, I appreciate your help!

ashkii7 - February 25, 2022
Hi, Brian, Many thanks for your reply Cordially

Brian - February 24, 2022
ashkii7. it looks like the OATHTool is a command line process to generate a time based one time password. More information about the tool is available here: https://www.nongnu.org/oath-toolkit/oathtool.1.html There is a link to download it for various Linux distros and you could probably get it running on your Synology device but I would be very careful!

ashkii7 - February 23, 2022
Hi, Brian, In fact the problem is no longer the secret key, I found how to find it, now the problem is that the certificate deployment script on the NAS uses the "OATTool" tool to generate the OTP code to validate the connection of the account. This tool "OATTool" does not exist on the NAS Synology DSM system. At best it exists in the Docker image but all NAS Synology do not support docker. This tool is not found, either in the basic package of Acme.sh script. So how do it? Can this OATTool tool on the NAS can be installed? It's possible ? Cordially

Brian - February 22, 2022
Hi ashkii7. I have not deployed 2FA on my synology since it is only available on my local network and I am not overly concerned with anyone trying to get into it. You might try disabling 2FA on the account you created for the SSL process and see if that will help. Chris B was having the same issue, maybe he will chime in if/when he finds a solution or workaround.

ashkii7 - February 22, 2022
Hi, When deploying my certificate I have the following error message: "If two-factor authentication is enabled for the user, set SYNO_TOTP_SECRET." With what value do I inform this variable SYNO_TOTP_SECRET? And especially where can I find this value? As the deployment operation is automatic I can not enter the OTP code that Google Authenticator gives me. Thank you for your reply. Best Regards

Brian - February 16, 2022
Chris, it would appear that SYNO_TOTP_SECRET is a reference to a Time based One Time Password. While I don't have any experience with this configuration it looks like there is some information on the acme github page that might get you pointed in the right direction. Look at #20 and see if that helps. https://github.com/acmesh-official/acme.sh/wiki/deployhooks#20-deploy-the-cert-into-synology-dsm

Chris B - February 15, 2022
Has anyone been able to get this working with 2FA enabled on the account? I get "If two-factor authentication is enabled for the user, set SYNO_TOTP_SECRET." but I'm not sure what to do from here? Disabling 2FA works, but as I am setting this up as a scheduled task, I'd prefer to have 2FA enabled Thanks

Brian - January 18, 2022
Good to hear Eric! I am glad you got it going and glad this guide helped!

Eric P - January 17, 2022
Thanks Brian! It's probably the password. My autogenerated password has an apostrophe embedded on it. I removed the apostrophe and replaced it with a random character then run through everything again and it worked. Thanks much for writing this guide!

Brian - January 16, 2022
Eric, I have two thoughts. 1: Are you sure you entered the certadmin password correctly when you typed in the export statements? Can you try logging into your synology device with the certadmin account to make sure it is able to log in without any issues? 2: Have you change the default ports on your synology device? By default it uses port 5000 for http and port 5001 for https communications. Unfortunately I am not able to replicate this issue so it is hard to provide more than a couple of guesses...

Eric P - January 15, 2022
Thanks for this guide. I am having problem running the line "./acme.sh -d "*.YOURDOMAIN.NAME" --deploy --deploy-hook synology_dsm --home $PWD". I am getting an error that says "Unable to authenticate to localhost:5000 using http". I did some googling and someone suggested that the acme.sh seems to be not of the latest version. So, I tried running again the first 5 lines but still got the same error. Would you know what could be causing the issue? Sorry, I am very new to this and not familiar with Linux commands. Thanks!

Brian - November 15, 2021
Good to hear Jack!

Jack P - November 15, 2021
Thank you very much! This worked for me.