贴上自己写的自动更新 ssl 证书脚本,以便帮助有需要的人。 ps:

  1. 这个脚本工作于我的 dsm6.2 ,如果是 dsm7 ,你可能需要更改下证书存放路径和服务重启方式(自己找找相关信息,思路是一样的)
  2. 由于运营商封 80 端口,所以不能使用 http challenge ,只能使用 dns challeng 。这个脚本使用的是 acme.sh 的 cloudflare 的 api ,如果要改成其它提供商如阿里云,请参考 acme.sh 相关文档,切换应该也很简单
#!/bin/bash

# Automatically update certs for Synology DSM6
# 1. Migrate your domain to Cloudflare, and create an A type record.
# 2. Generate a token with zone view authority and dns edit authority.
# 3. Install acme.sh on DSM6, no need crontabs: ./acme.sh --install --force -m my@example.com
# 4. Put this script into user defined task scheduler, executes per one month or two.
# 5. Make sure this script will be exectuted once immediately by your schedule task, or just execute it once mannually.

# Modify these as your own.
# See https://github.com/acmesh-official/acme.sh/wiki/dnsapi#using-the-new-cloudflare-api-token-you-will-get-this-after-normal-login-and--scroll-down-on-dashboard-and-copy-credentials
export CF_Account_ID="xxx"
export CF_Zone_ID="xxx"
export CF_Token="xxx"
DOMAIN_RECORD='example.com'

ACME_HOME=$HOME/.acme.sh
ACME_SH=$ACME_HOME/acme.sh

if ! command -v "$ACME_SH" &>/dev/null; then
    echo "Please install acme.sh."
    exit 1
fi

DOMAIN_CERT_HOME="$ACME_HOME/$DOMAIN_RECORD"

TARGET_DIRS=(
    "/usr/syno/etc/certificate/_archive/$(head -n1 /usr/syno/etc/certificate/_archive/DEFAULT | xargs echo -n)"
    '/usr/syno/etc/certificate/system/default'
    '/usr/syno/etc/certificate/smbftpd/ftpd'
    '/usr/local/etc/certificate/CardDAVServer/carddav'
    '/usr/local/etc/certificate/SynologyDrive/SynologyDrive'
    '/usr/local/etc/certificate/WebDAVServer/webdav'
)

issue_or_renew() {
    cert_issued=0
    domains=()
    while IFS='' read -r line; do domains+=("$line"); done < <($ACME_SH --list | awk '{print $1}')
    for domain in "${domains[@]}"; do
        if [ "$domain" = "$DOMAIN_RECORD" ]; then
            cert_issued=1
            break
        fi
    done
    if [ "$cert_issued" -eq 0 ]; then
        rm -rf "$DOMAIN_CERT_HOME"
        # Issue certs via zerossl, or via letsencrypt you'd have to update ca-certificates on DSM6.
        # Since DSM6 does not support ecc, rsa(-k) should be specified, or system default certs will be overridden by DSM6 when reboots.
        $ACME_SH --issue --server zerossl --dns dns_cf -d $DOMAIN_RECORD -k 2048
    else
        $ACME_SH --renew --force -d $DOMAIN_RECORD
    fi
}
copy_certs() {
    echo "Copying certs...."
    for dir in "${TARGET_DIRS[@]}"; do
        install -m 400 "$DOMAIN_CERT_HOME/$DOMAIN_RECORD.cer" "$dir/cert.pem"
        install -m 400 "$DOMAIN_CERT_HOME/$DOMAIN_RECORD.key" "$dir/privkey.pem"
        install -m 400 "$DOMAIN_CERT_HOME/fullchain.cer" "$dir/fullchain.pem"
    done
    echo "Certs copy completed."
}

restart_services() {
    echo "Restarting services...."
    nginx -s reload
    /var/packages/WebDAVServer/scripts/start-stop-status stop
    /var/packages/CardDAVServer/scripts/start-stop-status stop
    sleep 20
    /var/packages/WebDAVServer/scripts/start-stop-status start
    /var/packages/CardDAVServer/scripts/start-stop-status start
    /var/packages/SynologyDrive/scripts/start-stop-status restart
    echo "Services restart completed."
}

echo '--------------------------------------'
issue_or_renew
copy_certs
restart_services