Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
CLI script to programmatically replace SSL certs on Synology NAS
#!/bin/sh
#
# *** For DSM v6.x ***
#
# How to use this script:
# 1. Get your 3 PEM files ready to copy over from your local machine/update server (privkey.pem, fullchain.pem, cert.pem)
# and put into a directory (this will be $CERT_DIRECTORY).
# 2. Ensure you have a user setup on synology that has ssh access (and ssh access is setup).
# This user will need to be able to sudo as root (i.e. add this line to sudoers, <USER> is the user you create):
# <USER> ALL=(ALL) NOPASSWD: /var/services/homes/<USER>/replace_certs.sh
# 3. Call this script as follows:
# sudo scp ${CERT_DIRECTORY}/{privkey,fullchain,cert}.pem $USER@$SYNOLOGY_SERVER:/tmp/ \
# && sudo scp replace_synology_ssl_certs.sh $USER@$SYNOLOGY_SERVER:~/ \
# && ssh $USER@$SYNOLOGY_SERVER 'sudo ./replace_synology_ssl_certs.sh'
# Script start.
REVERSE_PROXY=/usr/syno/etc/certificate/ReverseProxy
FQDN_DIR=/usr/syno/etc/certificate/system/FQDN
DEFAULT_DIR=
DEFAULT_DIR_NAME=$(cat /usr/syno/etc/certificate/_archive/DEFAULT)
if [ "DEFAULT_DIR_NAME" != "" ]; then
DEFAULT_DIR="/usr/syno/etc/certificate/_archive/${DEFAULT_DIR_NAME}"
fi
# Move certs from /tmp to install directory
mv /tmp/{privkey,fullchain,cert}.pem /usr/syno/etc/certificate/system/default/
if [ "$?" != 0 ]; then
echo "Halting because of error moving files"
exit 1
fi
# Ensure correct permissions
chown root:root /usr/syno/etc/certificate/system/default/{privkey,fullchain,cert}.pem
if [ "$?" != 0 ]; then
echo "Halting because of error chowning files"
exit 1
fi
echo "Certs moved from /tmp & chowned."
# If you're using a custom domain name, replace the FQDN certs too
if [ -d "${FQDN_DIR}/" ]; then
echo "Found FQDN directory, copying certificates to 'certificate/system/FQDN' as well..."
cp /usr/syno/etc/certificate/system/default/{privkey,fullchain,cert}.pem "${FQDN_DIR}/"
chown root:root "${FQDN_DIR}/"{privkey,fullchain,cert}.pem
fi
# Replace certs for default Application Portal (if found)
if [ -d "$DEFAULT_DIR" ]; then
echo "Found upload dir (used for Application Portal): $DEFAULT_DIR_NAME, copying certs to: $DEFAULT_DIR"
cp /usr/syno/etc/certificate/system/default/{privkey,fullchain,cert}.pem "$DEFAULT_DIR/"
chown root:root "$DEFAULT_DIR/"{privkey,fullchain,cert}.pem
else
echo "Did not find upload dir (Application Portal): $DEFAULT_DIR_NAME"
fi
# Replace certs for all reverse proxy servers (if exists)
if [ -d "$REVERSE_PROXY" ]; then
echo "Found reverse proxy certs, replacing those:"
for proxy in $(ls "$REVERSE_PROXY"); do
echo "Replacing $REVERSE_PROXY/$proxy"
cp /usr/syno/etc/certificate/system/default/{privkey,fullchain,cert}.pem "$REVERSE_PROXY/$proxy"
chown root:root "$REVERSE_PROXY/$proxy/"{privkey,fullchain,cert}.pem
done
else
echo "No reverse proxy directory found"
fi
# Reboot synology services
echo -n "Rebooting all the things..."
/usr/syno/sbin/synoservice --restart nginx
/usr/syno/sbin/synoservice --restart nmbd
/usr/syno/sbin/synoservice --restart avahi
/usr/syno/sbin/synoservice --reload ldap-server
echo " done"
@yauyauwind
Copy link

yauyauwind commented Apr 14, 2021

Hello Catchdave,

Thank you for your script, to let's me know need restart not only nginx
and I make my code to support ReverseProxy and AppPortal

Here is my code "not complete code, just a related RP part"

letpath="/volume1/docker/letencrypt/config/etc/letsencrypt/archive/xxxxx.com"
certname=$(ls -v $letpath/cert*.pem | tail -1)
privname=$(ls -v $letpath/privkey*.pem | tail -1)
fullname=$(ls -v $letpath/fullchain*.pem | tail -1)
chainame=$(ls -v $letpath/chain*.pem | tail -1)
tarpathr="/usr/syno/etc/certificate/ReverseProxy"

