[版权声明] 本站内容采用 知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆 (CC BY-NC-SA 3.0 CN) 进行许可。
部分内容和资源来自网络,纯学习研究使用。如有侵犯您的权益,请及时联系我,我将尽快处理。
如转载请注明来自: Broly的博客,本文链接: Let’s Encrypt通配符证书的申请与自动更新(附阿里云域名的HOOK脚本)
相信能找到这篇文章的同学也应该对Let’s Encrypt有一定的了解,废话不多说,让我们开始正文:
一、准备工作
首先确保自己有域名的增、删权限,这是个必要条件。
本人测试环境:CentOS 7.x
Let’s Encrypt的证书需要用到官方工具certbot,安装很简单:
1 2 |
yum install certbot -y certbot --version // certbot 0.26.1 |
目前测试用的是最新版本0.26.1。尽量使用最新版本的,以前刚推出通配符域名时是0.22.x版本,有些地方有bug,比如--dry-run命令跟--server会有冲突。
二、理解验证的流程(重要)
申请证书必须要经过验证才能生效,一般验证的方法有几种,官方文档都有介绍:《Getting certificates (and choosing plugins)》
验证非通配符域名,也就是普通单域名时,一般选择常用方法是webroot,也就是可以往网站的根目录放验证文件进行验证(类似微信公众号开发),比较简单易用。或者是使用standalone方法,开启一个应用服务器验证(可能会跟Apache、NGINX有冲突)。
但是通配符域名验证,只能用DNS plugins的方式
This category of plugins automates obtaining a certificate bymodifying DNS records to prove you have control over adomain. Doing domain validation in this way isthe only way to obtain wildcard certificates from Let’sEncrypt.
来看看申请通配符证书的命令行:
1 2 3 4 5 6 7 8 |
certbot certonly \ --email your-email@example.com \ --agree-tos \ --preferred-challenges dns \ --server https://acme-v02.api.letsencrypt.org/directory \ --manual \ -d yourdomain.com \ -d *.yourdomain.com |
我们来拆解下命令行的意思,
certonly 获取或更新证书,但是不安装到本机。这个参数默认是run,即获取或更新证书并安装。另一个值是renew,即更新证书。
--email 接收有关账户的重要通知的邮箱地址,非必要,建议最好带上
--agree-tos 同意ACME服务器的订阅协议
--preferred-challenges dns 以DNS Plugins的方式进行验证
--server https://acme-v02.api.letsencrypt.org/directory 指定验证服务器地址为acme-v02的,因为默认的服务器地址是acme-v01的,不支持通配符验证
--manual 采用手动交互式的方式验证
-d yourdomain.com -d *.yourdomain.com 指定要验证的域名。注意,不带www的一级域名yourdomain.com,和通配符二级域名*.yourdomain.com都要写,如果只写*.yourdomain.com生成出来的证书是无法识别yourdomain.com的
然后按回车执行,根据提示就能进行验证了,详细步骤参考:
《Let's Encrypt 终于支持通配符证书了》中的实践那部分。
。。。为什么我不把里面的步骤也写出来呢,并不是因为我懒(借口,就是懒),是因为文中的手动验证并不是本文的重点。看完那篇链接你会发现,验证居然如此多步骤。快过期时,直接renew更新通配符证书是不行的(具体原因看下文),所以每次90天快过期又得经历一次,不是我所期望的。
三、自动验证
Let’s Encrypt有规定,证书90天后会过期,会提前一个月发邮件通知(如果申请时有填写通知邮箱)。到时候又得经历一次重新申请的经历。一直这样手动验证是不太合理的,得想办法自动更新才行。所以我研究了文档和网上找资料,发现官方也有提供方法释放你的双手,这个东西叫validation hooks。
通过图理解hook的流程(图片来自网上)
可以看到DNS验证方式中,--manual-auth-hook和--manual-cleanup-hook参数是我们的重点。
也就是理解为,增加TXT记录的域名和使用完删除这个域名,本来需要我们登录到域名管理后台,手动去操作的,变成了现在由hook脚本去做。
这两个hook要怎么写呢?首先得你的域名供应商提供有API给你操作管理域名,然后参考官方文档。现在主流的域名供应商应该都有这种API。我用的是阿里云(万网)的域名,提供有API,去官方看了文档然后自己写出来了,有兴趣的可以参考或者直接使用:
https://github.com/broly8/letsencrypt-aliyun-dns-manual-hook
好了,我们接着往下走,在原来手动验证的命令行,改成:
1 2 3 4 5 6 7 8 9 10 |
certbot certonly \ --email your-email@example.com \ --agree-tos \ --preferred-challenges dns \ --server https://acme-v02.api.letsencrypt.org/directory \ --manual \ --manual-auth-hook /path/to/http/authenticator.sh \ --manual-cleanup-hook /path/to/http/cleanup.sh \ -d yourdomain.com \ -d *.yourdomain.com |
自动验证的命令行即在原来的基础上增加了两个hook。
四、关于更新
如果你用了上面我介绍的自动验证方式获取的证书,那么要更新证书就很简单了,一条命令搞定:
1 |
certbot renew |
附上两个的可选参数:
--force-renewal 强制更新证书。如果不带这个参数,必须等到快过期(正常是前一个月)才能更新。
--quiet 静默执行,不带有任何提示
如果你以前是用了手动验证的方式获取证书的,直接执行renew,是会报错的,比如让你提供manual-auth-hook脚本。要改成自动验证方式有两种方法,
方法一:在上面自动验证的命令行基础上,加上--force-renewal参数,强制再更新一次证书。
方法二:编辑文件 /etc/letsencrypt/renewal/yourdomain.com.conf
在文件末尾处添加两行:
1 2 |
manual_auth_hook = /path/to/http/authenticator.sh manual_cleanup_hook = /path/to/http/cleanup.sh |
这样执行renew操作就不会报错啦。
五、计划任务更新
写个简单的脚本 certrenew.sh
1 2 3 4 5 |
#!/usr/bin/env bash echo "[$(date +%Y-%m-%d/%H:%M:%S)]" certbot renew systemctl restart nginx |
加入计划任务crontab -e
1 2 |
# 每月15号01:00执行一次更新,并重启nginx服务器 0 1 15 * * /usr/bin/sh /path/to/certrenew.sh >>/path/to/certrenew.sh.log 2>&1 |
大功告成!
参考链接: