如何在 Debian/Ubuntu 中阻止包和内核更新
在此页
- 先决条件
- 方法一(apt-mark)
- 方法 2 (/etc/apt/preferences)
- 跳过一个版本但允许另一个版本
- 更改存储库首选项
- 方法一(apt-mark)
- 方法 2 (/etc/apt/apt.conf.d/50unattended-upgrades)
- 方法 3 (dpkg)
- 方法 4 (/etc/apt/preferences)
APT 可能是 Linux 用户最有用的工具。您可以使用一条命令从您的 Linux 系统安装、升级和删除任何软件/软件包。但有时,您需要精细控制要安装或升级的包以及要阻止自动升级的包。你为什么想做这个?有时您会发现软件包更新版本有问题。您不希望下次运行
sudo apt upgrade
时升级该软件包。单独升级每个包很痛苦。本教程将介绍如何阻止安装或升级某些软件包,以及如何阻止安装特定版本的软件包或内核。
注意:很容易在一段时间后忘记您持有的软件包,即使它们的无错误版本已经发布。因此,请保持警惕,因为长时间持有包裹会带来安全问题。
我们将在这里讨论两种方法。第一种方法将阻止特定软件包的所有安装和升级。第二种方法提供更精细的控制,允许您阻止特定版本的包。
先决条件
- 装有 Ubuntu 或 Debian 操作系统的服务器。本教程使用 Ubuntu 22.04,但此处的命令也适用于其他基于 Debian 的操作系统和旧版本。
- 具有 sudo 权限的非根用户。
方法一(apt-mark)
要阻止安装、更新或删除包,我们可以使用
apt-mark
命令。如果要阻止安装、更新或删除软件包,例如
htop
,请使用以下命令。$ sudo apt-mark hold htop
您应该看到以下输出。
htop set on hold.
即使您升级系统,锁定的软件包也将保持相同的版本。这对于阻止图形驱动程序特别有用。
要取消对包的保留,请发出以下命令。
$ sudo apt-mark unhold htop
您应该看到以下输出。
Canceled hold on htop.
有一个重要的警告。虽然使用命令
sudo apt upgrade
或在升级系统时软件包不会自动升级,但您仍然可以手动删除软件包。sudo apt remove
仍然适用于保留的包。此方法仅锁定它们以防止自动更改。除非您决定手动删除它们,否则无论如何保留它们将使它们保持当前版本。
方法二(/etc/apt/preferences)
此方法涉及编辑
/etc/apt/preferences
文件,您可以在其中准确指定从哪个存储库安装哪个包的版本。每个包都有一个数字优先级,APT 根据该优先级决定是否安装该包,如果是,那么它应该从哪个存储库中获取它。
例如,让我们检查一些关于
nginx
包的细节。发出以下命令。$ apt-cache policy nginx
您应该会看到类似的输出。
nginx: Installed: (none) Candidate: 1.22.1-1~jammy Version table: 1.22.1-1~jammy 500 500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages 1.22.0-1~jammy 500 500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages 1.20.2-1~jammy 500 500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages 1.18.0-6ubuntu14.3 500 500 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages 500 http://us.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages 1.18.0-6ubuntu14 500 500 http://us.archive.ubuntu.com/ubuntu jammy/main amd64 Packages
您会看到 nginx 安装的位置有两个存储库。第一个是 Ubuntus 存储库,第二个是 nginxs 存储库。
您可以看到针对所有存储库写入 500。这个数字指定包的优先级。由于所有存储库都相同,因此 nginx 来自任一存储库的机会是相同的。那么系统将如何决定选择哪个包裹呢?它将选择现有的最高版本。在本例中,它是 1.22.1。对于 Ubuntu,完整的版本号变为 1.22.1-1~jammy。
如果你不想升级到 1.22.1 版本并且想阻止它,那么你需要编辑
/etc/apt/preferences
文件。在 nano 编辑器中打开文件。
$ sudo nano /etc/apt/preferences
如果该文件以前不存在于系统中,此命令还将帮助您创建该文件。
将以下代码粘贴到文件中。
Package: nginx Pin: version 1.22.1-1~jammy Pin-Priority: -1
将优先级设置为任何低于 0 的值意味着不会安装该软件包。如果您希望某个包始终安装,请将其优先级设置为 1000 或更高。
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
让我们再次检查包裹。
$ apt-cache policy nginx
您将看到以下输出。
nginx: Installed: (none) Candidate: 1.22.0-1~jammy Version table: 1.22.1-1~jammy -1 500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages 1.22.0-1~jammy 500 500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages 1.20.2-1~jammy 500 500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages 1.18.0-6ubuntu14.3 500 500 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages 500 http://us.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages 1.18.0-6ubuntu14 500 500 http://us.archive.ubuntu.com/ubuntu jammy/main amd64 Packages
注意到有什么不同吗?候选发布版本已从
1.22.1
降至1.22.0
。这意味着系统现在将安装的下一个更高版本是 1.22.0。您还会注意到针对最新版本编写的 -1,这意味着系统应该跳过该版本。跳过一个版本但允许另一个版本
您可以为文件中的同一个包添加多个条目。例如,将以下代码添加到文件中。
Package: nginx Pin: version 1.22.1-1~jammy Pin-Priority: -1 Package: nginx Pin: version 1.20.2-1~jammy Pin-Priority: 1000
这里我们告诉系统跳过版本
1.22.1
但始终安装1.20.2
版本。让我们使用
apt-cache policy
命令再次检查。nginx: Installed: (none) Candidate: 1.20.2-1~jammy Version table: 1.22.1-1~jammy -1 500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages 1.22.0-1~jammy 500 500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages 1.20.2-1~jammy 1000 500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages 1.18.0-6ubuntu14.3 500 500 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages 500 http://us.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages 1.18.0-6ubuntu14 500 500 http://us.archive.ubuntu.com/ubuntu jammy/main amd64 Packages
候选版本现已转移到
1.20.2
而不是1.22.0
。更改存储库首选项
让我们再考虑一种情况。如果我们想阻止 Nginx 从其存储库安装并选择 Ubuntu 存储库怎么办?一种方法是删除 Nginx 存储库,但您可以再次使用首选项文件为您选择存储库。
在文件中输入以下代码。
Package: nginx Pin: release o=nginx Pin-Priority: -1
release 关键字只是指定下一个更高版本。
o=nginx
指的是包的来源。这里是 nginx。这意味着系统不应该从其存储库安装 nginx 包。实现相同结果的另一种方法是使用以下代码。Package: nginx Pin: release o=jammy Pin-Priority: 1000
这次我们将 Ubuntu (
jammy
) 存储库包的优先级设置为 1000。这将确保 Nginx 始终从 Ubuntu 存储库安装,而不是从其他任何地方安装。您不仅可以指定包的来源,还可以在 Pin 部分下使用以下关键字添加系统应选择的包的存档、组件、标签和体系结构。
- c -> 组件
- a -> 存档
- o -> 起源
- l -> 标签
- n -> 架构
阻止特定的内核更新
让我们看看如何阻止特定的内核升级。列出系统上所有与内核相关的包。
$ dpkg -l "*$(uname -r)*" | grep kernel | awk '{print $2}'
您将看到类似的输出。
linux-headers-5.15.0-33-generic linux-image-5.15.0-33-generic linux-modules-5.15.0-33-generic linux-modules-extra-5.15.0-33-generic
对于此处获得的所有包,将需要重复以下方法。
方法一(apt-mark)
首先,让我们检查哪个版本的内核处于活动状态。为此,请运行以下命令。
$ uname -r
您应该会看到类似的输出。
5.15.0-53-generic
为了防止内核进一步升级,我们可以简单地使用
apt-mark
命令。$ sudo apt-mark hold linux-image-$(uname -r)
您应该会看到类似的输出。
linux-image-5.15.0-53-generic set on hold.
您可以按照相同的方法通过阻止
linux-headers-$ (uname -r)
包来阻止内核标头。方法二(/etc/apt/apt.conf.d/50unattended-upgrades)
第二种方法涉及
/etc/apt/apt.conf.d/50unattended-upgrades
文件。打开它进行编辑。
$ sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
向下滚动到
Unattended-Upgrade::Package-Blacklist
部分并进行如下编辑。Unattended-Upgrade::Package-Blacklist { "linux-generic"; "linux-image-generic"; "linux-headers-generic"; "linux-modules-generic"; "linux-modules-extra-generic"; };
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
方法 3 (dpkg)
要使用
dpkg
进行内核升级,请发出以下命令。该命令将同时保存所有与内核相关的包。$ for i in $(dpkg -l "*$(uname -r)*" | grep kernel | awk '{print $2}'); do echo $i hold | dpkg --set-selections; done
要删除保留,请使用以下命令。
$ for i in $(dpkg -l "*$(uname -r)*" | grep kernel | awk '{print $2}'); do echo $i install | dpkg --set-selections; done
方法四(/etc/apt/preferences)
让我们先检查有关当前内核版本的详细信息。
$ apt-cache policy linux-image-$(uname -r)
您应该看到以下输出。
linux-image-5.15.0-53-generic: Installed: 5.15.0-53.59 Candidate: 5.15.0-53.59 Version table: *** 5.15.0-53.59 500 500 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages 500 http://us.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages 100 /var/lib/dpkg/status
尽管
5.15.0.53
内核在编写本教程时是最新版本,但我们假设下一个版本已经发布(5.15.0.56
是当前稳定的 Linux 内核版本)。要阻止下一版本的内核,请在
/etc/apt/preferences
文件中输入以下代码。\Package: linux-image-5.15.0-53-generic linux-headers-5.15.0-33-generic linux-modules-5.15.0-33-generic linux-modules-extra-5.15.0-33-generic Pin: version 5.15.0-53.59 Pin-Priority: -1
上面的代码将阻止 Ubuntu 安装任何或所有内核升级。
您可以对任何常规包执行方法 2 和 3,而不仅仅是内核。
结论
这就是本教程的内容。您现在应该能够阻止您不想在 Ubuntu 或 Debian 系统上安装或升级的任何软件包的任何或特定版本。如果您有任何问题,请在下面的评论中发表。