通过 Docker 为群晖申请 SSL 证书，并设置自动更新

介绍

acme.sh：自动申请和更新证书的工具

Cloudflare：域名解析和托管平台（其中之一服务）

Let’s Encrypt：免费的证书颁发机构（有效期三个月）

准备

申请 Cloudflare Token

因为要对域名进行验证，需要先申请有编辑对应域名 DNS 权限的 Token：

在 用户 API 令牌 处点击创建令牌

选择编辑区域 DNS 处点击使用模板

之后在区域资源选择要申请证书的域名

保存

开启群晖 SSH 登录

登录群晖 Web，进入控制面板 -> 终端机和 SNMP，勾选启动 SSH 功能后保存。

注：另一种方案是直接通过群晖的任务计划执行每一个操作。

证书申请

以下操作是在成功通过 [[SSH]] 连接群晖的情况下执行，每个操作前 export 变量只要执行过一次即可，无须重复运行，在代码中显示只是为了更加直观。

默认情况下群晖的的账号没有加入 [[Docker]] 组，因此先切换到 root 账号方便操作，当然也可以为每个命令加 [[sudo]] 前缀执行，下面以切换到 root 账号为例子：

Copy
sudo -i

然后创建存放域名证书的文件夹：

Copy
mkdir -p /volume1/docker/acme.sh

注册 ACME 账号

Copy
export ACMEPATH="/volume1/docker/acme.sh" # 上一步创建的路径
export EMAIL="mail@example.com" # 用于注册 letsencrypt 的邮箱

docker run --rm \
-v "${ACMEPATH}":/acme.sh \
--net=host \
neilpang/acme.sh \
--register-account \
-m "${EMAIL}" \
--server letsencrypt

--rm：表示容器用完后立即销毁

--server：指定

申请证书

Copy
export ACMEPATH="/volume1/docker/acme.sh"
export DOMAIN="mail@example.com"
export CFTOKEN="Gl8exdSXRRwGxg5EjVnTDzYY42" # Cloudflare 申请的 Token

docker run --rm \
-v "${ACMEPATH}":/acme.sh \
-e CF_Token="${CFTOKEN}" \
--net=host \
neilpang/acme.sh \
--issue \
--dns dns_cf \
--ocsp \
--server letsencrypt \
-d "${DOMAIN}" \
-d "*.${DOMAIN}"

CFTOKEN 变量处填入 申请 Cloudflare Token 获取的 Token。

部署证书

Copy
export ACMEPATH="/volume1/docker/acme.sh"
export DOMAIN="immwind.com"
export USERNAME="username" # 群晖登录账号
export PASSWORD="password" # 群晖登录密码
export PORT="5001" # HTTPS 端口

docker run --rm \
-v "${ACMEPATH}":/acme.sh \
-e SYNO_Username="${USERNAME}" \
-e SYNO_Password="${PASSWORD}" \
-e SYNO_Scheme="https" \
-e SYNO_Port="${PORT}" \
-e SYNO_Certificate="A different certificate" \
--net=host \
neilpang/acme.sh \
--deploy --insecure \
--deploy-hook synology_dsm \
-d "${DOMAIN}" -d "*.${DOMAIN}"

SYNO_Certificate：是群晖证书界面对应域名下方的说明

部署完成后就可以在控制面板 -> 安全性 -> 证书处看到申请的域名证书，并进行设置。

自动更新证书配置

登录群晖 Web 后，进入控制面板：

选择任务计划

新增 -> 计划的任务 -> 用户定义的脚本

在任务设置 -> 运行命令部分填入下方内容（包括变量）

Copy
export ACMEPATH="/volume1/docker/acme.sh"
export DOMAIN="immwind.com"
export CFTOKEN="Gl8exdSXRRwGxg5EjVnTDzYY42"

export USERNAME="username" # 群晖登录账号
export PASSWORD="password" # 群晖登录密码
export PORT="5001" # HTTPS 端口

docker run --rm \
-v "${ACMEPATH}":/acme.sh \
-e CF_Token="${CFTOKEN}" \
--net=host \
neilpang/acme.sh \
--renew --force \
--dns dns_cf \
--ocsp \
--server letsencrypt \
-d "${DOMAIN}" -d "*.${DOMAIN}"

docker run --rm \
-v "${ACMEPATH}":/acme.sh \
-e SYNO_Username="${USERNAME}" \
-e SYNO_Password="${PASSWORD}" \
-e SYNO_Scheme="https" \
-e SYNO_Port="${PORT}" \
-e SYNO_Certificate="A different certificate" \
--net=host \
neilpang/acme.sh \
--deploy --insecure \
--deploy-hook synology_dsm \
-d "${DOMAIN}" -d "*.${DOMAIN}"

任务可以每月执行一次，不过为了确保任务正常运行，可以先手动执行一次看是否成功。

最后

配置完后，突然想起 [[ESXi]] 的证书也过期了许久，是不是也可以折腾下。

信息

环境

DSM 7.2

Docker 20.10.23

参考

Synology NAS Guide · acmesh-official/acme.sh Wiki

Options and Params · acmesh-official/acme.sh Wiki