介绍

acme.sh是一个github开源的域名ssl自动申请脚本,可实现免费ssl证书的自动化申请,续期,替换部署,脚本内置不同ca证书机构以及多种dns解析商api

  • 自该脚本3.0更新后,默认ca机构变成了zerossl,需要去zerossl官网申请一个用户账号后才可以申请证书,若感觉不便也可以按下文切换回之前的Let's Encrypt(无须注册账号,可直接申请ca)
  • 免费证书一般是90天,脚本会自动添加cronjob,并在60天时完成续期替换

1.安装acme.sh

一条命令即可

 curl https://get.acme.sh | sh

若国内服务器无法访问可尝试gitee 克隆后手动安装脚本

 git clone https://gitee.com/neilpang/acme.sh.git
 cd acme.sh
 ./acme.sh --install -m my@example.com

普通用户和 root 用户都可以安装使用. 安装过程进行了以下几步:

  1. 把 acme.sh 安装到你的 home 目录下:
 ~/.acme.sh/

并在.bashrc文件创建了一个 shell 的 alias,方便你的使用: alias acme.sh=~/.acme.sh/acme.sh

  1. 自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.

更高级的安装选项请参考: https://github.com/Neilpang/acme.sh/wiki/How-to-install

安装过程不会污染已有的系统任何功能和文件, 所有的修改都限制在安装目录中: ~/.acme.sh/

安装后若无法使用acme.sh命令,可运行 source ~/.bashrc 重新加载系统环境变量即可

2.不同ca选择

CA指的是证书签发机构,以下是两种常用的免费证书注册商,acme的更多ca选择也可以参考ca列表切换默认ca

ZeroSSL

  • zerossl是acme.sh 3.0版本后内置的默认ca签发机构,需注册账号
  • 先到他的官网注册账号后,到开发者页面最底下创建eab密钥对,该密钥对只会显示一次,请妥善保存

使用

  1. 切换默认ca为 ZeroSSL

     acme.sh --set-default-ca --server letsencrypt
  2. 将自己eab密钥注册到脚本

     acme.sh  --register-account  --server zerossl \
             --eab-kid  你的eab-kid \
             --eab-hmac-key  你的eab-hmac-key

Let's Encrypt

  • 老牌的一个免费证书机构,但申请频率过高可能被暂时限制申请
  • 没有用户注册限制

使用

  1. 切换默认ca为 Let's Encrypt

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

3.申请证书(主要是网站所有权校验)

  • 申请证书时需要校验网站所有权是你本人,一般有两种校验方式,根目录文件校验和域名dns解析验证,选择一种完成校验就能下发证书
  • 如果网站目录较为简单,不涉及路由访问,使用该方式即可
  • 如果网站存在复杂的路由或反代,或不想增加多余文件夹,就使用dns校验,dns校验更是支持多域名以及泛域名解析

网站根目录文件校验

  • 文件校验较为简单,可以签发普通域名,多域名,通配证书则必须要dns校验
  • 文件校验是在网站根目录下创建一个名为 .well-known文件夹,并在里面放置校验文件
  • 脚本命令

     acme.sh  --issue  -d www.mydomain.com -w /home/wwwroot/mydomain.com/
  • 脚本同时也支持nginxapache服务器的配置自动读取,但其实没那么好用,建议还是指定目录

     acme.sh --issue -d mydomain.com --apache
     acme.sh --issue -d mydomain.com --nginx
  • 更高级的用法请参考: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert

dns校验

通过向域名解析商查询一条指定的came记录或txt记录来判断网站所有权,本地不会创建任何校验文件,对网站访问路由没限制

dns手动校验

参考官方文档dns manual mode,需要手动去添加一条came记录或txt记录,该校验方式只能用一次,之后续期还需要手动重新填写,不推荐

dnsapi校验

  • dnsapi则是调用用户在配置项添加的各dns解析平台的密钥,去自动添加一条解析记录,在证书申请完成后,也会自动删除该记录,比较推荐这种
  • dnsapi 具体配置可参考官方文档dns api,国内外近150多个dns服务商都有收录 ,流程基本都是如下操作

    1. 到所在服务商获取子用户密钥
    2. 运行以下命令将dns服务商对应字符串与密钥写入当前shell环境变量(一般是两个字符串,有的服务商可能要求3个或更多),dns密钥字符串名称和dns服务商缩写都可以查看 项目官方文档,以阿里云为例
     export Ali_Key="你的key"
     export Ali_Secret="你的密钥"
    1. 运行以下命令,域名和服务商缩写词需要自行替换,如阿里的dns服务商缩写为dns_ali
     ./acme.sh --issue --dns dns_ali -d mydomain.com

    如果是泛域名则是 ./acme.sh --issue --dns dns服务商缩写词 -d *.mydomain.com

    1. 密钥正确的情况下等待几分钟就能申请成功

