介绍
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 用户都可以安装使用. 安装过程进行了以下几步:
- 把 acme.sh 安装到你的 home 目录下:
~/.acme.sh/
并在.bashrc文件创建了一个 shell 的 alias,方便你的使用: alias acme.sh=~/.acme.sh/acme.sh
- 自动为你创建 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
使用
切换默认ca为 ZeroSSL
acme.sh --set-default-ca --server letsencrypt
将自己eab密钥注册到脚本
acme.sh --register-account --server zerossl \ --eab-kid 你的eab-kid \ --eab-hmac-key 你的eab-hmac-key
Let's Encrypt
- 老牌的一个免费证书机构,但申请频率过高可能被暂时限制申请
- 没有用户注册限制
使用
切换默认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/
脚本同时也支持nginx与apache服务器的配置自动读取,但其实没那么好用,建议还是指定目录
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服务商都有收录 ,流程基本都是如下操作- 到所在服务商获取子用户密钥
- 运行以下命令将dns服务商对应字符串与密钥写入当前shell环境变量(一般是两个字符串,有的服务商可能要求3个或更多),dns密钥字符串名称和dns服务商缩写都可以查看 项目官方文档,以阿里云为例
export Ali_Key="你的key" export Ali_Secret="你的密钥"
- 运行以下命令,域名和服务商缩写词需要自行替换,如阿里的dns服务商缩写为dns_ali
./acme.sh --issue --dns dns_ali -d mydomain.com
如果是泛域名则是
./acme.sh --issue --dns dns服务商缩写词 -d *.mydomain.com
- 密钥正确的情况下等待几分钟就能申请成功
dns别名模式
具体步骤参考官方文档dns alias,如果您的 DNS 提供商不支持 API 访问,或者您担心授予 DNS API 访问主域的权限会带来安全问题,那么您可以使用 DNS 别名模式
eg: 如果想为blog.a.com
域名申请ssl协议,但该域名所在服务商不支持dns api,可以申请另一个支持dns api的域名,如在腾讯云或阿里云申请一个不重要的域名 b.com
,然后进行以下的操作
将
_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记录内容
运行以下命令申请
blog.a.com
的证书,--dns 参数为dns服务商的缩写,同时需要设置对应服务商的密钥,具体参考上文dns api校验 部分的密钥设置acme.sh --issue -d blog.a.com --challenge-alias blog.b.com --dns dns_ali
若需要签发泛域名(
*.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.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证书,到现在也没出问题