cd $tarpathr
lsdirectory=($(ls -d */))
for (( i=0; i<${#lsdirectory[@]}; i++)); do rsync -avh $fullname $tarpathr/${lsdirectory[$i]}/fullchain.pem; chown root:root $tarpathr/${lsdirectory[$i]}/.pem; chmod 400 $tarpathr/${lsdirectory[$i]}/.pem; done

I use array to store the sub-folder which is under the ReverseProxy directory
and use the loop to overwrite each cert

Just for your reference to implement your code, so that can support ReverseProxy and AppProtal

My code is work, but I haven't write the checking statement

Due to I use docker to renew Let's Encrypt Cert. however the updated cert will name to prvikey1,2,3,4,5.pem
I use var to get the latest pem name

Anyway, Just FYI

Thanks~

@cedricmenzi05
Copy link

cedricmenzi05 commented Aug 7, 2021

Hey!

I tried to use this script on my Synology with DSM 7 installed. I copy the files without any problem and set the permission. I then restart the Synology but the certificates don't change....
Is this related to DSM 7 or anything else?
Could you help me please?

Thanks in advance!

@paolopasqua
Copy link

paolopasqua commented Sep 27, 2021

Hey!

I tried to use this script on my Synology with DSM 7 installed. I copy the files without any problem and set the permission. I then restart the Synology but the certificates don't change....
Is this related to DSM 7 or anything else?
Could you help me please?

Thanks in advance!

Hi @cedricmenzi05 I'm doing a similar script to automate the certificate renewal and install it in the Synology. What I've seen (on DSM 7) the original certificates are stored in /usr/syno/etc/certificate/_archive/
Here there's folders containing the certificates and three files:

  • DEFAULT : the hash (folder name) of default certificate to apply.
  • INFO : the list of certificates with description, services list where applied, ...
  • SERVICES : the list of services

I'm quite sure that the other folders in /usr/syno/etc/certificate/ are regenerated every time nginx and other services are restarted.
And again, in DSM 7 changes the restart command: synosystemctl restart xxxx. DSM 7 changes are driving me crazy, I really don't find where to edit the nginx vhost conf :')

@catchdave
Copy link
Author

catchdave commented Sep 29, 2021

I don't have DSM7 installed on my NAS yet, so I can't provide any information as to what needs to happen for DSM7. I have used the above successfully on DSM6 for a while now. So I'd say start with what @paolopasqua said and do some google-research :)

@pronetguru
Copy link

pronetguru commented Oct 9, 2021

Hey!

I tried to use this script on my Synology with DSM 7 installed. I copy the files without any problem and set the permission. I then restart the Synology but the certificates don't change.... Is this related to DSM 7 or anything else? Could you help me please?

Thanks in advance!

Hi @cedricmenzi05,
I was having the same issue after updating to DSM 7 and stumbled upon this thread. @paulopoasqua is absolutely correct in that the certificates are regenerated every time nginx is restarted, which helped me to solve my issue and restore scripted updates of my certificates.

Within the /usr/syno/etc/certificate/_archive/ folder, I also that there were 2 additional folders with 6-character names. You may have more depending on how many different certificates you've installed on your Synology. One of those contains the "default" self-signed certificate, and the other contained the original (old, expired) custom certificate. If you cd to the appropriate folder and cat cert.pem you'll be able to identify the certificate folder you want to update. When you copy over the certificate component files (cert.pem, chain.pem, fullchain.pem, privkey.pem), just drop them into the certificate folder you identified and restart the necessary services. The certificate will re-populate from the .../_archive/XXXXXX/ folder each restart.

Also, as @paolopasqua noted, the command to restart services has changed, so make sure you update that in your script also.

@lawipac
Copy link

lawipac commented Nov 22, 2021

/usr/syno/sbin/synosystemctl restart nginx

For my case, With DSM7, restart Nginx also restart the VM under the VMware manager, Docker, which is quite unexpected. It's kinda a downgrade of the DSM.

/usr/syno/sbin/synosystemctl resload nginx is more appropriate, using reload instead of restart

In addition, I also need to default certificate in 'Control Panel / Security/ Certificate "

@jiquem
Copy link

jiquem commented Feb 2, 2022

I don't get the point : is the script working on DSM7 or not ? If not, is any update planned ?

@catchdave
Copy link
Author

catchdave commented Feb 13, 2022

@jiquem : When I upgrade to DSM7, I will rewrite this script to work on DSM7. The purpose of this script was just for my personal use case--shared in case it helps others.
As of this point in time, I don't have current plans to upgrade my DSM to v7.x--doing so will likely mean I will need to set aside a lot of time to rewrite several things like this, so that's a personal barrier for me :)

@catchdave
Copy link
Author

catchdave commented Feb 13, 2022

Update: Added support for application portal and reverse proxy certs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment