如何在 Ubuntu 20.04 上自动更新 certbot 证书

如何在 Ubuntu 20.04 上自动更新 certbot 证书

我在 AWS 上的 Ubuntu 20.04 上运行 certbot,安装为 snap 包。我不确定 certbot 更新是否运行正常。如果能帮助我找出如何最好地让它工作,我将不胜感激。

这是一台新服务器,我在准备投入生产时会打开和关闭它。目前它每天运行大约 8-10 个小时。它很少在午夜运行,我认为那是 cron 作业运行的时间。一旦我完成配置,几天后它将全天候运行。

我发现的一件事这个问题的答案

您无需设置任何东西。任何最近安装的 Debian/Ubuntu certbot 都应安装 systemd 计时器和 cron 作业(并且 cron 作业仅在 systemd 未处于活动状态时才会运行 certbot,因此您无法同时运行两者)。

在我看来,certbot 计时器没有运行,如果运行了,它似乎指向 /dev/null。由于 systemd 处于活动状态,我想知道 cron 作业是否正在运行。

计时器和 systemd

我发现了一个评论计时器和快照可能存在问题,所以这可能是已知问题。

systemctl 列表计时器

计时器似乎没有运行

NEXT                        LEFT          LAST                        PASSED       UNIT                         ACTIVATES
Wed 2021-03-17 23:44:00 UTC 3h 24min left n/a                         n/a          snap.certbot.renew.timer     snap.certbot.renew.service

Certbot 计时器似乎指向 /dev/null。这个问题表明情况不应该如此。

> root@aws2:/etc/systemd/system# ls -l | grep certbot
lrwxrwxrwx 1 root root    9 Jan  9 06:38 certbot.timer -> /dev/null

我可以在系统日志中看到以下内容,但我不确定这是什么意思

Mar 17 16:51:02 aws2 systemd[1]: Started Timer renew for snap application certbot.renew.

克罗恩

在系统日志中我可以看到 cron 任务正在运行,但没有输出

Mar 16 00:00:01 aws2 CRON[2072]: (root) CMD (test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew)

以下内容位于 /etc/cron.d/certbot 中(这可能是 certbot 安装时放在那里的,我大致知道它的作用,但不知道 test / perl 部分的作用)

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(43200))' && certbot -q renew

当我运行整个命令(root test /x 等)时,我收到以下消息。

Command 'root' not found, but can be installed with: snap install root-framework

当我运行此部分时,我没有得到任何输出(请注意,我已从 certbot 中删除了“-q”以进行测试)。我不确定测试部分在做什么,但当我运行此命令时,certbot 似乎没有做任何事情。

> test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot renew

关键问题

  1. 大家知道 systemd 计时器出了什么问题吗?为什么它指向 /dev/null?或者我应该忽略这个已知问题?
  2. 我是否应该像 Ubuntu 建议的那样“snap install root-framework”来安装“root”?
  3. cron 作业“root test”似乎没有做任何事情...有人能解释一下那里正在测试什么以及“cerbot renew”是否真的在运行吗?

更新 - 建议的解决方案(再次更新)

请注意,这不是必需的。systemd 计时器开始正常工作。

在 /etc/cron.daily 文件夹中,我创建了以下文件夹。我认为它会做我想要的事情,我会在某个时候检查日志来查看。我仍然对上面提出的问题感兴趣。

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
/usr/bin/certbot -q renew

答案1

由于你正在使用 snap,因此值得再检查一下是否有第二计时器(certbot-renew 除外)由 snap 实现,并且可以正确完成更新。

在这里您可以看到我有一个掩码来确保正常的 certbot.timer 被禁用,但我也有一个通过 snap 安装的计时器:

root@pi:/etc/systemd/system # ls -l *certbot*
lrwxrwxrwx 1 root root   9 Oct  6 10:42  certbot.timer -> /dev/null
-rw-r--r-- 1 root root 293 Oct  6 05:26  snap.certbot.renew.timer

