这篇文章主要介绍acme.sh,一个开源的ACME协议客户端,用于自动化申请、更新和部署SSL/TLS证书。文章详细讲解了如何安装、配置、选择默认CA、使用DNS API部署、申请证书、验证安全等级以及自动化签发和部署的过程。 简介 acme.sh是一个开源的ACME协议的客户端工具,用于自动化申请、更新和部署 SSL/TLS 证书。通过使用acme.sh,用户可以轻松地在服务器上设置 HTTPS 加密连接,而无需手动操作。它支持多种DNS接口和证书颁发机构,可以与各种 Web 服务器和DNS服务集成,提供了方便的命令行工具和丰富的功能选项。目前acme.sh支持 5 个正式环境 CA,分别是 Let’s Encrypt、Buypass、ZeroSSL、SSL.com 和 Google Public CA,默认使用 ZeroSSL。 acme.sh官网地址链接: https://acme.sh 或 https://github.com/acmesh-official/acme.sh 官网中文说明书:https://github.com/acmesh-official/acme.sh/wiki/说明 配置安装 使用源码安装(默认安装到当前用户目录下的.acme.sh目录下,建议通过sudo su后通过root用户安装):
sudo su
curl https://get.acme.sh | sh -s email=myemail@example.com
请注意替换 myemail@example.com 为你自己的邮箱,避免无法收到上游证书的邮件通知。 安装完成后创建 一个 shell 的 alias:
alias acme.sh=~/.acme.sh/acme.sh
#执行一个acme.sh的help命令
acme.sh -h
#输入上面的命令后显示下列信息说明安装配置成功了
https://github.com/acmesh-official/acme.sh
v3.0.8
Usage: acme.sh <command> ... [parameters ...]
Commands:
-h, --help Show this help message.
-v, --version Show version info.
--install Install acme.sh to your system.
--uninstall Uninstall acme.sh, and uninstall the cron job.
--upgrade Upgrade acme.sh to the latest code from https://github.com/acmesh-official/acme.sh.
--issue Issue a cert.
--deploy Deploy the cert
开启或者关闭自动更新:
#开启自动更新
acme.sh --upgrade --auto-upgrade
#关闭自动更新
acme.sh --upgrade --auto-upgrade 0
全局切换,选择默认 CA ,更多CA参数说明详见:https://github.com/acmesh-official/acme.sh/wiki/Server,目前 acme.sh 支持 5 个正式环境 CA,分别是 Let’s Encrypt、Buypass、ZeroSSL、SSL.com 和 Google Public CA,默认使用 ZeroSSL,如果需要更换可以使用如下命令:
#切换 Let’s Encrypt:
acme.sh --set-default-ca --server letsencrypt
#切换 Buypass:
acme.sh --set-default-ca --server buypass
#切换 ZeroSSL:
acme.sh --set-default-ca --server zerossl
#切换 SSL.com:
acme.sh --set-default-ca --server ssl.com
#切换 Google Public CA:
acme.sh --set-default-ca --server google
本文下面将针ZeroSSL进行举例说明,若需要使用其他的CA,可以访问官网相关说明文件。针对ZeroSSL 分别通过DNS API、手动DNS、http等三种方式验证域名所有权。
ZeroSSL CA证书签发 首先请登录ZeroSSL官网(没有账号就先注册一个,注册很简单,输入邮箱地址和密码即可)进入后台控制面板,点击左侧的【Developer】菜单,即可看到你当前账号的ZeroSSL API Key,也可以点击【RESET KEY】按钮重新生产一个ZeroSSL API Key,执行如下命令通过 API Key 获取 eab-kid 和 eab-hmac-key。
![](../../staticfiles/images/2024/240710123745.png)
curl -s -X POST "https://api.zerossl.com/acme/eab-credentials?access_key=97c3*************************2afbf"
#返回如下信息:
{
"success": true,
"eab_kid": "xxxxkid字符串xxxx", //"kid字符串",
"eab_hmac_key": "xxxxxxhmac_key字符串xxxx", //"hmac_key字符串",
}
然后手动添加帐号:
acme.sh --register-account --server zerossl --eab-kid xxxxkid字符串xxxx --eab-hmac-key xxxxxxhmac_key字符串xxxx
#返回如下信息:
Create account key ok.
Registering account: https://acme.zerossl.com/v2/DV90
Registered
ACCOUNT_THUMBPRINT='c**********************************************f'
1、通过自动DNS API签发证书 通过使用域名服务商提供的 API 密钥,让acme.sh自动创建域名验证记录以申请域名证书。acme.sh 支持全球主流域名服务商的API,本文将以阿里云为例(需要你要签发证书的域名解析服务在阿里云)。更多 DNS API 支持,请查看官网支持文档:https://github.com/acmesh-official/acme.sh/wiki/dnsapi 登陆阿里云控制台 - 访问控制 RAM - 身份管理-用户-创建一个新用户-输入登录名称,勾选访问方式为“OpenAPI 调用访问”,确定创建。
![](../../staticfiles/images/2024/240710123959.png) 复制保存好生成的AccessKey信息(AccessKey ID、AccessKey Secret),返回用户列表,点击刚创建的用户,进入【权限管理】--【新增授权】,搜索DNS,勾选策略名称为“AliyunDNSFullAccess”(描述为:管理云解析(DNS)的权限)的策略,确认新增授权。
![](../../staticfiles/images/2024/240710123836.png) 下面通过设置环境变量为 acme.sh 提供全局 API 密钥,使用阿里云的API密钥设置如下:
#将前面提取的AccessKey ID、AccessKey Secret分别赋值给环境变量Ali_Key、Ali_Secret
export Ali_Key="TL***************X"
export Ali_Secret="k1****************************23"
如果使用的腾讯云的域名解析,则可以通过腾讯云控制台https://console.cloud.tencent.com/cam获取对应的API密钥,操作步骤和阿里云类似在此就不赘述了,拿到腾讯云API 密钥后如下设置环境变量。
export Tencent_SecretId="AKID**************************************w28s"
export Tencent_SecretKey="Ww9*********************************2iF"
下面就可以开始给你的域名分配证书了。
#输入下面的命令开始签发证书,下面命令为纯域名example.com和其泛域名生成一张证书,泛域名证书不包含纯域名。
acme.sh --issue --dns dns_ali -d example.com -d *.example.com
#若使用腾讯云API,需要将--dns参数dns_ali改为dns_tencent,cloudflare的--dns参数为dns_cf,dnspod.cn的--dns参数为dns_dp(与腾讯云为一家但是接口不一样)
acme.sh --issue --dns dns_tencent -d example.com -d *.example.com
#系统会打印很多信息,最后生成的证书信息如下:
Your cert is in: /root/.acme.sh/example.com_ecc/example.com.cer
Your cert key is in: /root/.acme.sh/example.com_ecc/example.com.key
The intermediate CA cert is in: /root/.acme.sh/example.com_ecc/ca.cer
And the full chain certs is there: /root/.acme.sh/example.com_ecc/fullchain.cer
##如果你的站点域名比较多,你可以通过增加-d来实现将你的所有域名生成一张证书
acme.sh --issue --dns dns_ali -d example.com -d *.example.com -d example.com.cn -d *.example.com.cn -d example.cn -d *.example.cn
然后安装证书,将证书复制到nginx的证书目录下,并重启nginx
#nginx的http.conf中的https站点配置如下:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
#开启Quic或HTTP/3支持,注意:reuseport只能配置一个其他的启用quic即可。
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
#若无此行,HTTP3无法生效,其他server只用加这一行,不需要listen 443 quic reuseport;
add_header Alt-Svc 'h3=":443";ma=86400,quic=":443"; ma=2592000; v="46,43"';
#默认SSL配置,未配置server_name的也可以访问到的,多域名在共享一个证书
server_name example.com *.example.com example.com.cn *.example.com.cn example.cn *.example.cn
charset utf-8;
ssl_protocols TLSv1.3 TLSv1.2;
#控制在发送数据时的 buffer 大小,默认设置是 16k。这个值越小,则延迟越小,而添加的报头之类会使 overhead 会变大,反之则延迟越大,overhead 越小。
ssl_buffer_size 4k;
##设置ssl session缓存(10m是指缓存大小10兆)
ssl_session_cache shared:SSL:10m;
##设置长连接缓存过期时间 30m 4h
ssl_session_timeout 30m;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;
#HTTP Strict Transport Security(通常简称为 HSTS)是一个安全功能,它告诉浏览器只能通过 HTTPS 访问当前资源,而不是 HTTP。
add_header Strict-Transport-Security "max-age=31536000";
location / {
root /usr/local/nginx/html;
index index.shtml index.html index.htm;
}
#SSL 证书位置配置
ssl_certificate /usr/local/ssl/example.com/fullchain.cer;
ssl_certificate_key /usr/local/ssl/example.com/example.com.key;
}
#安装证书到指定目录,并重启nginx
acme.sh --install-cert -d 'example.com' \
--key-file /usr/local/ssl/example.com/example.com.key \
--fullchain-file /usr/local/ssl/example.com/fullchain.cer \
--reloadcmd "nginx -s reload"
#注意:/usr/local/ssl/example.com/为你web服务中ssl证书存放的位置
#--reloadcmd "nginx -s reload"为重启nginx,也可以改成nginx服务或者其他需要执行的命令
acme.sh常用的命令说明如下:
#从ZeroSSL平台注销证书
acme.sh --revoke -d example.com
#删除本机生成的证书
acme.sh --remove -d example.com
#如果签发证书出错, 请添加 debug log:
acme.sh --issue ..... --debug
#或者
acme.sh --issue ..... --debug 2
#acme.sh其他参数如下
--issue 颁发证书
--renew 更新证书
--renew-all 更新所有证书
--list 获取所有证书的信息,形成一个列表
目前证书在60天以后会自动更新,你无需任何操作。今后有可能会缩短这个时间,不过都是自动的,你不用关心。请确保 cronjob 正确安装, 看起来是类似这样的:
crontab -l
#显示信息如下:
56 * * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
2、通过手动DNS方式签发证书 手动DNS方式签发证书,需手动在域名上添加一条 txt 解析记录,验证域名所有权。 这种方式的好处是,你不需要任何服务器,不需要任何公网ip,只需要 dns 的解析记录即可完成验证。坏处是,如果不同时配置自动DNS API,使用这种方式 acme.sh 将无法自动更新证书,每次都需要手动再次重新解析验证域名所有权。
acme.sh --issue --dns -d mydomain.com \
--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
#注意第二次这里用的是 --renew
3、通过HTTP方式签发证书 http方式需要在你的网站根目录下放置一个文件,来验证你的域名所有权,完成验证。然后就可以生成证书了。
acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /usr/local/nginx/html/
只需要指定域名,并指定域名所在的网站根目录。acme.sh会全自动的生成验证文件,并放到网站的根目录,然后自动完成验证。最后会聪明的删除验证文件。整个过程没有任何副作用。 如果你用的apache服务器,acme.sh还可以智能的从apache的配置中自动完成验证,你不需要指定网站根目录:
acme.sh --issue -d mydomain.com --apache
如果你用的nginx服务器,或者反代,acme.sh还可以智能的从nginx的配置中自动完成验证,你不需要指定网站根目录:
acme.sh --issue -d mydomain.com --nginx
注意,无论是apache还是nginx模式,acme.sh在完成验证之后,会恢复到之前的状态,都不会私自更改你本身的配置。好处是你不用担心配置被搞坏,也有一个缺点,你需要自己配置ssl的配置,否则只能成功生成证书,你的网站还是无法访问https。但是为了安全,你还是自己手动改配置吧。 如果你还没有运行任何web服务,80端口是空闲的,那么acme.sh还能假装自己是一个webserver,临时听在80端口,完成验证:
acme.sh --issue -d mydomain.com --standalone
acme.sh脚本默认CA服务器是zerossl,若出错,会导致获取证书的时候一直出现:Pending,The CA is processing your order,please just wait。 只需要把ca服务器改成letsencrypt即可,虽然更改以后还是有概率出现pending,但基本2-3次即可成功
acme.sh --set-default-ca --server letsencrypt
HTTPS站点部署完成后,可以通过 https://www.ssllabs.com/ssltest/ 网站进行证书安全等级验证,本站的验证效果如下:
![](../../staticfiles/images/2024/240710134115.png)
|