Skip to main content
  1. Notes/
  2. RPM/

Investigate RPM's

Table of Contents
rpm - This article is part of a series.
Part 2: This Article

Investigate an RPM Package
#

This article explores various methods to investigate the contents and behavior of RPM (Red Hat Package Manager) packages. Understanding these techniques is crucial for system administrators and developers alike, allowing for deeper insight into how software is packaged and interacts with the system.

Listing targets
#

The first step in investigating an RPM package is to understand what files it contains and where they will be placed on the filesystem.

Normal listing
#

First, let’s download a regular package, qemu-guest-agent, using yumdownloader. This tool fetches the RPM file without installing it, allowing for examination before deployment.

[vagrant@localhost ~]$ yumdownloader qemu-guest-agent
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.schoemaker.systems
 * epel: ams.edge.kernel.org
 * extras: mirror.ams1.nl.leaseweb.net
 * updates: ams.edge.kernel.org
qemu-guest-agent-2.8.0-2.el7_5.1.x86_64.rpm                   | 150 kB  00:00:00

Listing targets after package
#

You can use rpm -qlp to list the content of a package. This command provides a preview of all the files that will be installed by the RPM and their target locations on the filesystem.

[vagrant@localhost ~]$ rpm -qlp qemu-guest-agent-2.8.0-2.el7_5.1.x86_64.rpm
/etc/qemu-ga
/etc/qemu-ga/fsfreeze-hook
/etc/qemu-ga/fsfreeze-hook.d
/etc/sysconfig/qemu-ga
/usr/bin/qemu-ga
/usr/lib/systemd/system/qemu-guest-agent.service
/usr/lib/udev/rules.d/99-qemu-guest-agent.rules
/usr/share/doc/qemu-guest-agent-2.8.0
/usr/share/doc/qemu-guest-agent-2.8.0/COPYING
/usr/share/doc/qemu-guest-agent-2.8.0/README
/usr/share/man/man8/qemu-ga.8.gz
/usr/share/qemu-kvm/qemu-ga
/usr/share/qemu-kvm/qemu-ga/fsfreeze-hook.d
/usr/share/qemu-kvm/qemu-ga/fsfreeze-hook.d/mysql-flush.sh.sample
/var/log/qemu-ga

Listing the raw content
#

Basically rpm’s are cpio files with extras so using rpm2cpio can achieve the same listing.

[vagrant@localhost ~]$ rpm2cpio qemu-guest-agent-2.8.0-2.el7_5.1.x86_64.rpm | cpio -t
./etc/qemu-ga
./etc/qemu-ga/fsfreeze-hook
./etc/qemu-ga/fsfreeze-hook.d
./etc/sysconfig/qemu-ga
./usr/bin/qemu-ga
./usr/lib/systemd/system/qemu-guest-agent.service
./usr/lib/udev/rules.d/99-qemu-guest-agent.rules
./usr/share/doc/qemu-guest-agent-2.8.0
./usr/share/doc/qemu-guest-agent-2.8.0/COPYING
./usr/share/doc/qemu-guest-agent-2.8.0/README
./usr/share/man/man8/qemu-ga.8.gz
./usr/share/qemu-kvm/qemu-ga
./usr/share/qemu-kvm/qemu-ga/fsfreeze-hook.d
./usr/share/qemu-kvm/qemu-ga/fsfreeze-hook.d/mysql-flush.sh.sample
./var/log/qemu-ga
1019 blocks

Investigate RPM scripting
#

Beyond just files, RPM packages often include scripts that are executed at various stages of the package’s lifecycle (installation, uninstallation, upgrade). These scripts handle tasks like starting services, creating users, or configuring system settings.

To view these scripts, use the rpm -q --scripts command.

[vagrant@localhost ~]$ rpm -q --scripts qemu-guest-agent
postinstall scriptlet (using /bin/sh):

if [ $1 -eq 1 ] ; then
        # Initial installation
        systemctl preset qemu-guest-agent.service >/dev/null 2>&1 || :
fi
preuninstall scriptlet (using /bin/sh):

if [ $1 -eq 0 ] ; then
        # Package removal, not upgrade
        systemctl --no-reload disable qemu-guest-agent.service > /dev/null 2>&1 || :
        systemctl stop qemu-guest-agent.service > /dev/null 2>&1 || :
fi
postuninstall scriptlet (using /bin/sh):

systemctl daemon-reload >/dev/null 2>&1 || :
if [ $1 -ge 1 ] ; then
        # Package upgrade, not uninstall
        systemctl try-restart qemu-guest-agent.service >/dev/null 2>&1 || :
fi

Scriptlet Arguments ($1):

The $1 variable within RPM scriptlets indicates the action being performed:

  • $1 -eq 1: Initial installation
  • $1 -eq 0: Package removal (not an upgrade)
  • $1 -ge 1: Package upgrade (or re-installation)

These conditional checks allow the scripts to behave differently depending on the context of the RPM operation.

Extracting RPM Package Contents
#

Sometimes, you might need to inspect the actual files within an RPM package without installing it on your system. This can be useful for security analysis, debugging, or simply examining configuration files.

The rpm2cpio command, combined with cpio, allows you to extract the contents of an RPM to a specified directory.