我可以看到它每天运行两次并且当前正在等待:

root@pi:/etc/systemd/system # systemctl list-units | grep certbot.renew
snap.certbot.renew.timer    loaded active waiting   Timer renew for snap application certbot.renew

root@pi:/etc/systemd/system # cat snap.certbot.renew.timer [Unit]
# Auto-generated, DO NOT EDIT 
Description=Timer renew for snap application certbot.renew 
Requires=snap-certbot-1515.mount 
After=snap-certbot-1515.mount 
X-Snappy=yes

[Timer] 
Unit=snap.certbot.renew.service 
OnCalendar=*-*-* 07:09 
OnCalendar=*-*-* 19:46

[Install] 
WantedBy=timers.target

不要被 cronjob 欺骗。它会进行双重检查,以确保它没有执行已由 systemd 管理的任务:

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

其中使用test的返回代码为“1”,因此 && 之后的任何内容都不会执行。

您的解决方法不会引起问题 - 但库存安装应该做正确的事。

因此,回答你的三个问题:

大家知道 systemd 计时器出了什么问题吗?为什么它指向 /dev/null?或者我应该忽略这个已知问题?

这是为了双重检查是否使用了 snap 定时器,以及 certbot 的任何系统定时器(例如通过 apt 安装时)是否

我是否应该像 Ubuntu 建议的那样“snap install root-framework”来安装“root”?

存储在 /etc/cron.d 中的 Cron 文件具有包含执行时要使用的用户名的语法。root这里表示 cronjob 以 root 用户身份运行。您不需要安装 root-framework - 单词“root”不是命令本身的一部分。

cron 作业“root test”似乎没有做任何事情...有人能解释一下那里正在测试什么以及“cerbot renew”是否真的在运行吗?

如上所述 - 这个 cronjob 有效地说“嘿,systemd 正在运行!我不会做任何事情!”

最后,您可以在日志文件中验证续订状态:

# grep -c skipped /var/log/letsencrypt/letsencrypt.log
14

就我的情况而言,虽然尚未发生任何续订(有效期足够长)但它正在运行 - 只是非常安静。

答案2

关于:

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(43200))' && certbot -q renew

您收到命令 root not found 的原因是您root在命令中包含了用户。该 cron 作业文件中的格式为min, hr, day, month, day of week, user, command。如果您想运行它进行测试,只需从命令前面删除用户名即可。

Cron 作业一般在设定的时间运行,如果服务器在这段时间内关闭,则作业不会稍后运行以弥补错过的时间。如果服务器开启,它只会在“闹钟”再次响起时运行。

有一个解决方案,cron 支持运行时的昵称,其中之一是@rebootCrontab(5) 手册

我会设置两个 cron 作业,一个按计划运行,例如每周一次或每月一次,由经销商选择。然后运行第二个作业以@reboot弥补服务器关闭时错过的任何内容。当然,如果服务器总是关闭和打开,那么它可能每天运行。但是 certbot 不会在意,更新程序会检查您的证书距离到期还有多久,如果证书没有接近到期,它就不会联系 certbot 服务器。

除非您需要它是计时器,否则请忽略此解决方案......

保留/etc/cron.d/certbot,但也许将其改为每周一次而不是每 12 小时一次。

# This would run every Sunday at 01:01
1 1 * * 0 root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

并添加到/etc/crontab

#This would run every time the server is booted.
@reboot root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

我不知道“Snap 包”是什么,也不知道为什么需要那么多额外的命令行。Certbot 通常只需要这个就可以工作。

@reboot root /usr/bin/certbot renew > /dev/null 2>&1

如果你只是希望 certbot 每周检查一次续订情况,假设服务器始终在线,并且你不需要 certbot 与任何控制面板或其他东西配合使用来进行续订,那么最简单的做法是

内部/etc/crontab添加

1 1 * * 0 root /usr/bin/certbot renew > /dev/null 2>&1

相关内容