Ubuntu 似乎对不永久连接到互联网的计算机的安全升级存在一个长期的盲点。如今,这样的计算机数量肯定很多,其中大部分是笔记本电脑。
理论上的解决方案是unattended-upgrades
。在 Ubuntu 上,默认情况下,它使用每日systemd
计时器或 cron 作业运行。使用 cron,anacron
默认情况下也会作为保护运行,并执行cron
由于计算机关闭而错过的任何作业。到目前为止,这是明智的。
但!
默认
unattended-upgrades
配置(/etc/apt/apt.conf.d/50unattended-upgrades
或类似配置)需要设置以下内容,否则在漫游笔记本电脑上升级可能会被跳过:Unattended-Upgrade::OnlyOnACPower "false"; Unattended-Upgrade::Skip-Updates-On-Metered-Connections "false";
更糟糕的是,
anacron
无论cron
是否有互联网连接,都会运行作业!这显然是非服务器 Ubuntu 的一个主要设计缺陷,因为个人电脑并不总是永久连接的。
TLDR:在漫游笔记本电脑上,使用默认配置unattended-upgrades
大多数时候都无法工作。
(也许需要有一个单独的cron
作业类或systemd
计时器,等待网络连接直到执行。或者cron.daily
可以切换到失败的作业,cron.hourly
直到它们成功执行。也许已经有一个了。)
一个实用的解决方案是网络上线后systemd
,将单元文件作为用户脚本执行unattended-upgrades
。但它每次启动时只会运行一次。
最佳解决方案是什么?有人知道是否有计划通过新软件包或配置改进来解决这个问题吗?
答案1
如果使用 连接到互联网network-manager
(Ubuntu 上的当前默认设置),则在连接到网络后创建一个调度程序脚本来启动unattended-upgrade
(是一个符号链接,也可以工作):unattended-upgrades
sudo touch /etc/NetworkManager/dispatcher.d/20-myconnectionscript
sudo chmod +x /etc/NetworkManager/dispatcher.d/20-myconnectionscript
在20-myconnectionscript
:
#!/bin/sh
if [ "$2" = "up" ];
# only proceed if unattended-upgrades was last run more than a day ago
ELAPSEDSINCEUU=$(($(date +%s) - $(date +%s -r /var/lib/apt/periodic/unattended-upgrades-stamp)))
if [ $ELAPSEDSINCEUU -gt 86400 ]; then
apt update --yes # replace, see below
/usr/bin/unattended-upgrade # replace, see below
fi
fi
编辑。结果是unattended-upgrades
没有触发软件包列表的更新。因此,如果unattended-upgrades
失败了,那么很有可能apt update
也失败了,在这种情况下升级将继续无法进行!因此,在脚本中添加了手动更新。令人失望的是,确保安全升级必须如此复杂。
编辑2。如果您希望绝对确保您的笔记本电脑是最新的,那么这就是您在非交互式脚本中所需要的。可以确认它可靠地工作。用它替换上面的 2 行。
DEBIAN_FRONTEND=noninteractive apt-get --yes update
DEBIAN_FRONTEND=noninteractive apt-get --yes --allow-downgrades --allow-remove-essential --allow-change-held-packages -- option Dpkg::Options::=--force-confold --option Dpkg::Options::=--force-confdef dist-upgrade
这是完整的dist-upgrade
,而不仅仅是安全升级。如果有人对安全版本有建议,在非交互模式下运行总是有效的,并且不需要对 repo 配置进行过多的调整,请建议一下。
再次:unattended-upgrades
不能指望发挥作用适用于间歇性连接的计算机。Ubuntu 安全团队确实需要解决这种情况。