acme.sh-ssl-logo.png

前言

之前有使用过 certbot 工具来进行免费 SSL 证书的申请和更新;最近接触了 acme.sh 项目,个人感觉比 certbot 更加轻便,纯 shell 脚本,无依赖;并且功能更加丰富,证书续期也支持自动 wellknown 和各种 dns api 验证;支持自定义 notify 和各种 hook 操作;

acme.sh项目地址https://github.com/acmesh-official/acme.sh

更详细的高级使用方法,请参考: acme.sh官方wiki手册

这里记录一下 acme.sh 的基本使用方式,作为备忘;

安装

安装过程非常简单,使用如下一条指令,任选一条即可;后面的 email 设置为你计划用来申请证书的邮箱

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

命令执行完成后,acme.sh 的所有相关脚本和文件都会被统一安装到当前账号家目录下的 .acme.sh/ 目录下

会自动在 .bashrc 文件中添加 alias acme.sh=~/.acme.sh/acme.sh 后续可直接运行 acme.sh 指令而不用输入完整路径;

不过需要重新登录,或者手动执行 source ~/.bashrc 后才会生效;

切换 CA 服务商

acme.sh 默认是使用 ZeroSSL 的 CA 进行免费证书的签发;如果你希望使用 Let's Encrypt 的免费证书,则需要执行如下命令切换到使用 Let's Encrypt 的 CA 服务器进行证书申请和签发

acme.sh --set-default-ca --server letsencrypt

申请新证书

先确定使用哪种验证方式(DNS txt验证,还是 webroot .well-know 文件验证)

  • 如果使用 DNS txt 验证,则需要先准备好对应 DNS API 的访问 ID 和 key;
    (当然也可以纯手动添加 txt 验证,不过以后就没办法自动进行证书续期,续期时也必须手动设置 txt 记录进行验证)
  • 如果使用 webroot 文件验证,则需要先将要申请的域名DNS A记录解析指向到当前的服务器IP上;
    同时准备好当前服务器 web server 的 webroot dir 完整路径

DNS验证,申请新证书

手动DNS验证 (无法自动续期)

执行如下指令后,根据输出的提示,在 DNS 上手动新增一笔 txt 记录

acme.sh --issue --dns -d domain.com -d www.domain.com -d mail.domain.com

设置好 txt 记录后,执行如下指令进行证书验证和签发

acme.sh --renew -d domain.com

自动DNS验证

acme.sh 支持非常多的 DNS API 对接,以自动完成 DNS TXT 的添加和验证;可以在 ~/.acme.sh/dnsapi/ 目录下找到所支持的各种 dns api 的对接脚本

以 dnspod 为例:

# 首次执行,需要先用环境变量的方式传递DNS API 的 ID 和 Key,证书申请成功后,该变量参数会自动保存到配置文件里供以后续期使用;
export DP_Id="334456"
export DP_Key="azkeiAJivce4lXIcew234fFxe"

# 执行指令申请新证书,支持通配符证书
acme.sh --issue --dns dns_dp -d example.com -d *.example.com

WebRoot 文件验证,申请新证书

首先确保要申请的域名 DNS 的 A 记录已经正确解析指向到了当前服务器的IP,
其次,确保当前服务器 IP 的 http 80 端口可以正常访问,且可以浏览 webroot 路径下的文件内容

然后执行如下指令进行新证书的签发

# 通用模式,手动指定要申请的域名和 webroot 路径
acme.sh --issue -d domain.com -d www.domain.com --webroot /home/wwwroot/mydomain.com/

# 如果是标准安装的 apache web 服务器,可执行如下指令自动从 apache 配置文件定位 webroot 路径完成验证
acme.sh --issue --apache -d domain.com -d www.domain.com -d mail.example.com

# 如果是标准安装的 nginx web 服务器,执行如下指令自动从配置文件定位 webroot 路径完成验证
acme.sh --issue --nginx -d domain.com -d www.domain.com -d mail.domain.com

如果服务器上当前没有安装任何的 web 服务器,且 80 端口未被占用,
则可以使用 --standalone 参数让 acme.sh 在申请证书的过程中,临时启动一个内置的 http 服务来完成 webroot 的验证工作;(该模式需要 socat 工具的支持,请确保服务器有安装 socat

acme.sh --issue --standalone -d domain.com -d www.domain.com -d mail.domain.com

如果验证通过,则新证书的申请与签发就完成了,新的证书和私钥都会默认保存在 ~/.acme.sh/[你的域名]/目录下

安装证书

证书申请签发完成后,通常我们还希望能将新申请的证书安装或替换到要使用证书的应用程序目录下,
并且最好是能在证书安装完成后自动重启或reload 我们的应用程序,让新的证书立即生效;

刚好 acme.sh 都为我们准备好了这一切,它提供了 --install-cert 参数,可以帮我们完成这一切

# --install-cert 参数可以分别指定 key 和 证书文件需要安装到的目录路径
# --reloadcmd 指定在证书安装完成后所需要执行的指令
acme.sh --install-cert -d domain.com \
--key-file       /path/to/keyfile/in/nginx/key.pem  \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd     "systemctl reload nginx"

以上指令执行完毕后不仅会将 key 和 证书 文件都以正确的权限被复制安装到正确路径,并自动重启应用服务让其立即生效;
同时还会自动将key 和证书的 路径 以及要执行的指令 自动保存到配置文件中,以便后续自动续期证书时自动完成这一系列工作;

相关参数保存在 ~/acme.sh/[你的域名]/[你的域名].conf 配置文件中

查看证书

查看当前已经申请了的证书列表,以及每一个证书的状态信息,使用如下指令

acme.sh --list

查看指定证书的详细信息,使用如下指令

acme.sh --info -d domain.com

更新证书

acme.sh 在安装成功时,就会自动创建一个 crontab 任务,在每天的自动执行一次证书检查工作,
如果发现某一个证书的有效期少于30天,就会自动对该证书进行续期更新操作,完全不需要您进行任何干预(前提是该证书能够自动完成 DNS 或 webroot 验证);

当然可以随时执行如下指令针对某个域名手动进行强制更新

acme.sh --renew -d domain.com --force

高级用法

acme.sh 还支持 notify 、hook 等更多高级用法;
可以实现在证书自动更新或续期成功时自动发送通知,或者是 hook 调用自定义的脚本完成更多关联的操作,可参考官方wiki说明;

总之我认为 acme.sh 这个项目是完美解决了我对于免费SSL证书的申请、自动续期、自动部署等场景所有的需求,并且轻量易用;
个人极力推荐!

Last modification:December 11, 2024
如果觉得我的文章对你有用,请随意赞赏