Acme.sh——自动证书管理工具-使用备忘

什么是Acme.sh

包括Lets在内的免费证书,纷纷响应号召,将免费证书的有效期从一年缩短到三个月甚至一个月。且如今泛证书也只能实现二级子域名的覆盖(即:x.xxxx.com),对于三级子域名,套用泛证书,游览器 / TLS库 连接依然会报不信任。

在免费证书有效期不断缩短的背景下,项目一多,或者说:域名 / 子域名一多,那么证书管理就是相当痛苦的事情,笔者自建的Derper服务器便因为证书过期在关键时刻掉链子,连不上远端的NAS。于是这里就记录一下使用Acme.sh自动管理证书的笔记,以供备忘或便利他人。Acme.sh是一个自动申请证书的实用程序,它可以做到:

  • 通过 DNS / HTTP 等方式自动获取TLS证书 (HTTP方式可配合nginx等一起使用,也可占用80端口完成验证;DNS方式也可以通过配置APIKEY实现自动获取)
  • 部署证书,将证书以指定名字导出到指定目录。
  • 定期renew先前自动申请的证书,并且能够根据预设的脚本,自动部署到程序上
  • …..

项目地址:https://acme.sh/

中文文档地址:https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E

安装

安装也是非常简单的,不过程序会从github上下载必要的文件,所以必要时请通过环境变量设置HTTP代理。

另外:程序支持使用该环境变量,如果环境网络特殊也可以在使用过程中用。

export http_proxy="socks5h://xxxx:1081"
export https_proxy="socks5h://xxxx:1081" 

随后运行一键安装指令:

curl https://get.acme.sh | sh -s email=my@example.com

这个my@example.com是用于申请证书的,在证书被吊销/出问题的时候由证书提供方发出通知。建议写一个真实邮箱以防万一,另:letsencrypt为了防止滥用,禁止么my@example.com这个邮箱的注册。

安装完成后,会自动创建一个定时任务,acme.sh会自动检测证书是否要到期,并在到期前完成续签等操作。

为此,你可以输入 crontab -e 检查一下。

使用

生成一个证书(DNS模式)

此处以笔者使用的阿里DNS为例,更多DNS请参阅:https://github.com/acmesh-official/acme.sh/wiki/dnsapi,下文将简单说明如何在阿里云中建立API,如果读者已有可以跳过。

使用子用户的AccessKey(推荐)

在https://ram.console.aliyun.com/users创建一个子用户即可,名字和备注随意,访问方式勾选“OpenAPI调用访问”,随后在跳转过去的页面中点击复制AccessKeyID和AccessSecret,并妥善保存 (只会显示一次)

image-20240518193608733

接下来,点击用户名,进入管理界面,选择“权限管理”->“新增授权”,搜索DNSFullAccess添加,点击确定即可。

image-20240518193422969

使用主账户的AccessKey(不推荐,不符合最小权限管理原则,但简单)

进入https://ram.console.aliyun.com/manage/ak,在弹出的对话框中选择“继续使用AccessKey”,随后点击创建即可。


完成操作后,将得到的AccessKey和KeyID写入环境变量:

export Ali_Key="<key>"
export Ali_Secret="<Secret>"

接下来,输入指令让acme.sh自动完成证书申请即可

acme.sh --issue --dns dns_ali -d xxx.com

一部分参数备注

-d 可以有多个,可以同时申请为多个子域申请证书

可以通过 –server 参数指定出来那家证书,详细列表可以参考:https://github.com/acmesh-official/acme.sh/wiki/CA,默认是ZeroSSL。

如果在这个过程中出错,可以在指令中加入 –debug 参数,根据日志找出错误,往往是权限没有配置好导致的。

部署证书

直接复制证书,或者将程序中引用证书的路径指向acme.sh保存证书的路径固然可行,但是这样就无法体验acme.sh的自动管理功能,故我们会使用acme.sh文档中的“部署证书”的方式去实现部署。

直接上说明文档命令:

acme.sh --install-cert -d example.com \
--cert-file      /path/to/certfile/in/apache/cert.pem  \
--key-file       /path/to/keyfile/in/apache/key.pem  \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd     "service apache2 force-reload"

略微修改一下,变成符合我们需要的命令:

acme.sh --install-cert -d xxxxxx \
--cert-file      /projects/derper/cert/xxxxxx \
--key-file       /projects/derper/cert/xxxxxx  \
--reloadcmd     "docker compose restart derper"

可选参数:–fullchain-file

这样操作后,会在更新证书后自动将新的证书覆盖到配置的路径,并重启docker容器,实现更新证书的目的。

根据官方文档,如果要修改路径,就重新走一遍这个流程。