https://letsencrypt.org 支持免费的https证书。但是有效期只有三个月,因此要定时更新。
现在也支持 泛域名证书(如*.example.com
),无需为每个域名单独签发证书。
生成证书和更新证书要使用客户端工具,官方推荐是 cerbot-auto 但是感觉 acme.sh 更好用。因此本文只介绍后者。
这两个客户端工具都是通过ACME协议与证书颁发机构通信来管理https证书。
CA 即 Certificate Authority 证书签发机构
ACME protocol 即 Automatic Certificate Management Environment 自动证书管理环境。是证书颁发机构和用户服务器之间的自主交互的通信协议。
acme 的使用
https证书使用大致分如下几步
- 获取客户端工具
- 签发证书
- 配置nginx的https
- 配置自动更新
Step1. 获取客户端工具
1.直接安装(推荐)
默认安装到 /root/.acme.sh/
1 | curl https://get.acme.sh | sh |
2.使用docker
参考:https://github.com/Neilpang/acme.sh/wiki/Run-acme.sh-in-docker
1 | docker run --rm neilpang/acme.sh |
两种方式都是为了获取acme.sh脚本。因此直接安装的使用方式是
1 | /path/to/acme.sh --arg1 --arg2 |
dcoker的使用方式是
1 | docker run --rm -it -v "$(pwd)/out":/acme.sh --net=host neilpang/acme.sh \ |
我觉得也可以将对docker的操作封指定别名操作更方便,但是没有试过。 如:
1 | alias acme-docker='docker run --rm -it -v "$(pwd)/out":/acme.sh --net=host neilpang/acme.sh' |
Step2. 签发证书(issue操作)
签发证书有多种方式,其目的是为了证明对域名的拥有权。仅介绍两种最方便的:
- 通过添加一条
txt
类型的域名解析 - 通过在网站根目录放置文件
方法1.txt类型域名解析(支持泛域名的唯一方式)
该方法分自动(推荐)和手动。自动方式需要域名商提供API,配置Key和Secret即可支持自动签发和更新证书。
以阿里云域名解析为示例,自动操作如下:
1 | #在shell中设置变量 |
所有支持的DNS服务商:https://github.com/Neilpang/acme.sh/wiki/dnsapi
注意事项:通配符/泛域名解析,需要同时指定根域名和泛域名,如:-d 'example.com' -d '*.example.com'
手动操作流程如下:
- 先执行一下签发(
issue
)操作。这一步会失败,但只是为了获取需要做解析的txt文本 - 做
txt
类型的域名解析,需要解析的子域名和值都会在执行上个操作后高亮显示出来。 - 等解析成功后,重新生成证书(
renew
)
1 | #1.先执行签发 获取需要做解析的txt文本 |
注意事项:手动签发便于测试,但不建议用在生产环境。因为每次证书更新都必须手动重新签发(issue) 更新txt域名解析,生成(renew)
手动配置的txt类型解析,在证书生成后可以手动删掉
方法2.指定网站根目录(不支持泛域名)
该方法不支持泛域名,但是支持自动更新。其更新原理也是在 root 账户的 crontab 脚本添加定时任务。
颁发证书(issue操作)
1 | /root/.acme.sh/acme.sh --issue -d 'example.com' -d 'www.example.com' \ |
Step3. 配置nginx
证书签发后会告诉我们生成证书的路径
1 | [Sat May 15 18:22:40 CST 2021] Your cert is in /root/.acme.sh/example.com/example.com.cer |
但是这个非常不建议直接用,因为这是acme自己内部用的。而且它提供了一个用于安装到指定路径的命令,该命令还要指定用于 Reload
的命令,用于证书自动更新的时候重新加载证书。
所以我们先确定路径,并配置到nginx中
- 证书文件:/data/https-cert/example.com/fullchain.cer
- 私钥文件:/data/https-cert/example.com/example.key
- 证书颁发机构的证书 /data/https-cert/example.com/ca.cer,如果不启用 OCSP,可以不配(nginx 默认关闭)。
1 | # domain自行替换成自己的域名 |
如果既要https又要http
1 | server { |
如果要http跳转到https
1 | server{ |
然后可以将证书复制到指定位置并 reload 服务器
1 | acme.sh --installcert -d 'example.com' -d 'www.example.com' \ |
Step4. 自动更新证书
对于通过自动DNS解析和网站根目录放置文件的方式,acme.sh
支持自动更新,无需任何操作。首次执行的时候其会记录相关配置,如域名、 App_key、App_Secret等。然后在root账户下生成一个定时任务。
1 | [root@localhost /]# crontab -l |
可以看出每天0点4分执行一次。
此外,当证书更新后要重启nginx,reload的指令在 /root/.acme.sh/example.com/example.com.conf
1 | Le_ReloadCmd='__ACME_BASE64__START_L3Vzci9sb2NhbC9uZ2lueC9zYmluL25naW54IC1zIHJlbG9hZA==__ACME_BASE64__END_' |
这个行命令是经过 base64转码的,比如我这里转码后是 L3Vzci9sb2NhbC9uZ2lueC9zYmluL25naW54IC1zIHJlbG9hZA==
解码后是:/usr/local/nginx/sbin/nginx -s reload
而手动DNS解析的方式,临近到期前需要手动重新走一遍签发、更新TXT解析、更新证书的流程