yum und dnf

Siehe auch

Verwandte Artikel
Offizielle Dokumentation

Software sollte soweit wie möglich per Paketmanager installiert und gepflegt werden. Das Werkzeug der Wahl auf RHEL-basierten Systemen ist DNF (Dandified YUM), der Nachfolger von YUM (Yellowdog Updater, Modified). YUM hat seine Wurzeln in Yellow Dog Linux und war bis RHEL 7 der Standard. Mit Fedora 22 löste DNF das alte YUM ab; in RHEL ist DNF seit Version 8 der Standard-Paketmanager. Das grafische Frontend unter GNOME ist GNOME Software, das über die Abstraktionsschicht PackageKit mit DNF spricht.

RHEL

Paketmanager

Version (Stand der jeweils letzten Minor)

Hinweis

7

yum

YUM 3.4.3 (7.9)

letzte YUM-3-Generation

8

dnf

DNF 4.7 (8.10)

yum ist ein Symlink auf dnf

9

dnf

DNF 4.14 (9.7)

yum ist ein Symlink auf dnf

10

dnf

DNF 4.20 (10.1)

yum bleibt Kompatibilitäts-Link; Nachfolger DNF5 (in Fedora bereits im Einsatz) in Vorbereitung

Die alten YUM-Pfade existieren auf RHEL 8 und neuer nur noch als Kompatibilitäts-Symlinks: /etc/yum.conf zeigt auf /etc/dnf/dnf.conf, /etc/yum/vars auf /etc/dnf/vars. Das Transaktions-Log liegt unter /var/log/dnf.log (nicht mehr /var/log/yum.log), der Paket-Cache unter /var/cache/dnf.

Bemerkung

Sofern nicht anders vermerkt, gelten die Kommandos in diesem Artikel für RHEL 8, 9 und 10. Wo etwas nur für bestimmte Versionen gilt (zum Beispiel das Modulsystem oder die versionierten Pakete), ist es markiert. Das yum/dnf Cheat Sheet dient als Schnellreferenz mit Versionsangabe pro Befehlsgruppe, die übrigen Abschnitte erklären die nicht-offensichtlichen Fälle.

Modules, Streams und Application Streams

Über die Major-Versionen hat sich mehrfach geändert, wie mehrere Versionen derselben Software angeboten werden. Hintergrund ist ein Zielkonflikt: RHEL garantiert über den rund zehnjährigen Lifecycle einen stabilen, eingefrorenen Userspace, Administratoren und Entwickler brauchen aber oft eine neuere oder eine bestimmte Version einer Sprachlaufzeit, Datenbank oder eines Webservers. Seit RHEL 8 ist die Distribution dafür in zwei Haupt-Repositories aufgeteilt: BaseOS mit den Kernkomponenten (Kernel, systemd, Core-Userspace) in genau einer Version, und AppStream mit der Anwendungsebene, in der mehrere Versionen angeboten werden.

Zur Begriffsklärung: AppStream ist der Name eines Repositories (seit RHEL 8). Application Streams ist dagegen das Konzept „mehrere Versionen einer Komponente mit jeweils eigenem Support-Lifecycle“. Wie dieses Konzept technisch umgesetzt wird, hat zwischen den Major-Versionen gewechselt.

RHEL 6 und 7: Paketgruppen plus Software Collections

Paketgruppen (definiert in comps.xml) gibt es seit jeher; sie sind nur eine benannte Liste von Paketen und treffen keine Aussage zur Version, im Repository liegt pro Paket genau eine Version. Wer eine andere Version brauchte, griff zu den Red Hat Software Collections (RHSCL), verfügbar für RHEL 6 (ab 6.4) und RHEL 7: Parallel-Installation nach /opt/rh, Aktivierung über scl enable, mit eigenem Pfad und eigener Umgebung, ohne die Basis-Tools des Systems zu ersetzen.

RHEL 8: Modularity

