How to block package and kernel updates in Debian

Estimated reading time: 5 min

Introduction

APT is probably the most useful tool for a Linux user. You can install, upgrade and remove any software/package from your Linux system with a single command. But sometimes occasions arise when you need granular control over which package you want to install or upgrade and which package to block from being upgraded automatically.

Why would you want to do this? Well, sometimes you find out that a package’s updated version is buggy. You don’t want that package to upgrade the next time you run sudo apt upgrade And it is a pain to upgrade each package individually.

In this tutorial, we will cover how to block certain packages from being installed or upgraded and how to block specific versions of packages or kernels from being installed.

Note: It is easy to forget what packages you have held after some time even when their bug free versions are out. So remain on alert as holding packages for long can introduce security issues.

We will discuss two methods here. The first method will block all installs and upgrades for a certain package. The second method offers more granular control which will allow you to block specific versions of a package.

Prerequisites

  • You need a Cloud VPS or Dedicated Server with Debian OS. Debian 10 was used for this tutorial but the commands here should work fine with older releases as well.
  • You need a non-sudo user to run the commands.

Method 1 (apt-mark)

To lock a package from being installed, updated or removed, we can use the apt-markcommand.

If you want to hold a package, for example, htop from being installed, updated or removed, use the following command.

$ sudo apt-mark hold htop

You should see the following output.

htop set on hold.

The locked package will remain on the same version even if you upgrade your system. This is especially useful for holding back graphics drivers.

To remove the hold on the package, just issue the following command.

$ sudo apt-mark unhold htop

You should see the following output.

Canceled hold on htop

There is an important caveat with this. While the package won’t get automatically upgraded on using the command sudo apt upgrade

or while upgrading the system, you can still remove the package manually. sudo apt remove <package> will still work on held packages.

This method only locks them from being changed automatically. Keeping them in the hold will keep them at their current versions no matter what unless you decide to remove them manually.

Method 2 (/etc/apt/preferences)

This method involves editing the /etc/apt/preferences file where you can specify exactly what version of which package from which repository is installed.

Each package gets a numeric priority based on which APT decides whether to install the package or not and if yes then from which repository it should pick it up from.

For example, let’s check some details about the nginx package. Issue the following command.

$ apt-cache policy nginx

You should see a similar output.

nginx:
  Installed: (none)
  Candidate: 1.17.5-1~buster
  Version table:
     1.17.5-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.4-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.3-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.2-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.1-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.14.2-2+deb10u1 500
        500 http://deb.debian.org/debian buster/main amd64 Packages
        500 http://security.debian.org/debian-security buster/updates/main amd64 Packages
        500 http://security.debian.org buster/updates/main amd64 Packages

You will see that there are two repositories from where nginx installs. First is Debian’s repository and the second one is nginx’s repository.

You can see 500 written against all repositories. This number specifies the package’s priority. Since it is the same for all repositories, the chances of nginx coming from either of the repositories are the same. So how will the system decide which package to pick? It will pick the highest version that there is. In this case, it is 1.17.5. For Debian, the complete version number becomes 1.17.5-1~buster.

Open the file in the nano editor.

$ sudo nano /etc/apt/preferences

This command will also help you create the file if it didn’t exist in the system previously.

Paste the following code in the file.

Package: nginx
Pin: version 1.17.5-1~buster
Pin-Priority: -1

Setting the priority to anything lower than 0 means that the package won’t get installed. If you want a package to always install, set its priority to 1000 or above.

Press Ctrl + X to exit and enter Y when prompted to save the file.

Let’s check the package again.

$ apt-cache policy nginx

You will see the following output.

nginx:
  Installed: (none)
  Candidate: 1.17.4-1~buster
  Version table:
     1.17.5-1~buster -1
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.4-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.3-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.2-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.1-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.14.2-2+deb10u1 500
        500 http://deb.debian.org/debian buster/main amd64 Packages
        500 http://security.debian.org/debian-security buster/updates/main amd64 Packages
        500 http://security.debian.org buster/updates/main amd64 Packages

Notice any difference? The Candidate release version has dropped from 1.17.5 to 1.17.4. This means the next higher version that the system will now install is 1.17.4. You will also notice -1 written against the latest version which means the system should skip that version.

