- DSM có thể dùng Lets’s Encrypt tạo wildcard SSL certificate dùng chung cho domain và tất cả các subdomain, tuy nhiên chỉ áp dụng cho domain thuộc Synology.
- SSL certificate của Synology có hạn dùng 1 năm so với các free certificate khác có hạn dùng 3 tháng. Tuy nhiên vì có thể auto renew các chứng chỉ bảo mật nên hạn dùng không là vấn đề.
- Có thể import SSL certificate từ nguồn khác vào DSM và chọn dùng cho từng dịch vụ web cụ thể.
Chúng ta có thể tạo wildcard SSL certificate của Let’s Encrypt từ máy tính khác như Raspberry Pi và import vào Synology NAS qua script.
Hoạt động của script như sau:
- Theo dõi certbot renew. Nếu không có chứng chỉ SSL mới thì thoát
- Chép chứng chỉ SSL mới cho tất cả các dịch vụ có dùng SSL trên Synology NAS
- Nếu một dịch vụ được cài đặt dùng chứng chỉ SSL của Synology thì DSM tự phục hồi chứng chỉ Synology
- Khởi động lại các dịch vụ có dùng SSL certificate
#!/bin/bash
# renew_certs.sh
# LNT <lnt@ly-le.info>
# -------------------
# domain cần update certs
DOMAIN='your.domain'
certbot -q renew --post-hook "touch /tmp/new_certs" &>/dev/null
[ ! -f /tmp/new_certs ] && exit
### Update NAS certs ###
NAS_SERVER='your_nas_ip'
# user có thể ssh tới NAS, có thể sudoer
SSL_USR="user@${NAS_SERVER}"
SSL_PORT=22
# script replace_certs.sh
REPLACE_CERTS='/path/to/replace_certs.sh'
# Nơi chứa certs
CERTS_DIRECTORY="/etc/letsencrypt/live/$DOMAIN"
echo "### Copying certificates to NAS ###"
scp -P ${SSL_PORT} ${CERTS_DIRECTORY}/{privkey,fullchain,cert}.pem ${SSL_USR}:/tmp/
if [ "$?" = "0" ]; then
echo "### Copying script to NAS ###"
scp -P ${SSL_PORT} ${REPLACE_CERTS} ${SSL_USR}:
echo "### Updating certificates to NAS ###"
ssh -p ${SSL_PORT} -t ${SSL_USR} 'sudo ./replace_certs.sh'
if [ "$?" != "0" ]; then
echo "--- ERROR Updating certificates to NAS ---"
fi
else
echo "--- ERROR Copying certificates to NAS ---"
fi
- Script này được gọi chạy thay cho lệnh certbot renew thông thường. Thí dụ trong file /etc/cron.d/certbot, thay đoạn certbot renew -q thành /path/to/renew_certs.sh
- SSL_USR phải có thể ssh đến NAS
- Ngoài ra để có thể chạy script
${REPLACE_CERTS}
trên NAS với quyền root thì${SSL_USR}
phải có thể sudoer
${SSL_USR} (ALL:ALL) ${REPLACE_CERTS}
# !/bin/bash
# replace_certs.sh
# Cải tiến script của catchdave, dành cho DSM 7.2
# LNT <lnt@ly-le.info>
# -------------------
DEBUG=0 # 0 or 1
error_exit() { echo "[ERROR] $1"; exit 1; }
warn() { echo "[WARN] $1"; }
info() { echo "[INFO] $1"; }
debug() { [[ "${DEBUG}" ]] && echo "[DEBUG] $1"; }
[[ "$EUID" -ne 0 ]] && error_exit "Please run as root!"
[ ! -f /tmp/cert.pem ] && error_exit "No new certs!"
services_to_restart=("nmbd" "avahi" "ldap-server")
packages_to_restart=()
syno_cert_dir='/usr/syno/etc/certificate'
certs_src_dir="$syno_cert_dir/system/default"
target_cert_dirs=( "$syno_cert_dir/system/FQDN" )
default_dir_name=$(cat $syno_cert_dir/_archive/DEFAULT 2>/dev/null)
if [[ -n "$default_dir_name" ]]; then
target_cert_dirs+=( "$syno_cert_dir/_archive/${default_dir_name}" )
(( $DEBUG )) && debug "Default cert directory found: '$syno_cert_dir/_archive/${default_dir_name}'"
else
error_exit "No default directory found! See $syno_cert_dir/_archive/DEFAULT"
fi
mapfile -t tmp <<< $(find ${syno_cert_dir}/smbftpd -mindepth 1 -maxdepth 1 -type d 2>/dev/null)
if (( ${#tmp[@]} )); then
target_cert_dirs+=( ${tmp[*]} )
(( $DEBUG )) && debug "SMB or FTPD found!"
else
warn "No SMB and FTPD found!"
fi
mapfile -t tmp <<< $(find ${syno_cert_dir}/AppPortal -mindepth 1 -maxdepth 1 -type d 2>/dev/null)
if (( ${#tmp[@]} )); then
target_cert_dirs+=( ${tmp[*]} )
(( $DEBUG )) && debug "App Portal found!"
else
warn "No App Portal found!"
fi
mapfile -t tmp <<< $(find ${syno_cert_dir}/ReverseProxy -mindepth 2 -maxdepth 2 -type d 2>/dev/null)
if (( ${#tmp[@]} )); then
target_cert_dirs+=( ${tmp[*]} )
(( $DEBUG )) && debug "Reverse Proxy found!"
else
warn "No Reverse Proxy found!"
fi
mapfile -t tmp <<< $(find /usr/local/etc/certificate -mindepth 2 -maxdepth 2 -type d 2>/dev/null)
if (( ${#tmp[@]} )); then
target_cert_dirs+=( ${tmp[*]} )
oIFS=$IFS
IFS=$'\n'
packages_to_restart=( `for path in ${tmp[@]}; do echo $path | awk -F/ '{print $6}'; done | sort -du`)
IFS=$oIFS
(( $DEBUG )) && debug "Packages found!"
else
warn "No Package found!"
fi
if (( $DEBUG )); then
echo "--- ${target_cert_dirs[@]} ---"
set -x
else
mv /tmp/{privkey,fullchain,cert}.pem "${certs_src_dir}/" 2>/dev/null || 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"
fi
info "Certs moved from /tmp & chowned."
if ! (( $DEBUG )); then
for target_dir in "${target_cert_dirs[@]}"; do
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
fi
info "Rebooting all the things..."
if ! (( $DEBUG )); then
for svc in "${services_to_restart[@]}"; do
/usr/syno/bin/synosystemctl restart "$svc"
done
for pkg in "${packages_to_restart[@]}"; do
/usr/syno/bin/synopkg is_onoff "$pkg" 1>/dev/null && /usr/syno/bin/synopkg restart "$pkg"
done
if ! /usr/syno/bin/synow3tool --gen-all && sudo systemctl reload nginx; then
warn "nginx failed to restart"
fi
fi
info "Completed"
Chú thích
- Nếu DEBUG=1, script không chép SSL certificate cho các dịch vụ cần thiết mà chỉ liệt kê các thư mục cần cập nhật SSL
- Mặt khác, có thể export Synology SSL certificate để dùng cho máy khác thro cách tương tự