[vagrant@localhost ~]$ mkdir rpm_contents
[vagrant@localhost ~]$ cd rpm_contents/
[vagrant@localhost rpm_contents]$ rpm2cpio ../qemu-guest-agent-2.8.0-2.el7_5.1.x86_64.rpm | cpio -idv
./etc/qemu-ga
./etc/qemu-ga/fsfreeze-hook
./etc/qemu-ga/fsfreeze-hook.d
./etc/sysconfig/qemu-ga
./usr/bin/qemu-ga
./usr/lib/systemd/system/qemu-guest-agent.service
./usr/lib/udev/rules.d/99-qemu-guest-agent.rules
./usr/share/doc/qemu-guest-agent-2.8.0
./usr/share/doc/qemu-guest-agent-2.8.0/COPYING
./usr/share/doc/qemu-guest-agent-2.8.0/README
./usr/share/man/man8/qemu-ga.8.gz
./usr/share/qemu-kvm/qemu-ga
./usr/share/qemu-kvm/qemu-ga/fsfreeze-hook.d
./usr/share/qemu-kvm/qemu-ga/fsfreeze-hook.d/mysql-flush.sh.sample
./var/log/qemu-ga
1019 blocks
[vagrant@localhost rpm_contents]$ ls
etc  usr  var

This command extracts all files into the current directory, maintaining their original directory structure relative to the root (/).

Verifying RPM Package Integrity and Signatures
#

Before installing any package, it’s crucial to verify its integrity and authenticity. RPM provides mechanisms to check cryptographic signatures and file checksums.

Verifying a package file
#

To verify the signature of an RPM package, use rpm -K. This command checks the GPG signature to ensure the package hasn’t been tampered with and comes from a trusted source.

[vagrant@localhost ~]$ rpm -K qemu-guest-agent-2.8.0-2.el7_5.1.x86_64.rpm
qemu-guest-agent-2.8.0-2.el7_5.1.x86_64.rpm: digests signatures OK

The “digests signatures OK” output indicates that the package’s checksums match and its GPG signature is valid. If the signature is not trusted, you might need to import the GPG key of the repository or vendor.

Verifying installed packages
#

You can also verify already installed packages using rpm -V. This command compares the current state of the installed files with the metadata stored in the RPM database. It checks file sizes, MD5 sums, permissions, type, owner, group, and mtime.

[vagrant@localhost ~]$ rpm -V qemu-guest-agent

If no output is produced, it means the installed package matches its original state. Any discrepancies will be reported with a character code indicating the type of change (e.g., S for size, M for permissions, 5 for MD5 sum).

Understanding RPM Package Dependencies
#

RPM packages often depend on other packages to function correctly. Understanding these dependencies is vital for troubleshooting installation issues and managing your system.

Listing dependencies of a package file
#

You can inspect the dependencies of an RPM file before installation using rpm -qpR.

[vagrant@localhost ~]$ rpm -qpR qemu-guest-agent-2.8.0-2.el7_5.1.x86_64.rpm
/bin/sh
/usr/sbin/useradd
/usr/bin/systemctl
config(qemu-guest-agent) = 2.8.0-2.el7_5.1
libc.so.6(GLIBC_2.2.5)(64bit)
libdl.so.2()(64bit)
libglib-2.0.so.0()(64bit)
libgmodule-2.0.so.0()(64bit)
libpthread.so.0()(64bit)
librt.so.1()(64bit)
libsystemd.so.0()(64bit)
libsystemd.so.0(LIBSYSTEMD_209)(64bit)
libuuid.so.1()(64bit)
libuuid.so.1(UUID_1.0)(64bit)
rpmlib(BuiltinObsoletes) <= 4.2.2-1
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsXz) <= 5.2-1
rtld(GNU_HASH)
systemd

This output lists both shared library dependencies (e.g., libc.so.6) and package dependencies (e.g., systemd).

Listing dependencies of an installed package
#

For an already installed package, use rpm -qR.

[vagrant@localhost ~]$ rpm -qR qemu-guest-agent
/bin/sh
/usr/sbin/useradd
/usr/bin/systemctl
config(qemu-guest-agent) = 2.8.0-2.el7_5.1
libc.so.6(GLIBC_2.2.5)(64bit)
libdl.so.2()(64bit)
libglib-2.0.so.0()(64bit)
libgmodule-2.0.so.0()(64bit)
libpthread.so.0()(64bit)
librt.so.1()(64bit)
libsystemd.so.0()(64bit)
libsystemd.so.0(LIBSYSTEMD_209)(64bit)
libuuid.so.1()(64bit)
libuuid.so.1(UUID_1.0)(64bit)
rpmlib(BuiltinObsoletes) <= 4.2.2-1
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsXz) <= 5.2-1
rtld(GNU_HASH)
systemd

The output is similar to -qpR but reflects the dependencies that were resolved during the installation process.

Conclusion
#

Investigating RPM packages is a fundamental skill for anyone working with Red Hat-based Linux distributions. By utilizing commands like rpm -qlp, rpm -q --scripts, rpm2cpio, rpm -K, rpm -V, and rpm -qR, you can gain a comprehensive understanding of a package’s contents, behavior, integrity, and dependencies. This knowledge empowers you to better manage your system, troubleshoot issues, and ensure the security and stability of your software installations.

rpm - This article is part of a series.
Part 2: This Article