Ein Modul (zum Beispiel nodejs, php oder ruby) bietet mehrere Streams (Versionslinien wie nodejs:20 oder php:8.2) an. Ein Profil gibt den Use Case innerhalb eines Streams vor (minimal, common, development). Module Streams installieren in die normalen Systempfade und lösten damit die Software Collections ab. Die zentrale Einschränkung: Pro Modul ist immer nur ein Stream gleichzeitig aktiv, nodejs:18 und nodejs:20 lassen sich nicht parallel installieren. „enabled“-Streams zeigt dnf module list mit [e] an, „default“-Streams mit [d]; nicht jedes Modul hat einen Default. Ein Wechsel des aktiven Streams ist nur über dnf module reset (Auswahl verwerfen, dann neu installieren) oder dnf module switch-to (ab RHEL 8.6) möglich.

RHEL 9 und 10: versionierte Pakete

Ab RHEL 9 wird das Konzept der Application Streams überwiegend nicht mehr über Module umgesetzt, sondern über klassische, versionierte Pakete mit eigenem Paketnamen (zum Beispiel python3.11 neben python3.12, oder nodejs24 neben dem Default nodejs). Diese lassen sich parallel installieren, ganz ohne enable oder reset. Die Default-Version liefert die Distribution weiterhin unter dem schlichten Namen, auf RHEL 10 etwa python3 (3.12) oder postgresql (16). Das Feature bleibt also bestehen, nur der Liefermechanismus hat von Module Streams zu versionierten Paketen gewechselt.

Bemerkung

Das gesamte Modulsystem ist deprecated und wird in einer zukünftigen Version von DNF5 entfernt. Ab RHEL 10 liefern die First-Party-Repositories und das EPEL keine Module mehr mit.

Aspekt

Paketgruppen

Module Streams (RHEL 8)

Versionierte Pakete (RHEL 9 / 10)

Zweck

Pakete bündeln

mehrere Versionen plus eigener Lifecycle

mehrere Versionen plus eigener Lifecycle

Versionsauswahl

nein, eine Version pro Repository

ja, über den Stream

ja, über den Paketnamen

Parallel installierbar

nein

nein, nur ein Stream aktiv

ja

Mehr Versionen über

Software Collections (/opt/rh)

im Systempfad

im Systempfad

Bedienung

dnf group install

dnf module enable / install

dnf install <name><version>

Komplexität

niedrig

hoch (enable / reset / switch-to)

niedrig

Eine Paketgruppe und ein Modul-Profil sind verwandt, aber nicht dasselbe: Die Gruppe sagt „diese Pakete zusammen“, das Profil sagt dasselbe, jedoch gebunden an eine konkrete Versionslinie.

yum/dnf Cheat Sheet

Die Versionsangaben hinter den Kommentaren geben an, auf welchen RHEL-Versionen das jeweilige Kommando sinnvoll ist.

# --- query (rhel8/9/10) ---
dnf search httpd
dnf info httpd
dnf list httpd
dnf list --installed 'php*'
dnf provides '*/sar'                              # which package ships a file
dnf repolist --all
dnf repoquery --list httpd                        # list files in a package

# --- install / remove (rhel8/9/10) ---
dnf install httpd
dnf install httpd-2.4.62-1.el10                   # a specific version
dnf remove httpd
dnf --assumeyes --allowerasing install httpd      # allow replacing conflicting deps
dnf --downloadonly --downloaddir=/root install httpd

# --- update (rhel8/9/10) ---
dnf check-update                                  # exit code 100 if updates are pending
dnf upgrade                                       # upgrade everything
dnf upgrade httpd                                 # upgrade a single package
dnf upgrade --security                            # security advisories only
dnf distro-sync                                   # align to what the repos currently offer

# --- package groups (rhel8/9/10) ---
dnf group list
dnf group info "Security Tools"
dnf group install "Security Tools"

# --- modules (rhel8/9; deprecated on rhel10, no modules shipped) ---
dnf module list
dnf module list nodejs
dnf module install nodejs:20/minimal
dnf module reset nodejs                           # drop the stream selection
dnf module switch-to nodejs:22                    # switch stream (rhel 8.6+)

# --- versioned application streams (rhel9/10) ---
dnf install python3.12                            # in parallel to python3.11
dnf install nodejs24                              # next to the default nodejs

# --- repositories (rhel8/9/10, needs dnf-plugins-core) ---
dnf config-manager --add-repo https://example.com/repo.repo
dnf config-manager --set-disabled epel
dnf config-manager --set-enabled epel
dnf --enablerepo epel install ntfs-3g            # one-off, without enabling permanently

