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-mark
command.
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 policy
command.
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/preferences
file.
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-mark
command 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.
Leave a Reply