如何使用acme.sh从CA生成免费证书并实现自动续签
现在SSL证书的有效期基本在一年左右,而免费的SSL证书的有效期只有90天,对于运维人员来说就需要每年甚至每季度更新一次证书。在今年10月10日苹果公司更是提出将SSL证书有效期缩短为45天的标准提案,试想一下,如果真的缩短到45天,那运维人员岂不是一个半月就要更新一次…那就只剩下自动化这条路了。
现在全球领先的云服务提供商都已经全部支持ACME自动化配置SSL证书,acme.sh项目就实现了ACME协议,通过它就可以从ZeroSSL,Let’s Encrypt等CA生成免费的证书并自动续签
- GitHub项目地址:https://github.com/acmesh-official/acme.sh
- 中文说明:https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E
- 中国大陆用户安装参考:https://github.com/acmesh-official/acme.sh/wiki/Install-in-China
安装acme.sh
安装很简单,就一条命令
1 | curl https://get.acme.sh | sh -s email=my@email.com && source ~/.bashrc |
说明
my@email.com替换为你自己真实的邮箱地址
如果要安装acme.sh的服务器位于中国大陆, 可能会无法访问GitHub导致安装失败,因此,对于中国大陆用户推荐从https://gitee.com/neilpang/acme.sh下载安装,具体安装命令为
1 | git clone https://gitee.com/neilpang/acme.sh.git |
安装脚本会将acme.sh安装到~/.acme.sh目录中,同时自动创建crontab计划任务,在每天00:XX(XX是随机的)自动检测所有的证书,如果快到期了,则自动续期并更新证书
生成证书
acme.sh实现了ACME协议支持的所有验证方式(HTTP/DNS/TLS-SNI/EXTERNAL-ACCOUNT),最常用的有HTTP和DNS两种方式。
说明
- HTTP验证:需要在网站根目录下放置一个文件,来验证对域名的所有权,然后才可以生成证书。(需要公网IP和开放相应端口)
- DNS验证:需要手动或通过域名服务商提供的API自动在域名上添加一条txt解析记录,验证域名所有权。
- 本文采用的是不需要公网IP的DNS验证
DNS验证的真正强大之处在于可以使用域名解析商提供的API自动添加TXT记录,且在完成验证后删除对应的记录。acme.sh目前支持超过一百家的DNS API,详情可以查看acme.sh官方文档,本文以阿里云为例。
获取域名服务商的Key和Secret信息
首先,登录你的阿里云账号(https://ram.console.aliyun.com/users)获取用于访问资源的RAM(Resource Access Management) API密钥,并添加DNS相关的权限策略,具体操作可参考以下阿里云官方文档
说明
RAM API密钥是用于身份验证和授权的重要凭证,确保用户能够安全地访问和管理其云资源,请妥善保管
然后执行以下命令配置AccessKey ID和AccessKey Secret
1 | export Ali_Key="<AccessKey ID>" |
说明
Ali_Key和Ali_Secret将会被保存在~/.acme.sh/account.conf文件中。当未来再次需要使用时,系统会自动从这个文件中读取,无需用户再次输入。
DNS自动验证签发证书
说明
DNS手动验证需要手动在域名上添加一条TXT解析记录,验证域名所有权,这种方式将无法自动更新证书,所以建议使用DNS自动验证(DNS API)
以我的域名为例,一级域名为koenli.com,二级域名为www.koenli.com,签发证书的命令如下:
1 | # acme.sh --issue --dns dns_ali -d <一级域名> -d <二级域名1> -d <二级域名2> |
配置证书到Nginx/Apache或者其他服务
证书生成好以后,我们需要把证书复制给对应的Nginx、Apache或其他WEB服务去使用。
说明
必须使用--install-cert命令来把证书复制到目标文件,请勿直接使用~/.acme.sh/目录下的证书文件,这里面的文件都是内部使用,而且目录结构将来可能会变化。
配置到Nginx
1 | acme.sh --install-cert -d example.com \ |
说明
更新证书后,acme.sh会通过reloadcmd传递的命令自动重新加载WEB服务的配置,因此请确认传递的reloadcmd命令准确无误。
配置到Apache
1 | acme.sh --install-cert -d example.com \ |
说明
更新证书后,acme.sh会通过reloadcmd传递的命令自动重新加载WEB服务的配置,因此请确认传递的reloadcmd命令准确无误。
配置到雷池WAF
说明
因为我配置了雷池WAF,证书需要配置在雷池上,配置步骤会有所区别。
在证书签发完成后,通过绿色字体部分获取证书存放路径

将证书中的fullchain.cer文件和域名.key文件拉取到本地,登录雷池,选择“防护站点”-“证书管理”-“添加证书”-“上传已有证书”,将证书文件上传到雷池

在“防护站点”-“站点管理”-对应站点右侧“...”-“编辑”中,配置站点证书为上一步上传的证书

在服务器上执行以下命令在雷池的站点配置文件中(雷池默认的安装路径为/data/safeline)查找对应域名的证书存放路径和文件名
1 | # cat /data/safeline/resources/nginx/sites-enabled/* | grep -C 4 <雷池上配置的站点域名> |
输出类似如下,表示cert文件的文件名为cert_119.crt,key文件的文件名为cert_119.key
1 | ... |
最后执行以下命令配置证书到雷池的证书存放路径
说明
雷池WAF为容器部署,所以站点配置文件中看到的存放路径为在容器中对应的路径,实际对应到宿主机上的路径为/data/safeline/resources/nginx/certs/
1 | acme.sh --install-cert -d koenli.com -d www.koenli.com --key-file /data/safeline/resources/nginx/certs/cert_119.key --fullchain-file /data/safeline/resources/nginx/certs/cert_119.crt --reloadcmd "docker exec safeline-tengine nginx -s reload" |
说明
更新证书后,acme.sh会通过reloadcmd传递的命令自动重新加载WEB服务的配置,因此请确认传递的reloadcmd命令准确无误。
查看已安装证书信息
1 | # acme.sh --info -d <一级域名> |
输出如下:
1 | DOMAIN_CONF=/root/.acme.sh/koenli.com/koenli.com.conf |
更新证书
目前证书每60天自动更新,你无需任何操作。但是也可以执行以下命令强制续签证书
1 | # acme.sh --renew -d <一级域名> --force |
常见问题
安装acme.sh时出现以下警告信息
1 | [Fri Dec 27 15:22:22 CST 2024] It is recommended to install socat first. |
从信息中可以看出是建议我们安装socat,那就听从官方建议装上即可
1 | yum install socat -y |