如何安排 Let's Encrypt certbot 在 cron 中自动更新我的证书?

How do I schedule the Let's Encrypt certbot to automatically renew my certificate in cron?

我看到了相互矛盾的建议。来自 eff.org docs:

if you're setting up a cron or systemd job, we recommend running it twice per day... Please select a random minute within the hour for your renewal tasks.

我也看到了 weekly jobs 的推荐。

我不是 cron 专家,所以我更喜欢一个包含设置 cron 作业的详细步骤的答案。

所以我决定每天安排一次 运行。首先我测试了自动更新为 the docs recommend:

sudo letsencrypt renew --dry-run --agree-tos

然后我更新了crontab:

sudo crontab -e

这是我添加的行:

12 3 * * *   letsencrypt renew >> /var/log/letsencrypt/renew.log

这 运行 每天 3:12 上午更新。我认为文档建议 "a random minute within the hour" 在更新服务器上分配负载。所以我想 0、15、30 或 45 以外的任何值都是首选。

我在 cron 设置中查看了 randomizing the minute,就像 Jenkins 允许您做的那样。 在原始 EEF 页面上是这个示例:

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && /usr/local/bin/certbot-auto renew

最后,我使用 sudo bash 测试了 cron 命令:

sudo bash -c "letsencrypt renew >> /var/log/letsencrypt/renew.log"

我最近(2018 年 4 月)在 Ubuntu 16.04 服务器上安装并 运行 certbot(版本 0.22.2),并在 /etc/cron 中自动创建了续订 cron 作业。 d/certbot.

这是创建的 cron 作业:

# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew

请在放置新的 Cron 作业之前检查此项。

更新(来自@Hamish Downer 的评论)

值得注意的是,如果 /run/systemd/system 存在,上述 cron 作业将不会 运行 certbot 更新 - 这是因为 systemd 计时器是 运行ning certbot - read more about certbot and systemd timers here.

将以下行添加到 /etc/crontab 每天00:00 和大约 16:40:

1  1    * * *   root    sleep ${RANDOM:0:3}m && /home/admin/certbot-auto renew --quiet --no-self-upgrade --authenticator webroot --installer apache -w /var/www/mywebroot

一年多来效果很好。

更新命令本身可能因您而异 - 我使用了 webroot,因为它当时看起来最强大。

通常,当您 运行 为 Ubuntu 16.04 服务器中的任何网络服务器设置 certbot 时,它会自动创建一个 cron

#cat /etc/cron.d/certbot

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew

在 Debian Jessie 及更高版本(包括 Ubuntu)中,不为 Certbot 更新执行 cron。 取而代之的是使用 systemd 定时器。查看计时器:/lib/systemd/system/certbot.timer

此计时器运行以下服务:/lib/systemd/system/certbot.service

其中包含:

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
PrivateTmp=true

为了列出所有定时器,在终端中执行以下命令:

systemctl list-timers

希望 Certbot 是其中的一部分:

Mon 2019-02-04 08:38:45 CET 9h left Sun 2019-02-03 15:25:41 CET 8h ago certbot.timer certbot.service

更新:

由于反对票。我将添加如何在基于 Debian 的发行版上安装 Certbot(它可能因您的 Linux 发行版而异)。

但是在 Debian Stretch 中,例如您可以通过以下方式安装 certbot 的后向端口包:

sudo apt-get install certbot -t stretch-backports

这将自动安装上面显示的文件!从而自动为您安排一个 certbot 计时器,该计时器运行该服务,该服务再次运行更新。

手动 运行 始终可以通过以下方式续订:

sudo /usr/bin/certbot renew

可以通过 --force-renewal 标志强制执行。有关详细信息,请参阅更新的帮助文本:

/usr/bin/certbot --help renew

certbot 包的文件部分(包括但不限于):

dpkg-query -L certbot
...
/lib/systemd/system/certbot.service
/lib/systemd/system/certbot.timer
...

好的。因此,在使用 systemd 的 Debian(或 Ubuntu)上,我可能遇到了与其他人相同的问题 - cron 作业未启动。我需要做一些其他地方没有提到的额外步骤和观察,所以单独回答它。


在我的例子中,/etc/systemd/system/ 目录存在,因此 /etc/cron.d/certbot 中的作业在初始测试时停止。

但是 /etc/systemd/system/certbot.timer 是指向 /dev/null 的指针。这意味着它是一个 masked 计时器。当我执行 systemd unmask certbot.timer 时,link 被删除,但我没有任何东西可以替换它(尝试 locate certbot.timer 但 none 安装在我的系统上)。我还可以在 systemd list-timers --all 中看到计时器,但它是一个空文件,因此也使用 systemd disable certbot.timer 将其删除。 /etc/systemd/system/certbot.service 中的服务完全 不存在

因此,在从 /etc/systemd/system/ 中实际清除所有与 certbot 相关的内容之后,我 手动创建了必要的文件

# /etc/systemd/system/certbot-renewal.service
[Unit]
Description=Certbot Renewal
[Service]
ExecStart=/usr/local/bin/certbot -q renew --post-hook "systemctl reload nginx"
# /etc/systemd/system/certbot-renewal.timer
[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
WantedBy=timers.target

定时器文件内容来自this answer.

我开始并检查了整个事情 运行:

sudo systemctl start certbot-renewal.timer
sudo systemctl enable certbot-renewal.timer
sudo systemctl list-timers --all
sudo journalctl -u certbot-renewal.service

更多注意事项:

  • 我在 /usr/local/bin/certbot 而不是 /usr/bin/certbot 中有 certbot(使用 which certbot 计算),不知道为什么。
  • 我正在使用 nginx,因此需要在 post 挂钩中重新加载它以考虑更新的证书。

每 2 个月更新一次:

#nano /etc/cron.d/certbot    

30 03 01 */2 * echo "2" | certbot --nginx -v -d yourdomain.com

为简单起见,设置一个计时器以自动验证:

systemctl status certbot.timer