使用免费的 Let's Encrypt 证书

环境说明

  • OS: CentOS 6
  • Web server: Nginx 1.x(通过 yum 安装)

Certbot 安装

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

证书安装

执行以下命令,按提示操作即可

/path/to/certbot-auto --nginx

安装完成后,nginx 配置文件中已经自动添加了证书的相关配置

自动续期

在 root 用户的 crontab 中加入一个定时任务,每天凌晨 2:30 执行一次

sudo crontab -e
# add line
# 30 2 * * * /path/to/certbot-auto renew --quiet --post-hook "service nginx reload"

用户可以通过日志文件定位错误,日志文件位置:/var/log/letsencrypt/letsencrypt.log

20180205 更新:

直到我收到证书要过期的邮件提醒,我的证书也没有自动续期成功。通过查看日志,发现定时任务每天都执行了。为解决问题,在网上各种搜索,大多说的是 crontab 本身或脚本路径、权限的问题,一直没找到对我适用解决办法。

今天,无意查看 /var/spool/mail/root 文件,发现有报错信息

Failed to find executable service in expanded PATH: /usr/bin:/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
Unable to find post-hook command service in the PATH.
(PATH is /usr/bin:/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin)

经网上查询,发现官网的一个帖子 Renewing: unable to find renew-hook,也是说 service 命令不在 root crontab 的环境变量 PATH 内。在我的服务器上,service 命令的位置是 /sbin/service,而报错信息中指明的 PATH 不包含 /sbin 路径,所以才找不到 service 命令。

到这里,问题就很明显了,解决方案有:

  • crontab 定时任务改为 30 2 * * * /path/to/certbot-auto renew --quiet --post-hook "/sbin/service nginx reload"
  • crontab 定时任务改为 30 2 * * * /path/to/certbot-auto renew --quiet --post-hook "/etc/init.d/nginx reload"
  • crontab 定时任务改为 30 2 * * * PATH=$PATH:/sbin; /path/to/certbot-auto renew --quiet --post-hook "service nginx reload"

总结,crontab 中涉及到的所有命令尽量写绝对路径

20180315 更新:

定时任务中使用 certbot-auto renew 命令续期失败,错误信息

certbot.main:Could not choose appropriate plugin: The nginx plugin is not working; there may be problems with your existing configuration.

上一小节“证书安装”是在交互式模式下安装的证书,并且使用到了 nginx 插件,但定时任务是在非交互模式下执行的,并且不能使用 nginx 插件。使用 certbot-auto certonly 命令替换 certbot-auto renew 命令,其中,-w 指明 web 程序根目录,-d 指明 域名

  • crontab 定时任务改为 30 2 * * * /path/to/certbot-auto certonly --webroot -w /path/to/www.izhizheng.net/webroot/ -d www.izhizheng.net --post-hook "/sbin/service nginx reload"
  • crontab 定时任务改为 30 2 * * * /path/to/certbot-auto certonly --webroot -w /path/to/www.izhizheng.net/webroot/ -d www.izhizheng.net --post-hook "/etc/init.d/nginx reload"
  • crontab 定时任务改为 30 2 * * * PATH=$PATH:/sbin; /path/to/certbot-auto certonly --webroot -w /path/to/www.izhizheng.net/webroot/ -d www.izhizheng.net --post-hook "service nginx reload"

20180316 更新:

定时任务(非交互式模式)执行 certbot-auto certonly 命令时,日志文件中报以下错误

DEBUG:certbot.log:Exiting abnormally:
in input_with_timeout raise EOFError
ERROR:certbot.log:An unexpected error occurred:

虽然不影响续期,但还是要解决问题。尝试在 shell(交互式模式)中执行 certbot-auto certonly 命令,输出以下内容

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Cert not yet due for renewal

You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/www.izhizheng.net.conf)

What would you like to do?
-------------------------------------------------------------------------------
1: Keep the existing certificate for now
2: Renew & replace the cert (limit ~5 per 7 days)
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

可以看出,默认情况下,certbot-auto certonly 命令是交互式的,需要用户参与。为了不要用户参与,可以给 certbot-auto certonly 命令添加 --quiet 参数(Silence all output except errors. Useful for automation via cron)

  • crontab 定时任务改为 30 2 * * * /path/to/certbot-auto certonly --quiet --webroot -w /path/to/www.izhizheng.net/webroot/ -d www.izhizheng.net --post-hook "/sbin/service nginx reload"
  • crontab 定时任务改为 30 2 * * * /path/to/certbot-auto certonly --quiet --webroot -w /path/to/www.izhizheng.net/webroot/ -d www.izhizheng.net --post-hook "/etc/init.d/nginx reload"
  • crontab 定时任务改为 30 2 * * * PATH=$PATH:/sbin; /path/to/certbot-auto certonly --quiet --webroot -w /path/to/www.izhizheng.net/webroot/ -d www.izhizheng.net --post-hook "service nginx reload"

此时,执行 certbot-auto certonly 命令,“What would you like to do?” 默认选项为 1

参考资料

相关文章

此处评论已关闭