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:00Listing 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-gaListing 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 blocksInvestigate 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 || :
fiScriptlet 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 varThis 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 OKThe “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-agentIf 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)
systemdThis 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)
systemdThe 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.