今晚发现 hellodk.com 的几个网站的证书过期(比如 https://router.hellodk.com )无法访问,然后续期证书遇到问题,本文记录解决过程。

由于之前是配置了 crontab 脚本定期续期证书的,没有成功续上那就肯定是程序执行出错了。检查 cron 日志发现下面这个报错

PluginError('An authentication script must be provided with
--manual-auth-hook when using the manual plugin non-interactively godaddy

出现这个错误的原因是 certbot 无法直接更新你的域名的DNS记录中的 TXT 记录值导致更新失败

因为推荐的申请泛域名证书/通配符证书的方式是--preferred-challenges dns dns challenge 模式。这是使用 DNS 方式校验域名所有权,域名验证 dns 解析需要增加 TXT 类型的解析配置,子域名为_acme-challenge 默认情况下需要你自己去域名服务商(比如 阿里云 腾讯云 华为云 godaddy等) dns 解析那里去配置。如果想要通过命令行直接更新 txt 值就要利用 certbot 提供的 hook 函数,我们在shell 中调用DNS服务商的相关API接口就可以动态的更新TXT记录了

就是这样一个原理。好在已经有大神写出来了相关的项目了。因为我的域名服务商使用的是 godaddy 所以找了一个支持 godaddy的github项目: https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au

仔细阅读大神项目的 readme 文档


重要的几个点

  1. 确定你的 au.sh 文件有执行权限
  2. 确定你域名的根域名在 domain.ini 文件中存在,如果不存在就自行添加一行
  3. 获取 DNS API 密钥,这个 API 密钥是用来认证你的用户身份以及授权http请求(因为你要通过调用服务商的 api 来更新 TXT 记录的值)
  4. 将获取的或者是新建的 api key 和 secret 填在 au.sh 文件中
  5. 先利用 certbot 的--dry-run 选项进行一次证书申请的测试
  6. 测试成功后再进行证书申请(或者是续期)
  7. 确定调用dns服务商的hook 是用的 python 还是 php,这个项目中腾讯云、阿里云、华为云都是用的python,而godaddy是php。要确保你的机器安装了python或php,否则肯定会报 command not found 之类的错误
  8. 这个项目中,aly 是阿里云;txy 是腾讯云;hwy 是华为云;godaddy 是 godaddy

附上一个小插曲,centOS7 安装 php7 的教程: https://linuxize.com/post/install-php-7-on-centos-7/

简而言之就是下面几条命令

  1. yum install epel-release yum-utils
  2. yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
  3. yum-config-manager --enable remi-php73
  4. yum install php php-common php-opcache php-mcrypt php-cli php-gd php-curl php-mysqlnd

执行 php -v 有版本输出代表本机的php7成功安装

$ php -v
PHP 7.3.27 (cli) (built: Feb  2 2021 10:32:50) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.27, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.27, Copyright (c) 1999-2018, by Zend Technologies

在开始之前,建议执行 certbot certificates 查看本机安装的证书,使用certbot delete 删除不需要的证书再开始(删除的时候是交互式的,放心大胆的执行 certbot delete 没事,会让你选择数字然后yes确认,或者直接按c取消操作)

测试申请通配符证书

带上 --dry-run 选项

certbot certonly -d "*.hellodk.com" -d hellodk.com \
--manual --preferred-challenges dns --dry-run \
--manual-auth-hook "/root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy add" \
--manual-cleanup-hook "/root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy clean"

下面这是测试时候的日志

[root@justhostRU /]# certbot certonly -d "*.hellodk.com" -d hellodk.com --manual --preferred-challenges dns --dry-run --manual-auth-hook "/root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy add" --manual-cleanup-hook "/root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy clean"
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Cert is due for renewal, auto-renewing...
Simulating renewal of an existing certificate for *.hellodk.com and hellodk.com
Performing the following challenges:
dns-01 challenge for hellodk.com
dns-01 challenge for hellodk.com
Running manual-auth-hook command: /root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy add
Running manual-auth-hook command: /root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy add
Waiting for verification...
Cleaning up challenges
Running manual-cleanup-hook command: /root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy clean
Running manual-cleanup-hook command: /root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy clean

IMPORTANT NOTES:
 - The dry run was successful.

如果有 IMPORTANT NOTES: - The dry run was successful. 的日志输出,那么说明 api key 和 secret 配置的肯定是正确的,说明成功请求到 dns 服务商的 api,然后就可以进行接下来的续期操作了

接着是实际上的续期证书

命令

certbot renew --manual --preferred-challenges dns \
--manual-auth-hook "/root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy add" \
--manual-cleanup-hook "/root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy clean"

下面这是实际续期时候的日志

[root@justhostRU /]# certbot renew --manual --preferred-challenges dns --manual-auth-hook "/root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy add" --manual-cleanup-hook "/root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy clean"
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/hellodk.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator manual, Installer None
Renewing an existing certificate for *.hellodk.com and hellodk.com
Performing the following challenges:
dns-01 challenge for hellodk.com
dns-01 challenge for hellodk.com
Running manual-auth-hook command: /root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy add
Running manual-auth-hook command: /root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy add
Waiting for verification...
Cleaning up challenges
Running manual-cleanup-hook command: /root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy clean
Running manual-cleanup-hook command: /root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy clean

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/hellodk.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all renewals succeeded:
  /etc/letsencrypt/live/hellodk.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

成功续期

执行一下 nginx -s reload

网页访问 https://router.hellodk.com

20210409231517.png

成功续期

修改/添加 crontab 脚本

# 每当 7月 10月 1月 4月 的 7号 上午9点 执行命令,续期通配符证书
0 9 7 7,10,1,4 * /usr/bin/certbot renew --manual --preferred-challenges dns --manual-auth-hook "/root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy add" --manual-cleanup-hook "/root/temp/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php godaddy clean" --renew-hook "/usr/sbin/nginx -s reload"

crontab -e 将上面的命令追加到末尾

# 重载 crond 服务
systemctl reload crond.service

# 重启 crond 服务
systemctl restart crond.service

这样一来,7月、10月、2022年1月、2022年4月(后面不断推进时间……)的7号上午的9点都会自动的续期通配符证书,https服务可以不间断的运行了。本文的分享结束

end.