CertGrid CertGrid
Hands-on Lab·CompTIA Linux+

Packages, repositories, and proving nothing changed

Domain 1 names package management and the two families answer every question differently. This guide installs the same tool on both, asks each what it installed and where it came from, verifies the files against the package record - including a deliberately tampered binary - and removes it, showing why Debian has two removal verbs and the RPM family has one.

System Management Guide 16 of 28 Beginner

One host of each family, because this is the domain where they diverge most - different tools, different queries, and a removal verb one of them does not have.
Server NameIP AddressOSRolesCPURAMHDD
LPLUS-A01192.168.0.73Ubuntu 26.04 LTSDebian-family host - apt, ufw, netplan, AppArmor2 Core4 GB50 GB
LPLUS-B01192.168.0.74AlmaLinux 10.2RPM-family host - dnf, firewalld, NetworkManager, SELinux2 Core4 GB50 GB

This guide includes

Use this when you need to know what a machine has installed, where a file came from, or whether a binary has been altered. This matters because rpm -V turns "has this been tampered with" into a one-command answer, and because removing a package on Debian without purge leaves its configuration behind.

Before you start

  1. What is installed, and where it came from

    An inventory, and the repositories behind it.

    bash Example session
    dpkg -l | grep -c "^ii"; echo "packages installed"; apt-cache policy | head -6765packages installedPackage files: 100 /var/lib/dpkg/status     release a=now 500 http://security.ubuntu.com/ubuntu resolute-security/multiverse amd64 Packages     release v=26.04,o=Ubuntu,a=resolute-security,n=resolute,l=Ubuntu,c=multiverse,b=amd64     origin security.ubuntu.comrpm -qa | wc -l; echo "packages installed"; dnf repolist | head -61266packages installedrepo id              repo nameappstream            AlmaLinux 10 - AppStreambaseos               AlmaLinux 10 - BaseOScrb                  AlmaLinux 10 - CRBepel                 Extra Packages for Enterprise Linux 10 - x86_64extras               AlmaLinux 10 - Extras

    Expected result764 packages on the Debian host with apt-cache policy showing the archives and their priorities - and 1267 on the RPM host, with baseos, appstream, crb, epel and extras.

    Success conditionYou can say what a machine has and which sources it trusts.

  2. Finding a package you do not have yet

    The query that searches the repository rather than the installed set.

    bash Example session
    sudo dnf provides '*/bin/tree' 2>/dev/null | grep -E "^(tree|Repo|Provide)" | head -5tree-2.1.0-8.el10.x86_64 : File system tree viewerRepo        : baseosapt-cache search --names-only '^tree$'; apt-cache policy tree | head -4tree - displays an indented directory tree, in colortree:  Installed: (none)  Candidate: 2.3.1-1  Version table:

    Expected resulttree-2.1.0-8.el10.x86_64 : File system tree viewer from dnf provides, with Repo : baseos - and on Debian, the package description plus Installed: (none) and Candidate: 2.3.1-1.

    Success conditionYou can find which package provides a command before installing anything.

  3. Installing, and what came with it

    One package, then the files and the ownership question.

    bash Example session
    sudo DEBIAN_FRONTEND=noninteractive apt-get install -y tree > /tmp/apt.log 2>&1; grep -E "newly installed|upgraded" /tmp/apt.log | tail -1; dpkg -l tree | tail -1 | awk '{print $1, $2, $3}'0 upgraded, 1 newly installed, 0 to remove and 54 not upgraded.ii tree 2.3.1-1sudo dnf install -y tree > /tmp/dnf.log 2>&1; grep -cE "^Installing|^  tree" /tmp/dnf.log; rpm -q tree2tree-2.1.0-8.el10.x86_64dpkg -L tree | grep -E "bin/|man" | head -4; dpkg -S $(command -v tree)/usr/bin/tree/usr/share/man/usr/share/man/man1/usr/share/man/man1/tree.1.gztree: /usr/bin/treerpm -ql tree | grep -E "bin/|man" | head -4; rpm -qf $(command -v tree)/usr/bin/tree/usr/share/man/man1/tree.1.gztree-2.1.0-8.el10.x86_64

    Expected result0 upgraded, 1 newly installed and ii tree 2.3.1-1 on Debian; tree-2.1.0-8.el10.x86_64 on the RPM host - then the binary and man page from each, and dpkg -S / rpm -qf naming the owning package.

    Success conditionYou can list what a package installed and find the package behind any file.

  4. What a package says about itself

    Metadata, and the field one family keeps that the other does not.

    bash Example session
    dpkg -s tree | grep -E "^(Package|Version|Depends|Description)" | head -4Package: treeVersion: 2.3.1-1Depends: libc6 (>= 2.38)Description: displays an indented directory tree, in colorrpm -qi tree | grep -E "^(Name|Version|License|Source RPM)" | head -4; rpm -q --changelog tree | head -2Name        : treeVersion     : 2.1.0License     : GPL-2.0-or-later AND LGPL-2.1-or-laterSource RPM  : tree-pkg-2.1.0-8.el10.src.rpm* Mon Nov 04 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 2.1.0-8- fix programming mistakes detected by static analysis

    Expected resultPackage: tree, Version: 2.3.1-1, Depends: libc6 (>= 2.38) on Debian - and on the RPM side the name, version, License: GPL-2.0-or-later, the Source RPM, and a changelog entry from Red Hat dated November 2024.

    Success conditionYou can read a package's metadata without unpacking it.

  5. Proving nothing has been tampered with

    A verified package, one byte removed, and the repair.

    bash Example session
    sudo rpm -V tree; echo "--- exit $? : silence means every file matches the package"--- exit 0 : silence means every file matches the packagesudo truncate -s -1 /usr/bin/tree && sudo rpm -V tree; echo "--- exit $? : S size, 5 checksum, T mtime"S.5....T.    /usr/bin/tree--- exit 1 : S size, 5 checksum, T mtimesudo dnf reinstall -y tree > /dev/null 2>&1; sudo rpm -V tree; echo "--- exit $? : reinstall restores the package's own copy, and the check is silent again"--- exit 0 : reinstall restores the package's own copy, and the check is silent again

    Expected resultSilence and exit 0 first - then after one byte is removed, S.5....T. /usr/bin/tree and exit 1 - and after a reinstall, silence and exit 0 again.

    Success conditionYou can prove a file still matches the package that shipped it.

  6. Removing it, and what each family leaves

    Two verbs on one family, one on the other.

    bash Example session
    sudo DEBIAN_FRONTEND=noninteractive apt-get install -y vsftpd > /dev/null 2>&1; dpkg -l vsftpd | tail -1 | awk '{print $1, $2, $3}'; head -2 /var/lib/dpkg/info/vsftpd.conffiles; echo "--- the conffiles, which decide what a remove leaves behind"ii vsftpd 3.0.5-0.4/etc/ftpusers/etc/init.d/vsftpd--- the conffiles, which decide what a remove leaves behindsudo DEBIAN_FRONTEND=noninteractive apt-get remove -y vsftpd > /dev/null 2>&1; dpkg -l vsftpd | tail -1 | awk '{print $1, $2}'; ls -l /etc/vsftpd.conf | awk '{print $5, $9}'; echo "--- rc: removed, configuration kept"rc vsftpd5850 /etc/vsftpd.conf--- rc: removed, configuration keptsudo DEBIAN_FRONTEND=noninteractive apt-get purge -y vsftpd > /dev/null 2>&1; dpkg -l vsftpd 2>&1 | tail -1; ls /etc/vsftpd.conf 2>&1 | tail -1; echo "--- and purge takes the configuration with it"dpkg-query: no packages found matching vsftpdls: cannot access '/etc/vsftpd.conf': No such file or directory--- and purge takes the configuration with itsudo dnf remove -y tree > /dev/null 2>&1; rpm -q tree; echo "--- exit $? : one verb, and no purge distinction to make"package tree is not installed--- exit 1 : one verb, and no purge distinction to make

    Expected resultvsftpd installed with conffiles /etc/ftpusers and /etc/init.d/vsftpd - then after remove, state rc with /etc/vsftpd.conf still on disk at 5,850 bytes - after purge, no package and no file - and on the RPM host, package tree is not installed from a single verb.

    Success conditionYou can remove a package completely, and know when you have not.

Troubleshooting

Official sources