默认情况下无人值守升级与 cron.daily 一起运行,最多是每天运行。对于攻击者来说,这可能需要很多时间。我想每 4 小时运行一次,我该怎么做?
答案1
无人值守升级的频率由两个步骤确定:
- 系统调度程序(例如 systemd 计时器或 cron/anacron),以及
- APT::周期性间隔。
其中一个的较低频率会阻碍另一个的较高频率,因此请确保设置正确两个都脚步。
第二步(APT::周期性间隔)需要 apt 版本 1.5 或更高版本,频率高于每天一次。 Debian 10 (buster) 附带 apt 1.8.2,所以没问题。
如果你使用 1.5 以下的 apt 版本,例如 Debian 9 (stretch),那么第二步就会出现问题。在开始第 1 步之前,滚动到此答案的底部,看看您是否愿意应用此处建议的丑陋解决方法。
另请注意,就像常规使用 一样, and /apt
之间也有区别。第一个是关于更新可用软件包的列表,第二个是关于软件包的升级。再次确保更改两者的设置。update
upgrade
install
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
没有子命令的情况下运行,这意味着update
和install
。如果您不使用 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 0
check_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"
根据您的需要调整命令。