☰
Ubuntu 18.04关闭unattended-upgrade:彻底禁用自动更新与安全补丁管理
2026/10/9 3:18:26 网站建设 项目流程

1. 项目背景与核心需求解析

1.1 unattended-upgrade 到底是什么

用过 Ubuntu 的人都应该对这个服务不陌生。它在 18.04 系统里默认就是开启的,作用是每天定时检查软件源,发现有安全更新或者常规更新后,自动下载并安装,省去管理员手动敲apt upgrade的麻烦。听起来很省心,但实际部署中,这个"省心"往往会变成"堵心"。

我最早碰到这个问题是在一台跑着 MySQL 的机器上。某天早上监控报警,数据库挂了。排查了半天,发现是凌晨 unattended-upgrade 自动更新了内核,然后触发了系统自动重启。虽然服务配置了开机自启,但因为重启时间点正好赶上业务高峰,恢复过程把整个链路都打乱了。从那天起,凡是生产环境,我第一时间就会检查这台机器有没有装 unattended-upgrade,装了就直接关掉。

对个人桌面用户来说,开着 unattended-upgrade 确实能降低安全风险。但对服务器、特别是承载核心业务的服务器,自动更新带来的不确定性往往比漏洞本身更可怕。它可能会在凌晨三点给你的 Nginx 升级到新版本,可能因为某个依赖冲突把 PHP 环境搞崩,也可能悄悄把一个配置文件的格式给改了。如果你经历过一次"早上到公司发现全站 502"的事故,就会理解为什么那么多管理员选择把它关掉。

1.2 适合关闭此功能的典型场景

我总结了一下,以下三类环境最需要关闭 unattended-upgrade:

  • 生产服务器:任何在跑线上业务的机器,都不应该让系统在无人值守的情况下自动变更软件包。哪怕只是一个小版本升级,也可能引入回归问题。
  • 需要严格变更控制的单位:很多公司内部有运维规范,所有变更都要走审批流程。自动更新等于绕过了审批,这种"计划外变更"在审计时非常要命。
  • 运行长期任务或特殊服务的机器:比如编译机、跑着长时间科学计算任务的机器、部署了自定义内核模块的机器。这些环境里,一个突如其来的软件更新可能直接打断任务。

但要注意,关闭 unattended-upgrade 不等于放弃安全更新。只是把"自动安装"变成"手动确认",安全更新依然可以通过apt update && apt upgrade手动执行。后面我会详细讲,如何在关闭自动更新后还能及时跟进安全补丁。

2. 关闭方案设计与原理拆解

2.1 程序包、服务与配置文件的关联关系

在动手关闭之前,有必要先搞清楚 18.04 里这个功能是怎么组织起来的。它不是一个孤立的可执行文件,而是由一个程序包、一个 systemd 服务、一组 apt 配置共同组成。

  • 程序包:unattended-upgrades
  • systemd 服务:unattended-upgrades.service和apt-daily-upgrade.service
  • apt 配置目录:/etc/apt/apt.conf.d/下的20auto-upgrades、50unattended-upgrades

平时你可能只听说过unattended-upgrade这个命令,但真正触发自动更新的是 systemd 的定时器(timer)。比如apt-daily-upgrade.timer会每天触发一次apt-daily-upgrade.service,这个服务内部就会调用unattended-upgrade程序。所以,想彻底关掉,不能只删掉一个文件,而是要同时处理服务自动激活和 apt 配置提示。

很多人直接执行systemctl disable unattended-upgrades,以为这样就行了,其实还不够。因为apt-daily-upgrade.service是独立的服务,它同样会触发自动升级。如果只禁用一个,另一个还在,你依然会在日志里看到自动更新操作。

2.2 为什么不推荐直接卸载

有一种更"暴力"的思路,就是直接apt remove unattended-upgrades。我当然试过,这样做确实百分之百能关闭,但我不推荐在多数环境下直接卸载。

原因有三:

  1. 系统里其他组件可能依赖它。虽然 Ubuntu 桌面版和服务器版默认都装了,但卸载后某些查找更新提示的功能可能失效。
  2. 以后如果你想重新启用自动安全更新,还得重新安装,并且要重新配置一系列选项。
  3. 卸载改动范围大,在最小化安装的容器镜像里可能会带来不必要的兼容性问题。

我更推荐的做法是:保留软件包,禁用触发机制,并修改配置让它完全不干活。这样既能保证系统组件完整性,又能让自动更新彻底停下。

3. 实操过程与核心环节实现

3.1 第一步:确认当前运行状态

动手调整前,先看看当前服务到底处于什么状态。我用的是 18.04,但下面命令在其他版本上同样适用。

systemctl status unattended-upgrades systemctl status apt-daily-upgrade.service systemctl status apt-daily-upgrade.timer

如果看到unattended-upgrades.service的状态是active (running),说明它正在后台运行。apt-daily-upgrade.timer的状态应该是active (waiting),表示定时器已经在等待触发点。

接着看一下 apt 自动更新的配置文件:

cat /etc/apt/apt.conf.d/20auto-upgrades

