Wie man Paket- und Kernel-Updates in Debian / Ubuntu blockiert

APT ist wahrscheinlich das nützlichste Tool für einen Linux-Benutzer. Du kannst jede Software/jedes Paket auf deinem Linux-System mit einem einzigen Befehl installieren, aktualisieren und entfernen. Aber manchmal brauchst du eine genaue Kontrolle darüber, welche Pakete du installieren oder upgraden willst und welche Pakete nicht automatisch upgegradet werden sollen. Warum solltest du das tun wollen? Manchmal stellst du fest, dass die aktualisierte Version eines Pakets fehlerhaft ist. Du willst nicht, dass dieses Paket beim nächsten Mal, wenn du sudo apt upgrade aufrufst, aktualisiert wird. Und es ist mühsam, jedes Paket einzeln zu aktualisieren.

In dieser Anleitung erfährst du, wie du bestimmte Pakete von der Installation oder Aktualisierung ausschließt und wie du bestimmte Versionen von Paketen oder Kerneln von der Installation ausschließt.

Hinweis: Es kann leicht passieren, dass du nach einiger Zeit vergisst, welche Pakete du zurückgehalten hast, selbst wenn es fehlerfreie Versionen davon gibt. Bleib also wachsam, denn wenn du Pakete zu lange zurückhältst, kann das zu Sicherheitsproblemen führen.

Wir werden hier zwei Methoden besprechen. Die erste Methode blockiert alle Installationen und Upgrades für ein bestimmtes Paket. Die zweite Methode bietet eine genauere Kontrolle und ermöglicht es dir, bestimmte Versionen eines Pakets zu blockieren.

Voraussetzungen

  • Ein Server mit Ubuntu oder Debian Betriebssystem. Für diesen Lehrgang wurde Ubuntu 22.04 verwendet, aber die Befehle hier sollten auch mit anderen Debian-basierten Betriebssystemen und älteren Versionen funktionieren.
  • Ein Nicht-Root-Benutzer mit sudo-Rechten.

Methode 1 (apt-mark)

Um zu verhindern, dass ein Paket installiert, aktualisiert oder entfernt wird, können wir den Befehl apt-mark verwenden.

Wenn du ein Paket, z.B. htop, daran hindern willst, installiert, aktualisiert oder entfernt zu werden, verwende den folgenden Befehl.

$ sudo apt-mark hold htop

Du solltest die folgende Ausgabe sehen.

htop set on hold.

Das gesperrte Paket bleibt auf der gleichen Version, auch wenn du dein System aktualisierst. Dies ist besonders nützlich, um Grafiktreiber zurückzuhalten.

Um die Sperrung des Pakets aufzuheben, gibst du den folgenden Befehl ein.

$ sudo apt-mark unhold htop

Du solltest die folgende Ausgabe sehen.

Canceled hold on htop.

Dabei gibt es eine wichtige Einschränkung. Das Paket wird zwar nicht automatisch aktualisiert, wenn du den Befehl sudo apt upgrade verwendest oder das System aktualisierst, du kannst das Paket aber trotzdem manuell entfernen. sudo apt remove <package> funktioniert auch bei zurückgehaltenen Paketen.

Diese Methode verhindert nur, dass sie automatisch geändert werden. Wenn du sie in der Warteschleife hältst, bleiben sie auf jeden Fall in ihrer aktuellen Version, es sei denn, du entscheidest dich, sie manuell zu entfernen.

Methode 2 (/etc/apt/preferences)

Bei dieser Methode bearbeitest du die Datei /etc/apt/preferences, in der du genau festlegen kannst, welche Version welches Pakets aus welchem Repository installiert wird.

Jedes Paket erhält eine numerische Priorität, anhand derer APT entscheidet, ob das Paket installiert werden soll oder nicht und wenn ja, aus welchem Repository es geholt werden soll.

Lass uns zum Beispiel einige Details über das Paket nginx überprüfen. Gib den folgenden Befehl ein.

$ apt-cache policy nginx

Du solltest eine ähnliche Ausgabe sehen.

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

Du wirst sehen, dass es zwei Repositories gibt, aus denen nginx installiert wird. Das erste ist das Repository von Ubuntu und das zweite ist das Repository von nginx.

Du kannst sehen, dass in allen Repositories 500 steht. Diese Zahl gibt die Priorität des Pakets an. Da sie für alle Repositories gleich ist, sind die Chancen, dass nginx aus einem der Repositories kommt, gleich groß. Wie entscheidet das System nun, welches Paket es auswählt? Es wählt die höchste Version, die es gibt. In diesem Fall ist das die Version 1.22.1. Für Ubuntu lautet die vollständige Versionsnummer 1.22.1-1~jammy.

Wenn du nicht auf die Version 1.22.1 upgraden willst und sie blockieren möchtest, musst du die Datei /etc/apt/preferences bearbeiten.

Öffne die Datei mit dem nano-Editor.

$ sudo nano /etc/apt/preferences

Dieser Befehl hilft dir auch dabei, die Datei zu erstellen, wenn sie vorher nicht im System vorhanden war.

Füge den folgenden Code in die Datei ein.

Package: nginx
Pin: version 1.22.1-1~jammy
Pin-Priority: -1

Wenn du die Priorität auf einen niedrigeren Wert als 0 setzt, wird das Paket nicht installiert. Wenn du willst, dass ein Paket immer installiert wird, setze seine Priorität auf 1000 oder höher.

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.

Lass uns das Paket noch einmal überprüfen.

$ apt-cache policy nginx

Du wirst die folgende Ausgabe sehen.

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

Fällt dir ein Unterschied auf? Die Candidate Release Version ist von 1.22.1 auf 1.22.0 gesunken. Das bedeutet, dass die nächsthöhere Version, die das System nun installieren wird, 1.22.0 ist. Du wirst auch feststellen, dass -1 gegen die letzte Version geschrieben wurde, was bedeutet, dass das System diese Version überspringen sollte.

Eine Version überspringen, aber die andere zulassen

Du kannst mehrere Einträge für dasselbe Paket in der Datei hinzufügen. Füge zum Beispiel den folgenden Code in die Datei ein.

Package: nginx
Pin: version 1.22.1-1~jammy
Pin-Priority: -1

Package: nginx
Pin: version 1.20.2-1~jammy
Pin-Priority: 1000

Hier weisen wir das System an, die Version 1.22.1 zu überspringen, aber immer die Version 1.20.2 zu installieren.

Prüfen wir noch einmal mit dem Befehl 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

Der Versionskandidat hat sich nun auf 1.20.2 statt auf 1.22.0 verschoben.

Ändern der Repository-Präferenz

Betrachten wir einen weiteren Fall. Was ist, wenn wir die Installation von Nginx aus dem eigenen Repository verhindern und stattdessen das Ubuntu-Repository wählen wollen? Eine Möglichkeit wäre, das Nginx-Repository zu entfernen, aber du kannst auch wieder die Voreinstellungsdatei verwenden, um das Repository für dich zu wählen.

Gib den folgenden Code in die Datei ein.

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

Das Schlüsselwort release gibt nur die nächsthöhere Version an. o=nginx verweist auf den Ursprung des Pakets. Hier ist es nginx. Das bedeutet, dass das System das nginx-Paket nicht aus seinem Repository installieren soll. Eine andere Möglichkeit, das gleiche Ergebnis zu erzielen, ist die Verwendung des folgenden Codes.

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

Diesmal haben wir die Priorität 1000 des Ubuntu (jammy) Repository-Pakets gesetzt. Dadurch wird sichergestellt, dass Nginx immer aus dem Ubuntu-Repository installiert wird und nicht von irgendwo anders.

