群晖自动申请、安装、续期 SSL 证书
记录一套在群晖上自动申请、部署与续期 SSL 证书的方案:基于 acme.sh、ZeroSSL 与 Cloudflare DNS API,结合 Container Manager 和计划任务实现证书的长期自动化管理。
事情的起因是大概几个月前断断续续收到了十几封来自阿里云的邮件,去年申请的 SSL 证书全部到期了。本来我还在琢磨更新那么多证书得折腾多久,然后就看到了阿里云的公告:免费 SSL 证书签发后的有效期统一变更为 3 个月。
再三斟酌下,我决定还是另寻他法,于是折腾了一下自动申请、安装、续期 SSL 证书的方法,结果一直拖着没有写这篇文章。直到 NAS 迁移后因为设置错误导致证书再次过期,折腾了一宿后才鼓起劲顺便完成这篇文章。
一、前言
首先需要声明,我已经提前做了一些准备工作,例如将域名管理托管至 Cloudflare。相比于阿里云,Cloudflare 的功能更加强大,简直就是良心企业。当然这不是必要条件,只是本文所有配置均以 Cloudflare 为例。
本文将涉及以下内容:
- ACME(用于申请证书的脚本)
- ZeroSSL(提供免费的 SSL 证书,配合 ACME 食用更佳,可以免费申请泛域名证书)
- Cloudflare(不必多说,实力强大的云服务提供商)
至于 SSL 是什么,SSL 有什么好处云云便不再赘述,感兴趣的话自行使用搜索引擎了解即可。
二、群晖 Container Manager 安装 acme.sh
首先在 docker 目录下创建 acme 文件夹。
为其添加读写权限。
然后在 Container Manager 注册表中搜索 neilpang/acme.sh 并下载。
运行映像开始安装,容器名称可以自定义,建议勾选 启动自动重新启动。
将 /docker/acme 文件夹映射至 /acme.sh。
添加部署信息
添加部署信息时涉及到群晖的用户名和密码,你可以通过临时管理员的角色来避免提供任何敏感信息;也可以在系统环境变量中设置用户名密码;当然也可以像我一样直接添加在容器的环境变量中,至于选择哪种方式请自行斟酌。
如果你开启了两步验证,那么还需要添加额外的环境变量,我这里提供一份 官方配置文档 供大家参考,这里以添加至容器的环境变量中为例。
配置项说明:
|
|
添加 DNS API
添加 Cloudflare API 同样可以采取两种方法,其他云服务商 API 可以参考这篇文档:How to use DNS API
方法一:使用 restrictive API(推荐)
登录 Cloudflare,在我的个人资料页面创建 API 令牌。
使用 编辑区域 DNS 模板。
按照图片所示填写,区域选择对应域名,点击继续并创建令牌。此令牌仅出现一次,后续无法再次查询,所以记得保存下来。
除了 Token 以外,还需要 zone ID。在主页选择网站后,下拉即可看到对应 zone ID。
在 docker 环境变量中,添加 CF_Token 和 CF_Zone_ID 两个字段,值分别是上方获取到的令牌和 zone ID。
方法二:使用 global API(不推荐)
这个方法有一定的安全隐患,所以不推荐使用,优点就是简单快捷。依然是刚才创建 API 令牌的位置,下方点击输入密码后查看 Global API Key。
此时在 docker 环境变量中,添加 CF_Key 和 CF_Email 两个字段,值分别是上方获取到的 Global API Key 和 Cloudflare 账户邮箱地址。
网络 & 执行命令
网络使用 host,命令填写 daemon 以守护进程,最后保存并启动容器。
三、自动申请、安装、续期证书
ZeroSSL 的证书有效期是 90 天,因此需要定期申请证书,这里使用群晖的计划任务来完成。
创建并上传脚本
本地创建 fetch.sh 脚本文件并上传至群晖 docker/acme 目录下,第一行代码是申请证书,第二行是将证书部署至群晖。注意将 邮箱地址 改为 Cloudflare 账户邮箱,将 example.com 更改为自己的域名。
|
|
添加计划任务
打开群晖控制面板,选择 任务计划 -> 新增 -> 计划的任务 -> 用户定义的脚本,任务名称随意,用户账号选择 root。
时间随便选一个,选择 每月重复。
根据需求选择是否需要通过邮件发送运行详情,运行命令处填写如下脚本,该脚本会将上方创建的脚本运行日志保存为 /docker/acme 下的 log.txt 文件。
|
|
点击确定保存后,右键该任务并运行。
如果没有出错的话,可以在 控制面板 -> 安全性 -> 证书 中看到申请的证书,那么到这里就大功告成了!如果发现并没有新的证书,则可以查看日志排查对应的错误。