再聊如何在群晖上申请与续期证书

前言

小伙伴说他家里的群晖无法使用外网连接了,我一看发现原来是证书问题。之前我是用 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

国内拉取镜像的方法

CleanShot-2024-08-25-at-14.42.44@2x

注册表镜像 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/

Footnotes

  1. deployhooks · acmesh-official/acme.sh Wiki

  2. dnsapi · acmesh-official/acme.sh Wiki

  3. 通过 CF 自建 Docker 镜像 – obaby@mars

  4. Certbot申请泛域名证书与续期 | 老麦笔记

  5. 群晖DSM SSL证书路径 - 叨叨念念 - 奇奇博讯