EthicsComputerCourses
Join training +91 90532 10052

Package Management on RHEL: dnf & rpm

Linux · Lesson 22 of 45 Intermediate 9 min read Updated

By the end of this lesson you will be able to install, update, check and lock software on a Red Hat style Linux server. You will also undo a bad update safely.

Many companies in India run their servers on Red Hat Enterprise Linux (RHEL). Banks, telecoms and large IT service firms like it for its long support and vendor certification. Rocky Linux and AlmaLinux are free rebuilds of RHEL. If you only know Ubuntu, your first day on such a server can feel strange. There is no apt, files sit in different places, and packages have different names.

This lesson teaches the Red Hat family's two package tools:

  • dnf installs and updates software from repositories.
  • rpm asks questions about installed packages and checks them.

You saw a small comparison table in Package Management: apt, snap & flatpak. Here you will go further, with repositories, security updates, history and version locks. Examples use Rocky Linux 10, which matches RHEL 10 (released in May 2025).

Packages, repositories and names

An RPM package is a .rpm file. It holds a program's files plus metadata, which is information about the package: its version, what it depends on, and scripts to run on install. Think of a courier parcel. The box holds the goods, and the label on top lists the sender, contents and handling notes.

A full package name has the form name-version-release.architecture. For example: openssh-clients-9.9p1-7.el10.x86_64. The el10 part means it was built for Enterprise Linux 10. Some packages also have an epoch, written as 2: before the version. A vendor adds an epoch when it changes its numbering, so the newer package still counts as newer.

A repository is an online store of packages that dnf downloads from. RHEL 10 and its rebuilds split their main repositories in two:

  • BaseOS holds the core operating system.
  • AppStream holds applications, languages and databases.

List the enabled repositories with:

Terminal
dnf repolist
Output
repo id                         repo name
appstream                       Rocky Linux 10 - AppStream
baseos                          Rocky Linux 10 - BaseOS
extras                          Rocky Linux 10 - Extras

On real RHEL, these repositories only work after you register the server with a Red Hat subscription (sudo subscription-manager register). Red Hat offers a no-cost Developer subscription for individual learning. Check its current terms on the Red Hat site.

Everyday dnf commands

With apt, you run a separate step to refresh the package lists. dnf does not need this. It refreshes repository data by itself when the data is old. Installing looks familiar:

Terminal
sudo dnf install nginx
Output
Last metadata expiration check: 0:41:12 ago on Mon 02 Nov 2026 09:20:44 AM IST.
Dependencies resolved.
================================================================================
 Package               Arch        Version               Repository       Size
================================================================================
Installing:
 nginx                 x86_64      2:1.26.3-1.el10       appstream        33 k
Installing dependencies:
 nginx-filesystem      noarch      2:1.26.3-1.el10       appstream        11 k
...
Transaction Summary
================================================================================
...
Is this ok [y/N]: y

dnf shows the whole transaction, meaning every change it is about to make. Then it asks before doing it. In scripts, add -y to answer yes automatically. Version numbers on your system will differ from these outputs.

One big difference from Ubuntu: RHEL does not start or enable a service when you install it. The firewall also blocks it until you open the port. So you must run sudo systemctl enable --now nginx and open HTTP in firewalld. Firewalls: nftables, firewalld & iptables shows how.

Taskdnf command
Upgrade everythingsudo dnf upgrade
Check what would be upgradeddnf check-update
Remove a package and unneeded dependenciessudo dnf remove nginx
Search names and summariesdnf search redis
Show details of a packagednf info nginx
Which package provides a file or commanddnf provides /usr/bin/dig
List installed packagesdnf list --installed
Clean cached downloadssudo dnf clean all

dnf provides is especially useful. When a command is missing, it tells you which package to install. For example, searching for /usr/bin/dig points to bind-utils. You would never guess that name from Ubuntu's dnsutils.

Querying with rpm

rpm works directly with installed packages and .rpm files. It does not use repositories. Use it to ask questions:

Terminal
rpm -qa | wc -l
rpm -qf /usr/bin/ssh
rpm -ql openssh-server | grep sbin
rpm -qc openssh-server
Output
612
openssh-clients-9.9p1-7.el10.x86_64
/usr/sbin/sshd
/etc/pam.d/sshd
/etc/ssh/sshd_config
...

Here is what each option does:

  • -qa lists all installed packages.
  • -qf finds the package that owns a file.
  • -ql lists a package's files.
  • -qc lists only its configuration files.

Do not install packages with rpm -i, because it does not fetch dependencies. If you have a downloaded .rpm file, use sudo dnf install ./file.rpm. Then dnf fetches the dependencies for you.

rpm -V verifies installed files against the package database. It shows which config files someone has changed. It can also reveal tampered programs:

Terminal
sudo rpm -V openssh-server
Output
S.5....T.  c /etc/ssh/sshd_config