dns别名模式

具体步骤参考官方文档dns alias,如果您的 DNS 提供商不支持 API 访问,或者您担心授予 DNS API 访问主域的权限会带来安全问题,那么您可以使用 DNS 别名模式

eg: 如果想为blog.a.com域名申请ssl协议,但该域名所在服务商不支持dns api,可以申请另一个支持dns api的域名,如在腾讯云或阿里云申请一个不重要的域名 b.com,然后进行以下的操作

  1. _acme-challenge.blog.a.com 添加cname解析到 _acme-challenge.blog.b.com

    • _acme-challenge.这个前缀是校验时所使用的子域名,在进行二级域名或一级域名的归属权校验时,都是需要在实际验证域名前加上这个前缀,并验证他的txt内容解析
    • 不过在他添加cname解析后,证书网站在校验blog.a.com归属权,即校验_acme-challenge.blog.a.com 的记录内容时,会转为去查询_acme-challenge.blog.b.com 的txt记录内容
  2. 运行以下命令申请blog.a.com 的证书,--dns 参数为dns服务商的缩写,同时需要设置对应服务商的密钥,具体参考上文dns api校验 部分的密钥设置

     acme.sh --issue -d  blog.a.com --challenge-alias blog.b.com --dns dns_ali
  3. 若需要签发泛域名(*.a.com),需要将ca切换为zerossl,然后主域名的验证域名添加cname,如将_acme-challenge.a.com cname解析到_acme-challenge.b.com, 然后运行以下命令

     acme.sh --issue -d  *.a.com --challenge-alias b.com --dns dns_ali
  4. 等待几分钟后即可签发证书

4.copy证书

签发完毕后证书会保存在 ~/.acme.sh/mydomain.com_ecc目录下,可以进入这个目录下手动替换证书到网站证书目录,但不建议这样做,正确方法是 --install-cert命令并指定证书目录,相应证书会copy到对应位置

 acme.sh --install-cert -d mydomain.com \
 --fullchain-file /usr/local/nginx/conf/ssl/mydomain.com/cert.pem \
 --key-file       /usr/local/nginx/conf/ssl/mydomain.com/privkey.key \
 --reloadcmd     "systemctl force-reload nginx.service"

参数说明

 --fullchain-file   网站ssl  证书文件位置
 --key-file         网站ssl  证书私钥文件位置
 --reloadcmd        复制证书后运行的命令,这里写的是软重载nginx配置,不会影响正在运行的服务,如果是apache则改为`service apache2 force-reload`

--install-cert命令的更多详细参数请参考官方文档

值得注意的是, 这里指定的所有参数都会被自动记录下来, 并在将来证书自动更新以后, 被再次自动调用.

5.部署证书

证书目录及文件名应与nginx或apache内填写的网站证书位置一致,如
 server {
     listen 443;
     #domain修改成你的域名即可
     server_name domain.com www.domain.com; 
 
     ssl on;
     #fullchain证书绝对路径
     ssl_certificate /usr/local/nginx/conf/ssl/mydomain.com/cert.pem;
     #privkey证书私钥绝对路径
     ssl_certificate_key /usr/local/nginx/conf/ssl/mydomain.com/privkey.key;
     ssl_session_timeout 5m;
     ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
     ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
     ssl_prefer_server_ciphers on;
 
 }

6.更新证书

acme.sh脚本在安装时就已经创建了cronjob,证书在 60 天以后会自动更新,你可以通过 crontab -l命令查看当前定时任务,有一行acme.sh创建的定时任务就行了,像是这样

 56 * * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

7.更新 acme.sh

目前由于 acme 协议和 letsencrypt CA 都在频繁的更新, 因此 acme.sh 也经常更新以保持同步.

升级 acme.sh 到最新版 :

 acme.sh --upgrade

如果你不想手动升级, 可以开启自动升级:

 acme.sh --upgrade --auto-upgrade

之后, acme.sh 就会自动保持更新了.

你也可以随时关闭自动更新:

 acme.sh --upgrade --auto-upgrade  0

其实一般也不需要更新,自己几年前下载的脚本一直自动申请Let's Encrypt证书,到现在也没出问题

最后修改:2024 年 06 月 07 日
如果觉得我的文章对你有用,请随意打赏