#!/bin/sh | |
# | |
# *** For DSM v7.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. Copy this script to Synology: sudo scp replace_synology_ssl_certs.sh $USER@$SYNOLOGY_SERVER:~/ | |
# 4. Call this script as follows: | |
# sudo bash -c scp ${CERT_DIRECTORY}/{privkey,fullchain,cert}.pem $USER@$SYNOLOGY_SERVER:/tmp/ \ | |
# && ssh $USER@$SYNOLOGY_SERVER 'sudo ./replace_synology_ssl_certs.sh' | |
# Script start. | |
#!/bin/bash | |
DEBUG= # Set to any non-empty value to turn on debug mode | |
error_exit() { echo "[ERROR] $1"; exit 1; } | |
warn() { echo "[WARN ] $1"; } | |
info() { echo "[INFO ] $1"; } | |
debug() { [[ "${DEBUG}" ]] && echo "[DEBUG ] $1"; } | |
# 1. Initialization | |
# ================= | |
[[ "$EUID" -ne 0 ]] && error_exit "Please run as root" # Script only works as root | |
certs_src_dir="/usr/syno/etc/certificate/system/default" | |
services_to_restart=("nmbd" "avahi" "ldap-server") | |
packages_to_restart=("ScsiTarget" "SynologyDrive" "WebDAVServer" "ActiveBackup") | |
target_cert_dirs=( | |
"/usr/syno/etc/certificate/system/FQDN" | |
"/usr/local/etc/certificate/ScsiTarget/pkg-scsi-plugin-server/" | |
"/usr/local/etc/certificate/SynologyDrive/SynologyDrive/" | |
"/usr/local/etc/certificate/WebDAVServer/webdav/" | |
"/usr/local/etc/certificate/ActiveBackup/ActiveBackup/" | |
"/usr/syno/etc/certificate/smbftpd/ftpd/") | |
# Add the default directory | |
default_dir_name=$(</usr/syno/etc/certificate/_archive/DEFAULT) | |
if [[ -n "$default_dir_name" ]]; then | |
target_cert_dirs+=("/usr/syno/etc/certificate/_archive/${default_dir_name}") | |
debug "Default cert directory found: '/usr/syno/etc/certificate/_archive/${default_dir_name}'" | |
else | |
warn "No default directory found. Probably unusual? Check: 'cat /usr/syno/etc/certificate/_archive/DEFAULT'" | |
fi | |
# Add reverse proxy app directories | |
for proxy in /usr/syno/etc/certificate/ReverseProxy/*/; do | |
debug "Found proxy dir: ${proxy}" | |
target_cert_dirs+=("${proxy}") | |
done | |
[[ "${DEBUG}" ]] && set -x | |
# 2. Move and chown certificates from /tmp to default directory | |
# ============================================================= | |
mv /tmp/{privkey,fullchain,cert}.pem "${certs_src_dir}/" || error_exit "Halting because of error moving files" | |
chown root:root "${certs_src_dir}/"{privkey,fullchain,cert}.pem || error_exit "Halting because of error chowning files" | |
info "Certs moved from /tmp & chowned." | |
# 3. Copy certificates to target directories if they exist | |
# ======================================================== | |
for target_dir in "${target_cert_dirs[@]}"; do | |
if [[ ! -d "$target_dir" ]]; then | |
debug "Target cert directory '$target_dir' not found, skipping..." | |
continue | |
fi | |
info "Copying certificates to '$target_dir'" | |
if ! cp "${certs_src_dir}/"{privkey,fullchain,cert}.pem "$target_dir/" && \ | |
chown root:root "$target_dir/"{privkey,fullchain,cert}.pem; then | |
warn "Error copying or chowning certs to ${target_dir}" | |
fi | |
done | |
# 4. Restart services & packages | |
# ============================== | |
info "Rebooting all the things..." | |
for service in "${services_to_restart[@]}"; do | |
/usr/syno/bin/synosystemctl restart "$service" | |
done | |
for package in "${packages_to_restart[@]}"; do # Restart packages that are installed & turned on | |
/usr/syno/bin/synopkg is_onoff "$package" 1>/dev/null && /usr/syno/bin/synopkg restart "$package" | |
done | |
# Faster ngnix restart (if certs don't appear to be refreshing, change to synosystemctl | |
if ! /usr/syno/bin/synow3tool --gen-all && sudo systemctl reload nginx; then | |
warn "nginx failed to restart" | |
fi | |
info "Completed" |
/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 "
I don't get the point : is the script working on DSM7 or not ? If not, is any update planned ?
@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 :)
Update: Added support for application portal and reverse proxy certs
Hello, I made a script to automate pushing SSL certificates and setting-up htaccess that works on DSM7
https://github.com/looran/synoadm
enjoy
DSM7 only need replace /usr/syno/sbin/synoservice --restart
to systemctl restart
In DSM7 to avoid docker and VMM to restart when restarting nginx use:
synow3tool --gen-all && systemctl reload nginx
source:
https://www.reddit.com/r/synology/comments/olve56/comment/h5hsogq/
Updated to work with DSM7
@carmatana thank you.
it works like a charm. With the following prompt.
root@acmedns:~# ssh root@nas2022 "/usr/syno/bin/synow3tool --gen-all && systemctl reload nginx "
Sync W3 certificate info successfully
Generate nginx tmp config successfully
I purposely switched to an old cert and switch it back. works as expected.
@catchdave, I've uploaded an improved version:
- instructions revised so this can work beyond a DSM update (which removes user edits to sudoers and more :( )
- includes alt port switches, all four *.pem files (original was missing chain.pem), copy rather than move to make setup diagnosis easier, and support for a number of popular Synology packages that make use of SSL certs
THANK YOU for doing this! A huge help.
Hello, I made a script to automate pushing SSL certificates and setting-up htaccess that works on DSM7 https://github.com/looran/synoadm enjoy
@looran that script is missing quite a bit on the SSL side. Among other things, synology services use more than just fullchain.pem and privkey.pem ;)
Right, I added mention that it has only been tested with the main web interface handled by nginx, since it's the only thing I tested.
Ran into some trouble today with /usr/syno/bin/synosystemctl
having seemingly vanished?
I eventually found a workaround in replacing
/usr/syno/bin/synosystemctl restart nginx
with
/usr/syno/sbin/synoservicectl --restart nginx
and likewise for the others. I don't really know what I'm doing though but it seems happy again?
@ekchew : synosystemctl
is for DSM7.x. I think /usr/syno/sbin/synoservicectl
is for DSM 6.x IIRC.
What version of Synology OS are you running?
I think there is a bug where line 22 always returns true. Should the line be if [ "$DEFAULT_DIR_NAME" != "" ]; then
instead?
Yes, synosystemctl is DMS7. Here's a link to my DSM7 version. NOTE that some packages do not use either synoservicectl OR synosystemctl... but synopkg instead! https://gist.github.com/MrPeteH/80b487a2f400e5c0d538b18ae2f5dd76
Refactored script to be cleaner and added some packages to restart as per @MrPeteH.
Refactored script to be cleaner and added some packages to restart as per @MrPeteH.*
WONDERFUL refactor job!
Unfortunately, I found some challenges...
First, what appears to be a bug:
- While it DOES work to copy the three files to the system/default and system/FQDN folders (privkey,fullchain,cert}.pem
- DSM does some work in those two folders automagically, to create/update four additional files: chain.pem, info (no extn), root.pem, and short-chain.pem
- But DSM doesn't do that in any of the other folders.
- SO, this script needs to copy all seven files from the source folder, not just three! (I do not know what process causes the extra updates, nor how quickly. seems very fast...)
- (Just do
find / -name cert.pem
to discover all of yours... )
Next, suggestions that relate to the up-front instructions:
- Many like to configure an alt ssh port. To specify the port in scp, use
-P nnnn
, in ssh-p nnnn
- DSM wipes out all customizations to
sudoers
on update. So it's better to recommend adding a line tosudoers.d/sudo-USER
- Sadly, brace expansion doesn't work in /bin/sh which can easily be the default shell for embedded scripts (like in ACME actions!) -- best workaround is either spell it all out, or embed the script in a script file with #!/bin/csh or whatever... (I just now discovered this was killing some of my automation :( )
@MrPeteH : Thanks!
- Regarding the other files beyond the 3 certs not being copied - have you noticed any issues with them not moving? As I use this script every 90 days (via letsencrypt), I have no problems in SSL certs working in all applications that use SSL certs on my Nas. Perhaps these files don't matter? On my NAS, I have not noticed any issues.
- Sudo and ports. Yes true to both - I have only noticed a wipe on a major upgrade (from 6.x to 7.x), minor updates are fine. I can look into testing what works. FWIW, my main focus on this gist on moving certs, I have so far intentionally been vague about managing SSH access (I figure anyone doing this stuff has ssh/sudo figured out already)
- Brace expansion. I understand /bin/sh doesn't support it. However, this script is explicit about using bash and is designed to run on synology (which has bash) via a direct ssh call. If you're using parts of this script in somewhere else - that's fine, but not it's not my intention to support uses outside of being executed directly (which will always use
/bin/bash
). How are you calling this script?
- Brace expansion. I understand /bin/sh doesn't support it. However, this script is explicit about using bash and is designed to run on synology (which has bash) via a direct ssh call. If you're using parts of this script in somewhere else - that's fine, but not it's not my intention to support uses outside of being executed directly (which will always use
/bin/bash
). How are you calling this script?
I'm talking about the recommended calling usage in the comments at the top... which of course is assumed to be in some OTHER machine, using scp and ssh to get the data to the Synology NAS. :)
The other files: I did see an issue once, but not since. All I know is, DSM creates those other files, and copies them all when installing a package. No idea why they don't get updated when the main system certs update. Perhaps we could call that a DSM bug LOL
I'm talking about the recommended calling usage in the comments at the top... which of course is assumed to be in some OTHER machine, using scp and ssh to get the data to the Synology NAS. :)
Makes sense! Appreciate the explanation :) @MrPeteH
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 youcd
to the appropriate folder andcat 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.