# --- transactions (rhel8/9/10) ---
dnf history
dnf history info 6
dnf history undo 5

# --- cleanup (rhel8/9/10) ---
dnf clean all                                     # cache lives in /var/cache/dnf

Pakete installieren und entfernen

Ein Paket installieren oder gezielt eine bestimmte Version:

dnf install nano
dnf install nano-8.3-1.el10

Nur herunterladen, ohne zu installieren. Wird der Download abgebrochen und erneut gestartet, beginnt er wieder von vorne:

dnf --downloadonly --downloaddir=/root install nano

Installiert ein Paket und erlaubt DNF dabei, störende (meist neuere) Bibliotheksversionen zu entfernen und durch passende zu ersetzen:

dnf --assumeyes --allowerasing install nano

Eine neuere Applikation aus einem fremden Repository installieren, das mit den RHEL-Repositories kollidiert. Im Beispiel werden alle Repos deaktiviert, zwei externe aktiviert und PHP aus letzteren bezogen:

dnf --assumeyes --disablerepo='*' --enablerepo=remi-php82,remi install php

Ein Repo gezielt ausschliessen, damit ein Paket garantiert nicht von dort kommt:

dnf --assumeyes --disablerepo=epel --allowerasing install openvas

Paket entfernen:

dnf remove fail2ban

Bemerkung

Fast alle Pakete sind so gebaut, dass ein dnf remove angepasste Konfigurationsdateien nicht entfernt. Siehe rpmnew- und rpmsave-Dateien.

Bemerkung

Die Option --assumeyes (kurz -y) beantwortet die Rückfrage Is this ok [y/N] automatisch mit „Yes“.

Updates

Prüfen, ob Updates vorliegen. dnf check-update liefert den Exit-Code 100, wenn Updates anstehen, sonst 0:

dnf check-update
dnf check-update kernel
dnf check-update | grep --ignore-case 'httpd\|php\|mariadb\|curl'

Alles aktualisieren, oder nur ein einzelnes Paket:

dnf upgrade
dnf upgrade httpd

Bereits installierte Software auf eine festgelegte Version anheben:

dnf upgrade openvpn-2.6.12-1.el10

dnf distro-sync führt eine echte Transaktion aus (mit Rückfrage) und bringt jedes installierte Paket auf genau die Version, die die aktivierten Repos anbieten. Anders als dnf upgrade wirkt das in beide Richtungen: ältere Pakete werden hochgezogen, aber auch Pakete, die neuer als der Repo-Stand sind, heruntergestuft. Nützlich nach einem Repo-Wechsel:

dnf distro-sync

Wer nur sicherheitskritische Updates einspielen möchte (zum Beispiel im Rahmen von Common Criteria), nutzt die eingebaute Errata-Auswertung. Ein separates Plugin ist auf DNF nicht nötig:

dnf updateinfo                          # summary of pending advisories
dnf updateinfo list --security          # list security advisories
dnf upgrade --security                  # apply security advisories only
dnf upgrade --sec-severity=Critical     # only critical ones

Automatische Updates

Für unbeaufsichtigte Updates bringt RHEL dnf-automatic mit. Es läuft über einen systemd-Timer und ersetzt selbstgebaute Cron-Konstrukte.

dnf install dnf-automatic

Das Verhalten steuert /etc/dnf/automatic.conf:

/etc/dnf/automatic.conf
[commands]
# default, security, security-severity:Critical, bugfix, ...
upgrade_type = security
# download only (no), or download and install (yes)
apply_updates = yes

Timer aktivieren und starten:

systemctl enable --now dnf-automatic.timer

Welche Dienste oder ob ein Reboot nach einem Update fällig sind, zeigt needs-restarting (Paket yum-utils bzw. dnf-utils):

dnf install yum-utils

needs-restarting --services      # affected systemd services only
needs-restarting --reboothint    # return code <> 0: reboot required (e.g. kernel update)

Warnung

Automatisches Installieren von Updates und insbesondere automatische Reboots gehören auf Produktivsystemen nur in vereinbarte Wartungsfenster.

Verteilte Updates an unterschiedlichen Tagen

