Skip to content

Instantly share code, notes, and snippets.

@tfilo
Forked from catchdave/replace_synology_ssl_certs.sh
Last active January 1, 2025 10:11
Show Gist options
  • Save tfilo/940856c9ef91e6a28f0d310aa899bb2c to your computer and use it in GitHub Desktop.
Save tfilo/940856c9ef91e6a28f0d310aa899bb2c to your computer and use it in GitHub Desktop.
CLI script to programmatically replace SSL certs on Synology NAS
#!/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.
# Set domain to copy certificates from correct directory of certbot
NEW_CERT_DIRECTORY="/volume1/docker/certbot/config/live/MY_DOMAIN"
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
active_backup_dir="/usr/local/etc/certificate/ActiveBackup/ActiveBackup/"
synology_drive_dir="/usr/local/etc/certificate/SynologyDrive/SynologyDrive/"
certs_src_dir="/usr/syno/etc/certificate/system/default"
services_to_restart=("avahi") # ("nmbd" "avahi" "ldap-server")
packages_to_restart=("ScsiTarget" "SynologyDrive" "WebDAVServer" "ActiveBackup" "LogCenter" "ReplicationService")
target_cert_dirs=(
"${active_backup_dir}"
"${synology_drive_dir}"
"/usr/local/etc/certificate/LogCenter/pkg-LogCenter/"
"/usr/local/etc/certificate/ReplicationService/snapshot_receiver/"
"/usr/local/etc/certificate/ScsiTarget/pkg-scsi-plugin-server/"
"/usr/local/etc/certificate/WebDAVServer/webdav/"
"/usr/syno/etc/certificate/kmip/kmip/"
"/usr/syno/etc/certificate/smbftpd/ftpd/"
"/usr/syno/etc/certificate/system/FQDN"
)
# 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
# Add WebStation app directories
for webstation in /usr/local/etc/certificate/WebStation/*/; do
debug "Found WebStation dir: ${webstation}"
target_cert_dirs+=("${webstation}")
done
[[ "${DEBUG}" ]] && set -x
# 2. Compare new and old certificate checksum and proceed only if file changed
# =============================================================
new_cert_sum=$(sha256sum "${NEW_CERT_DIRECTORY}/fullchain.pem" | cut -d " " -f 1)
old_cert_sum=$(sha256sum "${certs_src_dir}/fullchain.pem" | cut -d " " -f 1)
if [[ "$new_cert_sum" == "$old_cert_sum" ]]; then
echo "The certificates have not changed, exiting."
exit 0
else
echo "The certificates have changed, proceeding."
fi
# 3. Move and chown certificates from /tmp to default directory
# =============================================================
cp ${NEW_CERT_DIRECTORY}/{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."
# 4. 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
# 5. Setting correct owner of SynologyDrive and ActiveBackup certificates
# ========================================================
if ! (chown ActiveBackup:ActiveBackup "$active_backup_dir"{privkey,fullchain,cert}.pem); then
warn "Error chowning ActiveBackup certs to in $active_backup_dir"
fi
if ! (chown SynologyDrive:SynologyDrive "$synology_drive_dir"{privkey,fullchain,cert}.pem); then
warn "Error chowning SynologyDrive certs to in $synology_drive_dir"
fi
# 6. Restart services & packages
# ==============================
info "Rebooting all the things..."
for service in "${services_to_restart[@]}"; do # Restart units if active
/usr/syno/bin/synosystemctl try-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 /usr/syno/bin/synosystemctl restart nginx); then
warn "nginx failed to restart"
fi
info "Completed"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment