如何运行无人值守升级,不是每天而是每隔几个小时

如何运行无人值守升级,不是每天而是每隔几个小时

默认情况下无人值守升级与 cron.daily 一起运行,最多是每天运行。对于攻击者来说,这可能需要很多时间。我想每 4 小时运行一次,我该怎么做?

答案1

无人值守升级的频率由两个步骤确定:

  1. 系统调度程序(例如 systemd 计时器或 cron/anacron),以及
  2. APT::周期性间隔。

其中一个的较低频率会阻碍另一个的较高频率,因此请确保设置正确两个都脚步。

第二步(APT::周期性间隔)需要 apt 版本 1.5 或更高版本,频率高于每天一次。 Debian 10 (buster) 附带 apt 1.8.2,所以没问题。

如果你使用 1.5 以下的 apt 版本,例如 Debian 9 (stretch),那么第二步就会出现问题。在开始第 1 步之前,滚动到此答案的底部,看看您是否愿意应用此处建议的丑陋解决方法。

另请注意,就像常规使用 一样, and /apt之间也有区别。第一个是关于更新可用软件包的列表,第二个是关于软件包的升级。再次确保更改两者的设置。updateupgradeinstall

1.系统调度程序

在 Debian 9 (stretch) 和 Debian 10 (buster) 中,该进程由以下两个 systemd 计时器启动:

  • apt-daily.timer,通过apt-daily.service调用/usr/lib/apt/apt.systemd.daily update更新包列表 ( apt-get update),以及
  • apt-daily-upgrade.timer,通过apt-daily-upgrade.service调用/usr/lib/apt/apt.systemd.daily install来安装升级 ( unattended-upgrade)。

(anacron 作业/etc/cron.daily/apt-compat仍然存在,但如果检测到 systemd 就会退出。如果没有 systemd,它将在/usr/lib/apt/apt.systemd.daily没有子命令的情况下运行,这意味着updateinstall。如果您不使用 systemd,请参阅其他答案或有关更改计划的 anacron 文档。)

通过覆盖默认计划,可以将 systemd 计时器设置为以更高的频率触发,在您的示例中每四个小时触发一次。首先,更新包列表:

$ sudo systemctl edit apt-daily.timer

这创建了/etc/systemd/system/apt-daily.timer.d/override.conf.填写如下:

[Timer]
OnCalendar=
OnCalendar=*-*-* 0,4,8,12,16,20:00
RandomizedDelaySec=15m

然后,20 分钟后进行实际升级:

$ sudo systemctl edit apt-daily-upgrade.timer

[Timer]
OnCalendar=
OnCalendar=*-*-* 0,4,8,12,16,20:20
RandomizedDelaySec=1m

检查你的工作:

$ systemctl cat apt-daily{,-upgrade}.timer
$ systemctl --all list-timers apt-daily{,-upgrade}.timer

(部分摘自Debian Wiki:无人值守升级.)

2. APT::周期性间隔

系统调度程序调用脚本/usr/lib/apt/apt.systemd.daily,该脚本使用文件戳机制来确定请求的操作上次运行的时间。它将其与 APT::Periodic 中为该操作设置的间隔进行比较。您通常应该在以下位置找到这些设置/etc/apt/apt.conf.d/20auto-upgrades

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

我一直认为"1"这里的值只是意味着 True 或 On,但实际上,它是运行之间的最小间隔,以天表示。如果脚本确定自上次执行请求的操作以来已经过去了更少的时间,它将简单地不是执行该操作,无论系统调度程序是否要求它。

现在,在 apt 1.5~beta2 中,Paul Wise 可以通过添加后缀s,m或来定义以秒、分钟和小时为单位的间隔h,因此您可以更改/etc/apt/apt.conf.d/20auto-upgrades为:

APT::Periodic::Update-Package-Lists "3h";
APT::Periodic::Unattended-Upgrade "3h";

(小于"4h",以考虑系统调度程序中的随机延迟。)

更好的是,他可以将间隔设置为"always"确保该操作仅在请求时执行,无论自上次运行以来已经过去了多长时间:

APT::Periodic::Update-Package-Lists "always";
APT::Periodic::Unattended-Upgrade "always";

我更喜欢这个,因为你设置了一次,从那时起,如果你想改变频率,你只需要与系统调度程序(systemd计时器)交互。

适合<1.5

Debian 9 (stretch) 附带 apt 1.4.9,因此将 APT::Periodic 间隔设置为"always""3h"步骤 2 中所述的方法将不起作用。顺便说一句,间隔几天"0.1"也是行不通的。

如果您不介意丑陋的解决方法,请编辑脚本,通过在函数中/usr/lib/apt/apt.systemd.daily插入来排除时间戳机制(使用风险自负!):return 0check_stamp()

--- a/lib/apt/apt.systemd.daily
+++ b/lib/apt/apt.systemd.daily
@@ -82,10 +82,12 @@ check_stamp()
        debug_echo "check_stamp: interval=0"
        # treat as no time has passed
         return 1
     fi

+    return 0
+
     if [ ! -f $stamp ]; then
        debug_echo "check_stamp: missing time stamp file: $stamp."
        # treat as enough time has passed
         return 0
     fi

这样,脚本将始终认为时间间隔已经过去,因此它将运行请求的任何操作。当您升级 apt 时,此解决方法应该被覆盖,然后您可以切换到使用"always"上述步骤 2 中的方法。

如果您不想弄乱脚本,请考虑自定义 cron 作业,如其他一些答案中所述。在这种情况下,您也无需担心此答案的第 1 步。

答案2

老问题,但对可能遇到与我相同问题的人说:

在 Ubuntu 16.04(可能还有其他 systemd 系统)上,无人值守升级不再由 cron 触发。相反,它使用 systemd 计时器。

为了修改运行时间和随机延迟,您需要修改/覆盖计时器。更多信息可以在这里找到: https://github.com/systemd/systemd/issues/3233

答案3

正如 Krzysztof 所指出的,为此您需要一个单独的 cron 条目。

最好unattended-upgrade直接调用(它是一个 python 脚本),以确保包黑名单/白名单、重新启动和其他细节得到适当处理。

例如:

echo "0 0-23/4 * * * root sleep $(( $RANDOM % 14400 ));PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin unattended-upgrade" > /etc/cron.d/unattended-upgrade

这将覆盖在 中配置的时间段/etc/apt/apt.conf.d/。这是有效的,因为这些检查不是在unattended-upgrade脚本内完成的,而是在调用脚本的上一级完成的/usr/lib/apt/apt.systemd.daily

输出将/var/log/unattended-upgrades/照常记录。

答案4

中的无人值守升级脚本/etc/cron.daily/apt使用以天为单位的升级间隔,因此不可能设置超过一天的频率。

您可以使用标准 cron - 将其放入/etc/cron.d

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 0-23/4 * * * root   apt-get -q update && apt-get dist-upgrade -yq -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold"

根据您的需要调整命令。

相关内容