Prämisse: Produktivsysteme sollen Ende Woche genau dieselben Updates erhalten wie die Testsysteme Anfang Woche.

  1. Den DNF-Cache auf den Produktivmaschinen „einfrieren“:

    /etc/dnf/dnf.conf
    metadata_expire=never
    keepcache=True
    metadata_timer_sync=0
    
  2. Auf den Produktivmaschinen den Cache erzeugen und die Updates herunterladen. Das muss zum selben Zeitpunkt geschehen, an dem die Testserver ihre Updates beziehen:

    dnf makecache --refresh
    dnf upgrade --assumeyes --downloadonly --setopt=metadata_timer_sync=0
    
  3. Auf den Produktivmaschinen Ende Woche die heruntergeladenen Updates installieren:

    dnf upgrade --cacheonly
    

Downgrade und Undo

Ein Downgrade funktioniert nur bei Paketen, die in genau einer Version installiert sind, also beispielsweise nicht beim Kernel, bei glibc, SELinux oder D-Bus.

Warnung

Downgrades auf Produktivsystemen nur durchführen, wenn ein Backup des Systems vorhanden ist.

Den letzten Update-Vorgang als Ganzes rückgängig machen:

# find the transaction id
dnf history
# inspect what that transaction changed
dnf history info 277
# roll it back
dnf history undo 277

Gezielt auf eine bestimmte ältere Version zurückgehen:

dnf list --showduplicates httpd
dnf downgrade httpd-2.4.62-1.el10

Liefert der Downgrade Only Upgrade available on package ..., wurde die alte Version aus den aktiven Repos entfernt (typisch nach dem End-of-Life einer Minor-Version). In dem Fall hilft ein Archiv- bzw. Vault-Repository, das die alten Stände vorhält.

Scheitert der Downgrade an Abhängigkeiten (DNF kann sie beim Downgrade nicht automatisch auflösen), müssen die abhängigen Pakete mit angegeben werden:

dnf downgrade iptables iptables-libs

Damit das nächste dnf upgrade die Pakete nicht sofort wieder anhebt, gehört anschliessend ein Versions-Pin gesetzt, siehe Version-Pinning.

Kernel-Versionen verwalten

DNF hält standardmässig die letzten drei Kernel vor (installonly_limit = 3). Beim Update wird der jeweils älteste automatisch entfernt, sobald das Limit überschritten ist. Den Wert anpassen:

/etc/dnf/dnf.conf
installonly_limit=10

Jeder Kernel belegt auf /boot rund 70 bis 100 MB. Eine bestimmte Kernel-Version gezielt nachinstallieren:

dnf list --showduplicates kernel
dnf install kernel-6.12.0-55.el10

Alte Kernel über das jüngste Paar hinaus manuell entfernen:

dnf remove --oldinstallonly
# or explicitly, keeping the two newest:
dnf remove $(dnf repoquery --installonly --latest-limit=-2 --quiet)

Version Pinning

Das Thema hat eine eigene Seite spendiert bekommen: Version-Pinning.

Repositories

Repos aktivieren und deaktivieren

Kurzfristig ein sonst deaktiviertes Repo nutzen (Beispiel EPEL):

dnf --enablerepo epel install ntfs-3g

Ein Repo dauerhaft deaktivieren, drei Wege:

  1. dnf config-manager --set-disabled epel

  2. in der .repo-Datei enabled=1 auf enabled=0 setzen

  3. mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.disabled

Jede andere Dateiendung als .repo führt dazu, dass die Datei von DNF ignoriert wird.

Aufbau einer Repo-Konfigurationsdatei

Ein Beispiel für eine minimale Repository-Konfiguration:

/etc/yum.repos.d/internal.repo
[inhouse]
name=my internal repo
baseurl=http://mirror.example.com/$releasever/$basearch/
gpgcheck=0

$releasever, $basearch und weitere Variablen werden zur Laufzeit aufgelöst.

dnf-Variablen anzeigen

Eigene Variablen liegen als Dateien unter /etc/dnf/vars/. Die aktuell aufgelösten Werte zeigt die DNF-Python-API. Auf RHEL 9 und 10 über python3, auf RHEL 8 über /usr/libexec/platform-python (dort ist python3 nicht zwingend installiert):

