我们在使用let’s encrypt获取免费的HTTPS证书的时候,let’s encrypt需要对域名进行验证,以确保域名是你自己的
之前用默认的文件验证方式总有奇怪的问题导致失败,我也是很无奈,于是改用验证DNS-TXT记录的方式来验证,而且貌似如果申请泛域名证书也只能通过这个方式验证
本来呢我只打算在这篇记一下验证DNS记录的方式签发证书,不过以前也没写过如何用certbot签发免费Let’s Encrypt SSL证书诶,那正好就重头把过程写一遍。
一、安装Certbot
1.1 根据官网提示步骤安装
先去Certbot 官网,在网页上选择使用的服务器软件和系统版本,会跳转到安装的文档,
根据提示的步骤安装即可
1.2 使用自动安装脚本安装
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto # 给脚本执行权限
接下来直接使用该脚本进行签发证书等操作即可
第一次使用该脚本时会自动安装依赖。
官网提示的通过软件包管理安装的certbot,之后是可以直接使用certbot命令进行操作的
我接下来的描述中,执行命令默认是直接用certbot命令
如果你是用自动安装脚本certbot-auto的话,直接用这个脚本进行操作,我下面描述的命令里的certbot换成./certbot-auto
二、获取SSL证书
2.1 获取签发证书(standalone)
直接使用certbot
certonly命令即可开始签发,根据提示,先选择模式,一般选择standalone(使用standalone需要先停止nginx等服务器运行),然后根据提示列出需签的域名,之后会开始验证,通过之后会将生成的证书文件保存。
2.2 获取泛域名签发证书
获取泛域名签发证书(manual,通过DNS-TXT记录来验证域名有效性)
标题上线啦,这篇主要还是来讲这个验证问题的,感觉用这种方式签发更稳当一点。
certbot certonly --preferred-challenges dns -d "*.example.com" -d example.com --manual
用这个命令来手动验证DNS签发
这里我用example.com来假设要签的域名,-d后面跟着一个域名,如果有多个域名要签的话记得每一个单独的域名前都要写-d。
我指定了两个-d参数,因为certbot的泛域名其实只支持诸如*.example.com,如要直接使用example.com,就得为其单独也签发一条。
回车执行之后,会开始提示你给你的域名添加TXT解析记录。
这里将提示你为域名添加一个_acme-challenge的TXT记录,记录值为生成的一串字符。
这个只需要你去DNS服务商那里添加即可,这里如果你 -d 了几条不同的二级域名,那每个二级域名都要添加记录;在你添加完一个域名的记录值,在控制台回车之后会提示你下一个域名的记录值
![](/qrcode.jpg)
在你添加完记录保存之后,最好要检查一下解析记录。
在其他终端输入下面命令(示例example.com,记得修改):
nslookup -type=txt _acme-challenge.example.com 8.8.8.8
# 或者
dig -t txt _acme-challenge.example.com
如果包含你所添加的记录值,那么说明添加成功
那现在就可以控制台继续回车,不会意外就会把签发的证书文件保存,控制台打印出来证书文件的存放位置,一般情况下是会保存在/etc/letsencrypt/live/example.com目录下
这个目录下一般会有四个文件:
cert.pem: 服务器证书
chain.pem: 包含Web浏览器为验证服务器而需要的证书或附加中间证书
fullchain.pem: cert.pem + chain.pem
privkey.pem: 证书的私钥
我们一般用fullchain.pem和privkey.pem就可以了
三、在Nginx配置使用证书
这里我就不展开说了,监听的443端口设置ssl_certificate和ssl_certificate_key基本上就可以了
我这里贴上我自己的一段示例
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
# 你自己配置;
}
}
四、证书续期与注销
4.1 续期
免费的let’s encrypt有3个月的时间,到期前需要续期
第一次使用certbot签时如果输入了邮箱地址,证书快到期前是会发邮件提醒你的
单域名使用下面的命令续期
certbot renew --dry-run
设置自动续期的话,只需要写脚本放在Cron中定时运行即可,crontab -e打开crontab脚本,添加如下的脚本
0 3 */7 * * /bin/certbot renew --renew-hook "/where/your/nginx -s reload"
这个脚本表示每隔 7 天,夜里 3 点整自动执行检查续期命令一次。续期完成后,重启 nginx 服务
添加完后重启cron服务即可
service crond restart
泛域名通过DNS-TXT记录(自动)续期
这个就稍微麻烦一点,我们需要使用到DNS服务商提供的API,在renew证书时可以自动添加更新TXT记录来实现自动更新,当然一般还需要DNS服务商给用户提供的API密钥确保安全等
我先列出一些DNS插件的地址,具体的可以去查看插件安装使用方法,当然其他第三方的DNS插件也可以在github里找找
certbot提供的DNS插件列表
阿里云DNS插件
dnspod插件(腾讯云)
我这里使用的是DNSPOD,于是我也就只描述以下使用dnspod插件的情况
下载certbot-auth-dnspod脚本
wget https://raw.githubusercontent.com/al-one/certbot-auth-dnspod/master/certbot-auth-dnspod.sh
chmod +x certbot-auth-dnspod.sh
- 获取用户DNSPOD token
登录dnspod后,在控制台的用户中心 -> 安全设置下找到「API Token」,开启并创建token后,复制下id和token
- 配置token信息
echo "id,token" > /etc/dnspod_token
把id
和token
换成刚刚复制下来的真实内容 接下来就可以使用插件进行续期了
certbot renew --manual --preferred-challenges dns --manual-auth-hook /path/to/certbot-auth-dnspod.sh --force-renewal
如果要自动续期,就可以将下面的代码加入crontab中再重启cron服务,具体的过程上面说过了,这里也不再赘述
29 3 1 * * root /bin/certbot renew --manual --preferred-challenges dns --manual-auth-hook /path/to/certbot-auth-dnspod.sh --force-renewal --post-hook "/where/your/nginx -s reload"
这是每个月1号3点29分执行一次强制证书更新后重启nginx
当然用插件进行申请证书自动DNS验证也是可以的
certbot certonly --manual --preferred-challenges dns-01 --email [email protected] -d laravel.run -d *.example.com --server https://acme-v02.api.letsencrypt.org/directory --manual-auth-hook /path/to/certbot-auth-dnspod.sh
4.2 注销
使用下面的命令可以查看已生成的证书信息,包括证书名称,包含的域名,到期时间以及证书文件路径
certbot certificates
找到你要注销的证书,复制下证书文件的路径,然后使用下面的命令注销
certbot revoke --cert-path /etc/letsencrypt/live/example.com/fullchain.pem
参考链接:https://blog8.flyky.org/20191108/certbot-DNS-TXT-check/