由于腾讯云的TrustAsia免费证书有效期从一年改为了三个月,每次重新申请证书及重新部署到各个设备都很麻烦,所以改为使用 ZeroSSL的免费证书,并实现自动化部署。

安装acme.sh

acme.sh是用来申请免费证书的脚本。由于我使用的是群晖,脚本会在系统更新时删除而且没有crontab来定期续签,所以使用docker进行安装。 发现使用docker版本部署群晖需要显式提供密码,而且后来发现本来就是sh脚本,没必要硬上docker,唯一的问题是群晖没有crontab,所以安装时得注意,且得在web端中设置定时任务。使用root安装是为了部署到群晖时有相应权限,详见下文

sudo -i
git clone --depth 1 <https://github.com/acmesh-official/acme.sh.git>
cd acme.sh
./acme.sh --install \\
--home /volume1/scripts/acme.sh \\
--accountemail  "[email protected]" \\
--noncron

安装完成后需重新登录shell。

签发证书

acme.sh现在默认使用ZeroSSL发行证书,而不再是Let's Encrypt了。首先注册ZeroSSL账号,并前往左侧栏中Developer页面,获取EAB Credentials,之后使用以下代码进行注册。这样注册之后是可以在ZeroSSL看到签发的证书的。

EAB Credentials

acme.sh  --register-account  --server zerossl \\
        --eab-kid  xxxxxxxxxxxx  \\
        --eab-hmac-key  xxxxxxxxx

之后开始申请签发证书,我使用的是DNS验证方法。我的域名是使用DNSPod解析的,所以使用相应的选项,你也可以在dnsapi中找到其他DNS平台的使用方法。

export DP_Id="<id>"
export DP_Key="<key>"
acme.sh --issue --dns dns_dp -d example.com -d *.example.com

之后设置部署钩子(deploy hooks),在每一次证书签发之后都会自动重新进行部署。

部署至群晖

将证书部署到群晖上较为复杂,提供的脚本中有两种方式:创建临时用户进行设置和使用现有管理员账号密码进行设置。创建临时用户进行设置需要root权限,并且需要在本机上进行,那么用docker版和远程部署。否则的话得使用管理员账号密码,可能还需要二次验证码之类的。

我们这里介绍在本机上使用root进行部署,最为安全方便。直接export SYNO_USE_TEMP_ADMIN=1,然后acme.sh --deploy --deploy-hook synology_dsm -d example.com,完事了。

如果你的群晖设置不太一样,需要首先配置其他环境变量:

export SYNO_SCHEME="http"
export SYNO_HOSTNAME="localhost"
export SYNO_PORT="5000"
export SYNO_CREATE=1
export SYNO_CERTIFICATE=""

部署至路由器

https://github.com/acmesh-official/acme.sh/wiki/deployhooks#3-deploy-the-cert-to-remote-server-through-ssh-access要求能够不用密码ssh到远程服务要求器,也就是需要配置密钥进行登陆。

参考了https://blog.mstg.top/archives/978来进行设置。我的路由器是`RT-AX86U Pro,用的是koolshare的梅林改版固件,版本是3004.388.4。不知道是不是路由器架构不一样还是固件版本不一样,我路由器存放证书的位置在/jffs/.cert里面,证书拷贝进去后/sbin/service restart_httpd`重启网络服务就能更新路由器证书了。

接下来设置以下环境变量:

变量作用
DEPLOY_SSH_USERadminSSH用户名
DEPLOY_SSH_SERVER192.168.50.1目的服务器/路由器ip地址
DEPLOY_SSH_KEYFILE/jffs/.cert/key.pemSSL证书key文件安装路径
DEPLOY_SSH_FULLCHAIN/jffs/.cert/cert.pemSSL证书文件安装路径
DEPLOY_SSH_REMOTE_CMD/sbin/service restart_httpd部署后需要执行的命令(这里以梅林固件重启http服务为例)
DEPLOY_SSH_MULTI_CALLyes是否采用拆分多个SSH调用,以解决命令行缓冲区不足

之后执行命令:

acme.sh --deploy -d example.com --deploy-hook ssh

另外由于我部署至群晖和路由器时是分开进行的,所以每次自动部署时只会自动部署最后一项任务。在证书目录example.com_ecc下找到配置文件example.com.conf,将Le_DeployHook='ssh'改为Le_DeployHook='ssh,synology_dsm',则每次更新证书都会重新部署所有任务。

部署至腾讯云

  • SSH到群晖之后安装miniconda
  • 创建虚拟环境conda create -n web --python=3.11
  • 从github下载zfb132/qcloud-ssl-cdn,用来更新腾讯云证书
  • 切换到虚拟环境conda activate web,并安装依赖项pip install requests tencentcloud-sdk-python
  • 修改config.example.py参数,根据注释修改每一项内容,然后重命名为config.py
  • 运行python main.py更新证书

设置群晖定时任务

"/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh"

群晖定时任务里设置该命令,将"/home/user/.acme.sh"改成你自己的安装目录。该命令能够检查acme.sh的更新,之后检查证书是否快要到期然后续签并部署。

"~/.miniconda3/bin/python" "~/qcloud-ssl-cdn"/main.py

群晖定时任务设置更新腾讯云SSL证书,"~/.miniconda3"设置为python的绝对路径(可以在虚拟环境里面使用which python获得),"~/qcloud-ssl-cdn"设置为你自己的下载地址。

Todos

使用 GitHub - dromara/domain-admin: 域名SSL证书监测平台、SSL证书申请自动续签。Domain and SSL Cert monitor System. 进行多域名证书管理。