-
-
Save catchdave/69854624a21ac75194706ec20ca61327 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# | |
# *** 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). | |
# Personally, I use this script (https://gist.github.com/catchdave/3f6f412bbf0f0cec32469fb0c9747295) to automate steps 1 & 4. | |
# 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. | |
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" |
@Daermegil RSA is fine; that's what I'm using too... I did see in my notes that I needed to manually import the LE certificates into DSM before the automation worked reliably.
When you're prompted for Private Key that's the privkey.pem
file. When you're prompted for the Certificate that's cert.pem
. When prompted for the Intermediate Certificate that's fullchain.pem
.
DSM does accept certs without adding the intermediate cert, but it causes some things to fail.
Try manually adding those and see if that works for you. Once the manual add works, the automation should also work.
I think from my memory, if you upload the wrong files (and it'll still appear to work sometimes) in the wrong inputs, it will actually rename things on the filesystem but when the automation works, it's now updating the wrong files. I'm not stating that right but I definitely had some weirdness early on because I wasn't providing the Intermediate cert; instead I was using fullchain.pem
as the Certificate file, which gave me issues with VPN, for example.
@telnetdoogie I added a RSA only certificate and replaced it using the script, everything seems to work brilliantly now!
Thanks for the help!
This appears to miss all "WebStation" pages for me.
I added
# Add WebStation directories
for webstation in /usr/local/etc/certificate/WebStation/*/; do
debug "Found WebStation dir: ${webstation}"
target_cert_dirs+=("${webstation}")
done
But those then weren't re"compiled" into the correct folders nginx uses, so I wrote
# somehow WebStation ends up not getting applied later, so lets manually do it (if it works later it will simply get overwritten)
for ws in /usr/syno/etc/www/certificate/WebStation_*/; do
info "Copying WebStation certificates to '$ws'"
ws_crt=$( grep -o "$ws"cert.conf -Pe '(?<=ssl_certificate\s)\s*.*(?=;$)' | xargs )
ws_key=$( grep -o "$ws"cert.conf -Pe '(?<=ssl_certificate_key\s)\s*.*(?=;$)' | xargs )
ln -f "${certs_src_dir}/"fullchain.pem "$ws_crt"
ln -f "${certs_src_dir}/"privkey.pem "$ws_key"
done
which appears to be sufficient. I still had to add nginx -s reload
to get changes to show up.
Is this really the only way to do this?
In the process I grepped through my /usr
and also saw my cert ended up in /usr/local/etc/certificate/LogCenter/pkg-LogCenter/
somehow, so it might be good to add that path as
target_cert_dirs=(
[...]
"/usr/local/etc/certificate/LogCenter/pkg-LogCenter/")
# 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
The above lines should change to
if ! /usr/syno/bin/synow3tool --gen-all; then
warn "nginx failed to generate config"
fi
info "Restart nginx"
# Faster ngnix restart (if certs don't appear to be refreshing, change to systemctl restart)
systemctl reload nginx
Otherwise, systemctl reload nginx
will not be executed.
Otherwise,
systemctl reload nginx
will not be executed.
@xiaozhuai: I'm not sure I understand how the above is true (or why you want to separate out the two commands). The intent is that we do not restart if the certs did not generate correctly and instead issue a warning.
systemctl reload nginx
will be executed if and only if the synow3tool --gen-all
command is executed correctly, which is the intent of the original code.
Could you provide an example where this does not work as intended?
Could you provide an example where this does not work as intended?
@catchdave
That's odd.
I try this script on my machine last time and foud the second command never exec.
And I'm sure the /usr/syno/bin/synow3tool --gen-all
is ok.
Confirmed, the script is wrong. You can try below.
#!/usr/bin/env bash
if ! true && echo "Good"; then
echo "Not good"
fi
It prints nothing.
It should be
#!/usr/bin/env bash
if ! (true && echo "Good"); then
echo "Not good"
fi
And it prints Good
.
So the script should change to
# Faster ngnix restart (if certs don't appear to be refreshing, change to systemctl restart)
if ! (/usr/syno/bin/synow3tool --gen-all && systemctl reload nginx); then
warn "nginx failed to restart"
fi
Thanks --you are right, it should have parenthesis! I updated the script. Appreciate the suggestion, @xiaozhuai
Hello @catchdave. Nice script! I want to test it. But I have DS218+ where in all certs directories are not just 3 files which is copied by your script.
There are these structure:
cert.pem chain.pem fullchain.pem info privkey.pem root.pem short-chain.pem
I can create cert.pem chain.pem fullchain.pem privkey.pem
But I haven't idea about root.pem short-chain.pem.
Do you have same structure? Or is it something new? How to solve it? Thx for info.
@raven2cz my advice is to initially manually add your LE cert and make it default. Through the DSM interface, the mapping of LE generated files is:
Private Key ---------------> privkey.pem
Certificate ---------------> cert.pem
Intermediate Certificate --> fullchain.pem
Once that's done and the LE cert is now your default certificate, the script should work fine.
Great script. You may also be interested in my old scripts for managing certificates also for other apps like MailStation and co. Recently I added also synow3tool call to be able to reload nginx properly in DSM7. This script presents jsut a slightly different approach and was mainly developed for DSM6. If you have a reliable way of reloading services in the absence of /usr/local/libexec/certificate.d/$subscriber in DSM7 I would really appreciate
@telnetdoogie thank you for your quick reply.
I do have 2 certificates, one is my actual certificate. The other one is for quickconnect, but I can't delete that one. I also don't think it is the one causing problems.
But I think I see the problem. The certificate I'm using is RSA, but the old one from synology is RSA/ECC. The webserver is probally using ECC I guess, because the file ECC-cert.pem is still my old certificate. I'm just going to reset the certificates and readd them. But I have reached my request limit so I'll have to wait a bit.