再聊如何在群晖上申请与续期证书
前言
小伙伴说他家里的群晖无法使用外网连接了,我一看发现原来是证书问题。之前我是用 Docker 帮他安装 acme.sh 的,但不知是不是因为小伙伴升级群晖系统了,现在群晖管理员账号登陆要使用 TOTP 来验证,故之前使用 Docker 安装的 acme.sh 已经没法将证书部署到群晖上了。同样的问题在我自己的群晖上也出现了,小伙伴不爱折腾,升级系统的频率很低,因此到今天才发现这个问题。我之前解决 TOTP 验证的方法是添加一个变量,export SYNO_DEVICE_ID="浏览器中的 cookie 值"
。但现在再看文档1发现方法好像更新了,新方法看着好像挺简单的,但我已经不想再折腾了。直接使用 acme.sh 推荐的自动创建临时管理员用户的方法,其优点无需提供任何管理员账号和密码,缺点就是 acme.sh 只能在本地部署,不再支持使用 Docker 来运行。
当然,如果想继续使用 Docker 的方式来部署的话还是有办法,就是感觉配置起来有点麻烦。我更推荐在 Docker 上部署 certbot 来申请与续期证书。
came.sh
开启端口
群晖 -> 控制面板 -> 终端机和 SNMP -> 勾选 启动 SSH 功能 (在不连接时记得取消勾选)
ssh 管理账号@群晖内网IP -p 22
安装
sudo su
cd ~
wget https://github.com/acmesh-official/acme.sh/archive/master.tar.gz
tar xvf master.tar.gz
cd acme.sh-master/
./acme.sh --install --nocron --home /usr/local/share/acme.sh --accountemail "email@msn.com"
配置变量(以 Cloudflare 为例)
cd /usr/local/share/acme.sh
vim acme.sh.env
# 添加以下变量并修改其对应的值
export SYNO_USE_TEMP_ADMIN=1
export CERT_DNS="dns_cf"
export CF_Token="Cloudflare Token"
export CF_Email="Cloudflare 账号"
export CERT_DOMAIN="申请的域名"
export SYNO_Hostname="localhost"
export SYNO_Scheme="http"
export SYNO_Port="5000"
export SYNO_Certificate="申请的域名"
首次颁发证书(例如 Let’s Encrypt)时(而不是续订证书)
export SYNO_CREATE=1
必须执行一次。任何后续运行都不需要该变量,因此它根本不会保存在您的配置文件中。
根据文档上的说明,若首次颁发证书的添加以下变量
export SYNO_CREATE=1
载入添加的变量
source ~/.profile
注:若域名托管在其他服务商,可到官方文档里查看相应的 DNS API2。
创建与部署证书
cd /usr/local/share/acme.sh
# 创建证书
./acme.sh --issue --home . -d "$CERT_DOMAIN" --dns "$CERT_DNS"
# 部署证书
./acme.sh --deploy --home . -d "$CERT_DOMAIN" --deploy-hook synology_dsm
若部署证书时提示 API 服务器的证书不被信任,可以在部署时添加 --insecure
这个参数。
自动续期
群晖 -> 控制面板 -> 任务计划 -> 新增 -> 计划的任务 -> 用户定义的脚本
常规
任务名称:随意
用户账号:root
计划
设置成每周更新即可。如,每周六上午 11:00。
任务设置
用户定义的脚本
/usr/local/share/acme.sh/acme.sh --cron --home /usr/local/share/acme.sh
至此 acme.sh 本地部署的方法分享完毕,接下来分享使用 Docker 来部署 certbot 来搞定群晖证书的申请、部署、续期。
certbot
拉取所需镜像
certbot/dns-cloudflare
国内拉取镜像的方法
注册表镜像 URL 来自 @obaby3
准备工作
在本地创建与容器绑定的目录
mkdir -p /volume3/docker/certbot
mkdir -p /etc/letsencrypt
mkdir -p /var/lib/letsencrypt
mkdir -p /var/log/letsencrypt
/volume3/docker/certbot
该目录用作保存 Cloudflare Token4,可自定义路径,修改后记得也要将其对应的路径修改到下面的命令中。
申请证书
docker run -it --rm --name certbot \
-v "/volume3/docker/certbot/cloudflare.ini:/opt/certbot/cloudflare.ini" \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
-v "/var/log/letsencrypt:/var/log/letsencrypt" \
certbot/dns-cloudflare certonly --non-interactive --agree-tos --email i@iamlm.com --dns-cloudflare --dns-cloudflare-credentials /opt/certbot/cloudflare.ini --dns-cloudflare-propagation-seconds 30 -d nas.iamlm.com
申请好证书后需将证书保存到本地,然后通过「控制面板」 -> 安全性 -> 证书 -> 新增 -> 导入刚才申请的证书并设置为默认证书
续期证书
查看 Docker 路径,群晖的自定义脚本建议使用完整路径来调用。
which docker
/usr/local/bin/docker
如上,配置一个定义的脚本,运行以下命令
/usr/local/bin/docker run --rm --name certbot \
-v "/volume3/docker/certbot/cloudflare.ini:/opt/certbot/cloudflare.ini" \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
-v "/var/log/letsencrypt:/var/log/letsencrypt" \
-v "/usr/syno/etc/certificate/_archive/Bek8oS:/target" \
certbot/dns-cloudflare renew --non-interactive --agree-tos --email i@iamlm.com --dns-cloudflare --dns-cloudflare-credentials /opt/certbot/cloudflare.ini --deploy-hook "cp -fLR /etc/letsencrypt/live/nas.iamlm.com/* /target/"
当前默认证书路径 /usr/syno/etc/certificate/_archive/Bek8oS
可通过 cat /usr/syno/etc/certificate/_archive/DEFAULT
查看到当前默认证书的证书ID。
注:将 /usr/syno/etc/certificate/_archive/Bek8oS
与容器内部的 target
目录进行绑定,当证书续期成功时就会触发 cp -fLR /etc/letsencrypt/live/nas.iamlm.com/* /target/
,进而更新默认证书目录下的证书文件。
附群晖存放证书的目录
以下内容引用自@奇奇博讯5
1、SSL证书根目录
/usr/syno/etc/certificate/
2、所有SSL证书目录
/usr/syno/etc/certificate/_archive/
3、当前的默认证书文件
/usr/syno/etc/certificate/_archive/DEFAULT
4、SSL证书配置文件
/usr/syno/etc/certificate/_archive/INFO
5、相关SSL证书
/usr/syno/etc/certificate/_archive/证书ID
6、系统自带证书目录
/usr/syno/etc/certificate/system/default/