在当今互联网环境中,HTTPS 已成为保障网站安全和用户数据隐私的标配。然而,申请和管理 SSL/TLS 证书往往让人头疼,尤其是手动更新证书,稍不注意就会导致证书过期,影响网站访问。幸运的是,acme.sh 这款强大且开源的 ACME 协议客户端工具,能让 HTTPS 证书的申请与更新变得轻松自动化。接下来,我们就一步步深入了解如何使用 acme.sh 实现 HTTPS 证书的自动申请与更新,并且详细介绍每个命令的使用。
安装 acme.sh
github安装
使用github脚本安装的前提是服务器的网络得能正常访问github,如果有梯子是没问题的。
# 以下 curl 或者 wget 二选一执行即可,主要看服务器上安装了哪种请求工具,邮箱主要的作用是接收证书过期提醒
curl https://get.acme.sh | sh -s email=844826411@qq.com
wget -O - https://get.acme.sh | sh -s email=844826411@qq.com
# 使用命令查看版本以此验证是否安装成功,如果提示 acme.sh: command not found,可重新登录或者重新激活一下用户环境 source ~/.bashrc再试
acme.sh -v
gitee源码安装
无法访问github的替代方案,安装后发现版本号没有github方式安装的版本号新,明显未同步github的最新代码
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m 844826411@qq.com
生成证书
acme.sh 实现了 acme 协议支持的所有验证协议。一般有两种方式验证: HTTP 和 DNS 验证。
HTTP 验证
直接签发
只需要指定域名,并指定域名所在的网站根目录. acme.sh 会全自动的生成验证文件,并放到网站的根目录,验证完成后会聪明的删除验证文件,整个过程没有任何副作用。
acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /home/wwwroot/mydomain.com/
使用 Apache 模式
如果你用的 Apache 服务器,acme.sh 还可以智能的从 Apache 的配置中自动完成验证,你不需要指定网站根目录:
acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com
使用 Nginx 模式
如果你用的 Nginx 服务器,或者反代,acme.sh 还可以智能的从 Nginx 的配置中自动完成验证,你不需要指定网站根目录:
acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com
我用的就是nginx,所以采用的就是此方法,
使用独立服务模式
如果服务器上没有运行任何 Web 服务,80 端口是空闲的,那么 acme.sh 还能假装自己是一个 WebServer,临时监听 80 端口,完成验证:
acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com
修改默认 CA
acme.sh 脚本默认 CA 服务器是 ZeroSSL
,有时可能会导致获取证书的时候一直出现:Pending,The CA is processing your order,please just wait.
只需要把 CA 服务器改成 Let's Encrypt
即可,虽然更改以后还是有概率出现 pending,但基本 2-3 次即可成功
acme.sh --set-default-ca --server letsencrypt
CA服务器厂商了解到的有:
更高级的用法请参考: https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
DNS 验证
如果你没有服务器,没有公网 IP,只需要 DNS 的解析记录即可完成验证。
手动验证
这需要你手动在域名上添加一条 TXT 解析记录,验证域名所有权。
注意,如果使用手动验证,acme.sh 将无法自动更新证书,每次都需要手动添加解析来验证域名所有权。如果有自动更新证书的需求,请使用自动验证(DNS API)。
acme.sh --issue -d mydomain.com --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please
然后,acme.sh 会生成相应的解析记录显示出来,你只需要在你的域名管理面板中添加这条 TXT 记录即可。
等待解析完成之后(可能会有延迟没有马上生效),执行以下命令重新生成证书:
acme.sh --renew -d mydomain.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
自动验证(DNS API)
DNS 方式的真正强大之处在于可以使用域名解析商提供的 API 自动添加 TXT 记录,且在完成验证后删除对应的记录。
acme.sh 目前支持超过一百家的 DNS API,这里只作了解就不演示了。
以 DNSPod.cn 为例,你需要先登录到 DNSPod.cn,拿到你的 DNSPod API Key 和 ID 并设置:
export DP_Id="1234"
export DP_Key="sADDsdasdgdsf"
现在我们可以签发通配符证书了:
acme.sh --issue --dns dns_dp -d example.com -d *.example.com
DP_Id
和 DP_Key
将保存在 ~/.acme.sh/account.conf
中,并在需要时自动获取,无需手动再设置。
更详细的 DNS API 用法: https://github.com/acmesh-official/acme.sh/wiki/dnsapi
复制证书
证书生成好以后,我们需要把证书复制给对应的 Apache、Nginx 或其他服务器去使用。
必须使用 --install-cert
命令来把证书复制到目标文件,请勿直接使用 ~/.acme.sh/
目录下的证书文件,这里面的文件都是内部使用,而且目录结构将来可能会变化。
Apache 示例
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"
Nginx 示例
acme.sh --install-cert -d example.com \
--key-file /path/to/keyfile/nginx/key.pem \
--fullchain-file /path/to/keyfile/nginx/cert.pem \
--reloadcmd "nginx -s reload" # 这里因nginx安装的方式而不同,由于我是通过源码安装的,所以直接用的是nginx命令,包管理器安装的可能是 "service nginx reload" 或 "systemctl restart nginx"
Nginx 的配置项 ssl_certificate
需要使用 /etc/nginx/ssl/fullchain.cer
,而非 /etc/nginx/ssl/<domain>.cer
,否则 SSL Labs 的测试会报证书链问题(Chain issues Incomplete
)。
默认情况下,证书每 60 天更新一次(可自定义)。更新证书后,Apache 或者 Nginx 服务会通过 reloadcmd
传递的命令自动重载配置。
注意:reloadcmd
非常重要。证书会自动申请续签,但是如果没有正确的 reloadcmd
命令,证书可能无法被重新应用到 Apache 或者 Nginx,因为配置没有被重载。
转换为p12证书
虽然acme.sh生成的证书可以直接配置到Nginx、Apache等等Web服务器使用,不过有少数时候如果说想直接配置证书到Tomcat中(Spring Boot)那就需要将证书转换成p12格式了!
生成证书后,将证书文件和证书密钥文件复制出来,通过openssl命令转换:
openssl pkcs12 -export -in "证书文件路径" -inkey "证书密钥文件路径" -out "指定生成的p12证书文件路径"
执行命令会让你设定p12证书的密码,自行设定即可。
然后在Spring Boot配置文件配置如下:
# SSL证书设置
server.ssl.key-store=证书jks文件所在位置
server.ssl.key-store-password=证书密码
server.ssl.keyStoreType=PKCS12
server.ssl.key-store配置项需要以classpath:或者file:开头,一般classpath:开头的表示jar包内路径,Maven项目中src\main\resources文件夹即可对应为 classpath 的根目录,而 file: 对应的是jar包外相对路径或者绝对路径。
# classpath路径
server.ssl.key-store=classpath:ssl.p12
# jar包外路径
server.ssl.key-store=file:ssl/ssl.p12
查看已安装证书信息
acme.sh --list # 查看申请的证书域名列表
acme.sh --info -d example.com # 查看指定域名信息
续期证书
目前证书每 60 天自动更新,你无需任何操作。但是你也可以强制续签证书:
acme.sh --renew -d example.com --force # 强制续期
acme.sh --renew-all # 一键全部续期
吊销和移除证书
如果证书不需要了,我们可以将其吊销,需要注意的是:吊销不是删除证书就行了
首先通过下列命令吊销证书:
acme.sh --revoke -d example.com
出现 Revoke success 说明吊销成功。
不过现在证书文件还残留在服务器上,通过下列命令移除:
acme.sh --remove -d example.com
其它用法
关于修改 reloadcmd
目前修改 reloadcmd
没有专门的命令,可以通过重新安装证书来实现修改 reloadcmd
的目的。
此外,安装证书后,相关信息是保存在 ~/.acme.sh/example.com/example.conf
文件下的,内容就是 acme.sh --info -d example.com
输出的信息,不过 reloadcmd
在文件中使用了 Base64 编码。理论上可以通过直接修改该文件来修改 ReloadCmd
,且修改时,无需 Base64 编码,直接写命令原文 acme.sh
也可以识别。
不过,由于 example.conf
文件的位置和内容格式以后可能会改变,且 example.conf
一直都是内部使用,后续也有可能会改为用 SQLite 或者 MySQL 格式存储. 所以一般不建议自己修改。
更新 acme.sh
acme.sh 还在不断开发中,因此强烈建议保持并使用最新的版本。看代码最近一次提交已经是三年前了,升级应该是无望了~_~!
升级 acme.sh 到最新版:
acme.sh --upgrade
如果你不想手动升级,可以开启自动升级:
acme.sh --upgrade --auto-upgrade
之后,acme.sh 就会自动保持更新了。
你也可以随时关闭自动更新:
acme.sh --upgrade --auto-upgrade 0
出错调试
如果出错,请添加 --debug
参数输出详细的调试信息:
acme.sh --issue ..... --debug
或者输出更详细的信息:
acme.sh --issue ..... --debug 2
请参考:https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh
在 DNS 验证模式下如果 debug 中出现诸如 timed out
等字样可能是因为 GFW
HTTP(S) Proxy 环境变量。(请按照自己实际设定修改)
export http_proxy="socks5h://localhost:1081"
export https_proxy="socks5h://localhost:1081"
查看帮助
acme.sh -h