Skip 1 version but allow the other one

You can add multiple entries for the same package in the file. For example, add the following code in the file.

Package: nginx
Pin: version 1.17.5-1~buster
Pin-Priority: -1

Package: nginx
Pin: version 1.17.3-1~buster
Pin-Priority: 1000

Here we are telling the system to skip version 1.17.5 but always install the 1.17.3 version.

Let’s check again using the apt-cache policycommand.

nginx:
  Installed: (none)
  Candidate: 1.17.3-1~buster
  Version table:
     1.17.5-1~buster -1
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.4-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.3-1~buster 1000
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.2-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.17.1-1~buster 500
        500 http://nginx.org/packages/mainline/debian buster/nginx amd64 Packages
     1.14.2-2+deb10u1 500
        500 http://deb.debian.org/debian buster/main amd64 Packages
        500 http://security.debian.org/debian-security buster/updates/main amd64 Packages
        500 http://security.debian.org buster/updates/main amd64 Packages

Candidate version has now shifted to 1.17.3 instead of 1.17.4.

Change the Repository preference

Let’s consider one more case. What if we want to block nginx from installing from its repository and choose the Debian repository instead. One way would be to remove the nginx repository but you can again use the preferences file to choose the repository for you.

Enter the following code in the file.

Package: nginx
Pin: release o=nginx
Pin-Priority: -1

The release keyword just specifies the next higher version. o=nginx refers to the origin of the package. Here it is nginx. This means the system shouldn’t install the nginx package from its repository. Another way to achieve the same result is to use the following code.

Package: nginx
Pin: release o=debian
Pin-Priority: 1000

This time we have set the priority 1000 of the Debian repository package. This will ensure that nginx is always installed from the Debian repository and not from anywhere else.

Not only you can specify the origin of the package, but you can also add the archive, component, label, and architecture of the package which the system should pick by using the following keywords under the Pin section.

  • c -> Component
  • a -> Archive
  • o -> Origin
  • l -> Label
  • n -> Architecture

Blocking Specific Kernel Updates

Let’s see how we can block specific kernel upgrades in Debian.

First, let’s check what version of the kernel is active. To do that, run the following command.

$ uname -r

You should see a similar output.

4.19.0-6-amd64

To prevent the kernel from being further upgraded, we can simply use the apt-mark command.

$ sudo apt-mark hold linux-image-$(uname -r)

You should see a similar output.

linux-image-4.19.0-6-amd64 set on hold.

Let’s check the details regarding the current version of the kernel first.

$ apt-cache policy linux-image-$(uname -r)

You should see the following output.

linux-image-4.19.0-6-amd64:
  Installed: 4.19.67-2+deb10u1
  Candidate: 4.19.67-2+deb10u1
  Version table:
 *** 4.19.67-2+deb10u1 500
        500 http://security.debian.org/debian-security buster/updates/main amd64 Packages
        500 http://security.debian.org buster/updates/main amd64 Packages
        100 /var/lib/dpkg/status
     4.19.67-2 500
        500 http://deb.debian.org/debian buster/main amd64 Packages

Even though 4.19.0.6 kernel is at its latest version (4.19.67) as of writing this tutorial, we are supposing that the next version is already out(4.19.81 is the current stable Linux kernel version).

To block the next version of the kernel, enter the following code in the /etc/apt/preferencesfile.

ackage: linux-image-4.19.0-6-amd64
Pin: version 4.19.81-2+deb10u1
Pin-Priority: -1

The above code will block Debian from installing only the 4.19.81 version. It won’t stop it from upgrading to the next higher version so you might need to keep the file updated with multiple versions if you want to block all those. Or you can simply use the apt-markcommand to hold all upgrades at once.

You can follow the same method for blocking kernel headers by blocking the linux-headers-$(uname -r) package.

Conclusion

Congratulations, you should now be able to block any or specific versions of any packages you don’t want to get installed or upgraded on your Debian system.

Was this article helpful?
Dislike 1
Views: 18169

Reader Interactions

Leave a Reply

Your email address will not be published. Required fields are marked *