Package Management on RHEL: dnf & rpm
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:
dnfinstalls and updates software from repositories.rpmasks 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:
dnf repolistrepo 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:
sudo dnf install nginxLast 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.
| Task | dnf command |
|---|---|
| Upgrade everything | sudo dnf upgrade |
| Check what would be upgraded | dnf check-update |
| Remove a package and unneeded dependencies | sudo dnf remove nginx |
| Search names and summaries | dnf search redis |
| Show details of a package | dnf info nginx |
| Which package provides a file or command | dnf provides /usr/bin/dig |
| List installed packages | dnf list --installed |
| Clean cached downloads | sudo 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:
rpm -qa | wc -l
rpm -qf /usr/bin/ssh
rpm -ql openssh-server | grep sbin
rpm -qc openssh-server612 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:
-qalists all installed packages.-qffinds the package that owns a file.-qllists a package's files.-qclists 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:
sudo rpm -V openssh-serverS.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:
sudo dnf history list --reverse | tail -n 3
sudo dnf history info 14
sudo dnf history undo 1413 | 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:
[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-shopThe 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:
dnf updateinfo list --security
sudo dnf upgrade --security
sudo dnf needs-restarting -rneeds-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:
- Install
dnf-automatic. - In
/etc/dnf/automatic.conf, setupgrade_type = securityandapply_updates = yes. - 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. Usednf install ./file.rpm. - Expecting a service to start after install. On RHEL, enable it and open the firewall yourself.
- Setting
gpgcheck=0to 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
.rpmpackages from BaseOS and AppStream, managed withdnf. dnf install,upgrade,remove,search,infoandprovidescover daily work. There is no separate refresh step.rpm -qa,-qf,-qland-qcquery installed packages;rpm -Vverifies files.dnf historylists and undoes transactions;dnf upgrade --securityapplies only security fixes.- Repositories are
.repofiles withgpgcheck=1.dnf versionlock(likeapt-mark hold) pins versions.
Exercise
You join a team that runs Rocky Linux 10. Write the commands for these tasks:
- Find which package provides the
semanagecommand, and install it. - Show which configuration files it installed.
- Apply only pending security updates.
- Check whether a reboot is needed.
- Lock the
nginxpackage at its current version.
Show solution
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... 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?
-qf (query file) names the package that installed a file.
2. Why should you prefer dnf install ./app.rpm over rpm -i app.rpm?
rpm installs only the one file; dnf handles dependencies from the repositories.
3. What does S.5....T. c /etc/ssh/sshd_config from rpm -V mean?
Letters mark differences and dots mean "same"; c marks a configuration file.
4. After sudo dnf install nginx on RHEL, why does the site not load?
RHEL leaves services stopped and firewalld closed until you act.
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