# RHEL 9/10
python3 -c 'import dnf, json; db = dnf.dnf.Base(); print(json.dumps(db.conf.substitutions, indent=2))'
# RHEL 8
/usr/libexec/platform-python -c 'import dnf, json; db = dnf.dnf.Base(); print(json.dumps(db.conf.substitutions, indent=2))'
{
  "arch": "x86_64",
  "basearch": "x86_64",
  "releasever": "10",
  "releasever_major": "10",
  "releasever_minor": "1"
}

Die Schlüssel releasever_major und releasever_minor gibt es ab RHEL 9; auf RHEL 8 liefert die API nur arch, basearch und releasever.

Verhalten bei Repo-Änderungen

Angenommen, MariaDB-server wurde aus Repo A installiert, und dnf info MariaDB-server zeigt erwartungsgemäss an, dass das Paket aus Repo A stammt. Nun wird Repo A entfernt und ein anderes Repo B aktiviert, mit neuer Download-URL und anderen (neueren) Versionen von MariaDB-server. Was passiert beim nächsten dnf upgrade?

DNF zieht das Paket aus dem neuen Repo B und aktualisiert es, unabhängig davon, woher es ursprünglich stammte. Massgeblich ist allein, dass der Paketname übereinstimmt.

GPG-Key-Rotation

Tauschen die Maintainer den GPG-Key eines Repos aus (aus Sicherheits- oder Altersgründen), lassen sich auf einer Maschine, die bereits Pakete aus dem Repo installiert hat, keine weiteren Pakete mehr installieren oder aktualisieren. DNF meldet dann:

The GPG keys listed for the "ICINGA (stable release)" repository are already
installed but they are not correct for this package.
Check that the correct key URLs are configured for this repository.
Error: GPG check FAILED

Das passiert, wenn der Repo-Key als Datei abgelegt ist (im Beispiel definiert /etc/yum.repos.d/ICINGA-release.repo die Ablage unter /etc/pki/rpm-gpg/RPM-GPG-KEY-ICINGA). Es wird also der neue Key benötigt.

Wer LFOps/Ansible nutzt, deployt die Repo-Definitionen neu. Manuell (oder per Ansible-Ad-hoc-Kommando):

# download the new key
curl --output /etc/pki/rpm-gpg/RPM-GPG-KEY-ICINGA https://packages.icinga.com/icinga.key
# import the new key into the rpm database
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-ICINGA

Proxy und Caching

Outbound-Proxy für DNF in /etc/dnf/dnf.conf:

/etc/dnf/dnf.conf
# the proxy server - server:port
proxy=http://proxy.example.com:3128
# credentials for proxy connections
proxy_username=dnf
proxy_password=linuxfabrik

Heruntergeladene Pakete werden nach erfolgreicher Transaktion gelöscht (keepcache = 0). Wer den Cache behalten will, etwa um Pakete offline weiterzuverwenden, setzt:

/etc/dnf/dnf.conf
keepcache=1

Der Cache liegt unter /var/cache/dnf und lässt sich jederzeit per dnf clean all leeren, vor allem nach dem Deaktivieren oder Entfernen von Repos sinnvoll. Mit fastestmirror=1 in der dnf.conf wählt DNF aus einer Mirror-Liste den schnellsten Server (Default 0).

Troubleshooting

Error in PREIN scriptlet in rpm package xyz-7.0, xyz-6.0 was supposed to be removed but is not!

Das neue Paket ging davon aus, dass das alte entfernt wurde, was nicht passiert ist, oder die RPM-Datenbank und der DNF-Cache sind nicht mehr synchron. Das kann helfen:

# not critical
dnf clean all
rpm --rebuilddb

Falls das nicht reicht, hilft unter Umständen das Erzwingen, aber Obacht: Am Ende kann die Installation kaputt sein.

# be careful: this is done without any "are you sure" prompting
rpm --erase --noscripts --nodeps openvas-scanner-6.0.0-6930.el7.art.x86_64
cannot install both iptables-libs-1.8.10-4.el9_4 and iptables-libs-1.8.10-2.el9

Ausführlicher meldet DNF, dass ein installiertes Paket eine exakte Lib-Version verlangt, die das Update ersetzen würde:

package iptables-legacy-1.8.10-2.2.el9.x86_64 from @System requires
iptables-libs(x86-64) = 1.8.10-2.el9, but none of the providers can be installed

Abhilfe:

dnf upgrade --allowerasing
dnf install iptables
reboot