默认输出一般是这样:

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

这两行配置的含义很明确:第一行表示每天自动更新软件包列表,第二行表示每天运行 unattended-upgrade 自动安装更新。把它们都改成"0",就能从配置层面让自动更新失效。

但改配置只能拦住"APT 自动调起"这条路径,systemd 定时器那条路径可能会绕过部分检查。所以标准操作是:先改配置,再禁用服务,双保险。

3.2 第二步:修改 APT 配置彻底关闭自动更新

打开配置文件:

sudo nano /etc/apt/apt.conf.d/20auto-upgrades

把两行都改成"0":

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

保存退出。这里我想特别补充一句:Update-Package-Lists也建议关掉,否则系统仍然会每天自动执行apt update,虽然不装软件,但会产生网络流量和源索引更新日志,对某些严格网络环境也是麻烦。

除了这个文件,还有一个/etc/apt/apt.conf.d/50unattended-upgrades,它定义了哪些包可以自动更新、哪些需要排除。如果前面已经设成"0",这个文件实际上不会触发,但为了保险,你也可以进去把里面的自动更新开关段落全部注释掉。不过一般不需要动它,保留即可。

3.3 第三步:禁用 systemd 定时器和服务

这才是"掐断源头"的关键步骤。依次执行:

sudo systemctl stop unattended-upgrades.service sudo systemctl disable unattended-upgrades.service

然后处理 apt-daily-upgrade:

sudo systemctl stop apt-daily-upgrade.service sudo systemctl disable apt-daily-upgrade.service sudo systemctl stop apt-daily-upgrade.timer sudo systemctl disable apt-daily-upgrade.timer

这里disable是让服务下次开机不再自启,stop是让当前正在运行的立即停止。两个都要执行,顺序无所谓。

顺带提醒一句:18.04 里还有一个apt-daily.timer,它是负责每天自动执行apt update的定时器。如果连软件列表更新也想彻底关掉,就把它也禁掉。命令类似:

sudo systemctl stop apt-daily.timer sudo systemctl disable apt-daily.timer

3.4 第四步:验证关闭结果

配置改完、服务禁用完之后,必须验证一下,别相信我说的,也不要相信"应该这样就行",要用命令确认。

先看服务状态:

systemctl is-enabled unattended-upgrades.service apt-daily-upgrade.service apt-daily-upgrade.timer

如果全部输出disabled,说明自启已经被禁用。更彻底的验证是重启系统后再看状态,因为我遇到过某些情况下服务状态显示 disabled,但系统重启后又出现了,原因可能是被 dependencies 间接拉起。

再看配置文件是否生效:

apt-config dump | grep -E "Unattended-Upgrade|Update-Package-Lists"

输出应该看到两个"0"。

最后看进程列表,确认没有残留进程:

ps aux | grep unattended

正常情况下不会看到任何进程。如果看到,说明还有别的路径在触发它,需要进一步排查。

3.5 补充一个技巧:保留安全更新但禁用自动重启

有些朋友的真实需求其实不是完全关闭 unattended-upgrade,而是只想关掉"自动重启"。因为 18.04 里很多内核安全更新装完后会要求重启,一重启就出问题。

这时可以不去完全关闭功能,而是修改/etc/apt/apt.conf.d/50unattended-upgrades中的配置。找到这一段:

Unattended-Upgrade::Automatic-Reboot "true";

把它改成"false",就能让系统只安装更新,不自动重启。同样的,如果发现存在"自动清理不需要的依赖包"等行为,也可以在文件里控制。但要注意,修改这个文件前最好先备份,不要删错段落。

4. 常见问题与排查技巧实录

4.1 关闭后又自动更新了怎么办

我见过很多这样的情况:明明按网上的教程设置了"0",也 disable 了服务,但第二天发现日志里还是有 unattended-upgrade 的痕迹。如果有这种问题,优先级最高的排查方向有三个。

第一,确认是否禁用了所有相关定时器。systemctl list-timers | grep apt能列出所有与 apt 相关的定时器,仔细看有没有apt-daily-upgrade.timer、apt-daily.timer。我建议把这两个都 disable 掉。

第二,检查/etc/cron.daily/下是否有apt-compat之类的脚本。18.04 虽然使用 systemd,但部分残留的 cron 任务也可能调用 apt 自动更新。可以通过ls /etc/cron.daily/看是否有unattended-upgrades相关的符号链接,有的话删掉。

第三,也是最容易被忽略的:Docker 容器或云服务器镜像。如果你是从云厂商的镜像创建实例,很多镜像在/etc/apt/apt.conf.d/下还有自己的配置片段,比如50cloud-init之类的。这些片段可能重新设置APT::Periodic::Unattended-Upgrade "1",覆盖掉你改的20auto-upgrades。所以关闭之后,记得再全局搜索一下:

grep -rn "Unattended-Upgrade" /etc/apt/apt.conf.d/

确保所有文件里都没有"1"出现。

4.2 如何确定是否还有定时器触发

在 18.04 里,systemctl list-timers会展示所有定时器,包括下次触发时间。这是我排查看日志最常用的命令之一。