Each letter marks a difference: S is size, 5 is checksum and T is modification time. A dot means that property matches. It works like a hostel warden checking a room against the inventory list. The c marks a configuration file, so this change is probably an administrator's edit. The same report for a file in /usr/sbin would be worth investigating.

History and undo

dnf records every transaction, and many can be reversed. This is a real safety net when an upgrade breaks something:

Terminal
sudo dnf history list --reverse | tail -n 3
sudo dnf history info 14
sudo dnf history undo 14
Output
13 | upgrade                  | 2026-10-30 09:12 | Upgrade        |   38
14 | install php-fpm          | 2026-11-02 10:01 | Install        |    6

history info shows exactly which packages a transaction changed. history undo performs the opposite transaction. Undoing an upgrade only works if the older versions are still in the repositories. Ubuntu 26.04's APT 3.1 gained similar apt history-list and apt history-undo commands.

Extra repositories, security updates and version locks

Third-party repositories are .repo files in /etc/yum.repos.d/. Always keep signature checking on with gpgcheck=1. The signature proves the packages really come from the publisher, like the seal on a medicine strip:

Text
[shop-tools]
name=Sharma Sweets internal tools
baseurl=https://repo.example.in/el10/$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.example.in/RPM-GPG-KEY-shop

The most common extra repository is EPEL (Extra Packages for Enterprise Linux). The Fedora project maintains it. On Rocky and AlmaLinux, sudo dnf install epel-release adds it. Many EPEL packages also need the CRB repository. Enable it with sudo dnf config-manager --set-enabled crb.

Security updates come with advisories, which are notes describing the fix. So you can list and apply only those updates:

Terminal
dnf updateinfo list --security
sudo dnf upgrade --security
sudo dnf needs-restarting -r

needs-restarting -r tells you whether a reboot is needed, for example after a kernel update. If so, it exits with code 1. To apply security updates automatically, follow these steps:

  1. Install dnf-automatic.
  2. In /etc/dnf/automatic.conf, set upgrade_type = security and apply_updates = yes.
  3. Run sudo systemctl enable --now dnf-automatic.timer.

A version lock stops a package from being upgraded. You might lock a database during an important sale week, such as Diwali. Install the plugin with sudo dnf install python3-dnf-plugin-versionlock. Then run sudo dnf versionlock add mariadb-server. versionlock delete removes the lock. The Ubuntu equivalent is sudo apt-mark hold mariadb-server.

Common mistakes

  • Installing with rpm -i. Dependencies are not resolved. Use dnf install ./file.rpm.
  • Expecting a service to start after install. On RHEL, enable it and open the firewall yourself.
  • Setting gpgcheck=0 to silence an error. You lose the proof that packages are genuine. Import the correct key instead.
  • Mixing many third-party repositories. Packages with the same name from different sources clash. Add only what you need.
  • Forgetting to reboot after kernel updates. Check with dnf needs-restarting -r.

Key points

  • RHEL, Rocky and AlmaLinux use .rpm packages from BaseOS and AppStream, managed with dnf.
  • dnf install, upgrade, remove, search, info and provides cover daily work. There is no separate refresh step.
  • rpm -qa, -qf, -ql and -qc query installed packages; rpm -V verifies files.
  • dnf history lists and undoes transactions; dnf upgrade --security applies only security fixes.
  • Repositories are .repo files with gpgcheck=1. dnf versionlock (like apt-mark hold) pins versions.

Exercise

You join a team that runs Rocky Linux 10. Write the commands for these tasks:

  1. Find which package provides the semanage command, and install it.
  2. Show which configuration files it installed.
  3. Apply only pending security updates.
  4. Check whether a reboot is needed.
  5. Lock the nginx package at its current version.
Show solution
Terminal
dnf provides '*/semanage'
sudo dnf install policycoreutils-python-utils
rpm -qc policycoreutils-python-utils
sudo dnf upgrade --security
sudo dnf needs-restarting -r
sudo dnf install python3-dnf-plugin-versionlock
sudo dnf versionlock add nginx
Output
...
Reboot is required to fully utilize these updates.
More information: https://access.redhat.com/solutions/27943
Adding versionlock on: nginx-2:1.26.3-1.el10.*

dnf provides accepts a wildcard path when you do not know the full location. It reports policycoreutils-python-utils, the package you will need in SELinux & AppArmor. rpm -qc may print nothing if the package has no configuration files. Here needs-restarting -r says a reboot is required, so schedule one at a quiet time.

Quick Quiz

1. Which command shows which package owns /usr/bin/ssh on Rocky Linux?

2. Why should you prefer dnf install ./app.rpm over rpm -i app.rpm?

3. What does S.5....T. c /etc/ssh/sshd_config from rpm -V mean?

4. After sudo dnf install nginx on RHEL, why does the site not load?

Learn Linux with a mentor

Free lessons get you started. Our Ethical Hacking & Cyber Security training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call