Du kannst nicht nur die Herkunft des Pakets angeben, sondern auch das Archiv, die Komponente, das Label und die Architektur des Pakets, die das System auswählen soll, indem du die folgenden Schlüsselwörter unter dem Abschnitt Pin verwendest.

  • c -> Komponente
  • a -> Archiv
  • o -> Herkunft
  • l -> Label
  • n -> Architektur

Bestimmte Kernel-Updates blockieren

Schauen wir uns an, wie wir bestimmte Kernel-Updates blockieren können. Liste alle kernelbezogenen Pakete auf deinem System auf.

$ dpkg -l "*$(uname -r)*" | grep kernel | awk '{print $2}'

Du wirst eine ähnliche Ausgabe sehen.

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

Die folgenden Methoden müssen für alle hier aufgelisteten Pakete wiederholt werden.

Methode 1 (apt-mark)

Prüfen wir zunächst, welche Version des Kernels aktiv ist. Dazu führst du den folgenden Befehl aus.

$ uname -r

Du solltest eine ähnliche Ausgabe sehen.

5.15.0-53-generic

Um zu verhindern, dass der Kernel weiter aktualisiert wird, können wir einfach den Befehl apt-mark verwenden.

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

Du solltest eine ähnliche Ausgabe sehen.

linux-image-5.15.0-53-generic set on hold.

Du kannst die gleiche Methode anwenden, um Kernel-Header zu blockieren, indem du das Paket linux-headers-$(uname -r) blockierst.

Methode 2 (/etc/apt/apt.conf.d/50unattended-upgrades)

Die zweite Methode betrifft die Datei /etc/apt/apt.conf.d/50unattended-upgrades.

Öffne sie zum Bearbeiten.

$ sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Scrolle nach unten zum Abschnitt Unattended-Upgrade::Package-Blacklist und bearbeite sie wie folgt.

Unattended-Upgrade::Package-Blacklist {
"linux-generic";
"linux-image-generic";
"linux-headers-generic";
"linux-modules-generic";
"linux-modules-extra-generic";
};

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.

Methode 3 (dpkg)

Um das Kernel-Upgrade mit dpkg durchzuführen, gib den folgenden Befehl ein. Mit diesem Befehl werden alle kernelbezogenen Pakete gleichzeitig angehalten.

$ for i in $(dpkg -l "*$(uname -r)*" | grep kernel | awk '{print $2}'); do echo $i hold | dpkg --set-selections; done

Um den Hold zu entfernen, gibst du den folgenden Befehl ein.

$ for i in $(dpkg -l "*$(uname -r)*" | grep kernel | awk '{print $2}'); do echo $i install | dpkg --set-selections; done

Methode 4 (/etc/apt/preferences)

Überprüfen wir zunächst die Details zur aktuellen Version des Kernels.

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

Du solltest die folgende Ausgabe sehen.

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

Auch wenn 5.15.0.53 zum Zeitpunkt der Erstellung dieser Anleitung die neueste Version des Kernels ist, gehen wir davon aus, dass die nächste Version bereits verfügbar ist (5.15.0.56 ist die aktuelle stabile Linux-Kernelversion).

Um die nächste Version des Kernels zu blockieren, gibst du den folgenden Code in die Datei /etc/apt/preferences.` ein.

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

Der obige Code verhindert, dass Ubuntu irgendwelche oder alle Aktualisierungen des Kernels installiert.

Du kannst die Methoden 2 und 3 für jedes reguläre Paket anwenden, nicht nur für den Kernel.

Fazit

Das war’s für diesen Lehrgang. Du solltest jetzt in der Lage sein, alle oder bestimmte Versionen von Paketen zu blockieren, die du nicht auf deinem Ubuntu- oder Debian-System installieren oder aktualisieren möchtest. Wenn du Fragen hast, schreibe sie unten in die Kommentare.

Das könnte dich auch interessieren …