如果看到apt-daily-upgrade.timer的状态是active (waiting),即使你刚才 disable 了,也可能是因为它被某些操作重新激活了。另外要注意,Ubuntu 18.04 的 apt 相关定时器会在系统安装后自动启用,如果你只是手动执行过一次apt upgrade,不会自动开启,但如果运行过apt install unattended-upgrades或者系统升级的大动作,可能会重新激活。

还有一个小技巧:systemctl list-timers | grep apt能看到每个定时器的最后一次触发时间和下次触发时间。如果下次触发时间还在一个小时内,说明它已经被调度了,赶紧再 stop 一次。

4.3 误删配置文件怎恢复

有次我图省事,直接删了/etc/apt/apt.conf.d/20auto-upgrades,以为删掉就彻底关掉。结果系统重启后,由于文件不存在,apt 的默认行为反而可能触发 unconfigured 状态,某些 dpkg 操作还会重新生成一个默认配置,里面又变成"1"。

实际上这个文件是apt包自带的,所以恢复方式很简单:

sudo apt install --reinstall apt

或者从原包中提取:

dpkg -L apt | grep 20auto-upgrades

如果文件丢了,也可以自己重新创建,内容就是我前面提到的那两行,改成"0"即可。不要删文件,改成"0"是最稳妥的。

注意:修改任何 apt 配置文件之前,都要养成备份的习惯。sudo cp /etc/apt/apt.conf.d/20auto-upgrades /etc/apt/apt.conf.d/20auto-upgrades.bak一行命令就能避免很多麻烦。

5. 影响范围分析与替代方案

5.1 关闭后系统的安全风险对应策略

关闭 unattended-upgrade 之后,系统失去了自动打补丁的能力。如果你只是图省事,关了就不管了,那系统可能长期处于"裸奔"状态。这是很多管理员容易掉进去的坑。

更合理的做法是建立一个手动更新提醒机制。你不需要每天跑一遍apt upgrade,只要有个提醒,比如每周定期登录检查一次。具体可以这样做:

apt list --upgradable

这条命令会列出所有可升级软件包。我习惯每周一上午跑一次,把输出存到日志里,然后手动执行sudo apt upgrade,在低峰期操作。

如果你闲麻烦,也可以保留 unattended-upgrade 的安全更新能力,但改为手动配置。比如在50unattended-upgrades里,明确定义只允许安全来源的更新,不启用自动重启,然后保留定时器,让它每天晚上只执行apt update,但不自动安装。具体操作是把Unattended-Upgrade::Allowed-Origins里不需要的 origin 注释掉。

5.2 与自动安全更新的取舍建议

关于"关不关"这个问题,我给几个基于实际场景的建议:

  • 个人笔记本/开发机:建议保留 unattended-upgrade,设置为只做安全更新。毕竟自己用,安全性和省心更重要。
  • 测试/暂存环境:可以完全关闭,方便复现生产环境的问题,避免环境差异。
  • 生产环境:除非你有非常成熟的自动化补丁流程和灰度发布机制,否则建议关闭自动安装,只保留手动安装。关闭后由运维定期窗口升级。

另外,如果你使用的云厂商提供安全补丁的镜像通道(比如很多云平台有"系统更新管理"界面),那你完全可以关闭系统内的 unattended-upgrade,交给云平台去管理。这一点在云服务器上尤其常见。

5.3 我自己的落地配置模板

最后分享一套我自己在 18.04 生产机上使用的模板。它不是一个"一键脚本",而是一套组合拳。

第一步,配置/etc/apt/apt.conf.d/20auto-upgrades:

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

第二步,禁用服务:

sudo systemctl disable --now apt-daily.timer sudo systemctl disable --now apt-daily-upgrade.timer sudo systemctl disable --now unattended-upgrades.service

第三步,在/etc/apt/apt.conf.d/50unattended-upgrades里保留允许自动更新的安全来源,但我不依赖它,因为前面的 "0" 已经让自动更新不触发了,这只是留着以后手动启用。

第四步,写一个简单的提醒脚本,放到/usr/local/bin/check-updates.sh:

#!/bin/bash # 简单检查可用更新数量并写入日志 apt update > /tmp/apt_update.log 2>&1 count=$(apt list --upgradable 2>/dev/null | wc -l) echo "$(date) -- $count upgradable packages" >> /var/log/updates.log

然后设置一个普通 cron,每周一早上运行一次。既不自动安装,也不会错过安全漏洞提醒。

这套方案运行了两年多,没有出现过一次因为自动更新导致的故障,补丁也能按时打上。如果你正好被 18.04 的自动更新坑过,不妨照着上面的步骤操作一遍。

最后分享一个小细节:Ubuntu 18.04 已经进入维护末期,如果条件允许,早点规划升级到 20.04 或 22.04。但即便停留在 18.04,也要把自动更新关掉,这比什么都重要。我在实际维护中还发现,关闭 unattended-upgrade 后系统负载更稳定了,特别是凌晨时段的磁盘 I/O 明显下降。这个收获算是一个意外之喜吧。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询