Australian cloud for business software — built and run in Sydney since 2003

NetLeverage
NetLeverage

Checking a restored Linux server against its package records: rpm --verify, dpkg --verify and debsums

Technical article
Backup & Recovery

About this article: AI-assisted writing, reviewed against the cited sources. This is source research, not lab validation. Check the stated versions and your own requirements before making changes.

After a Linux server is restored, the first test is usually whether it boots and its services start. That matters, but it does not tell you whether the operating system files are the ones the packages installed. A partial restore, a restore that mixed recovery points, damaged media or an exclusion that caught a packaged directory can all leave a server that starts and then fails later (our reading).

Both main Linux package families keep a record of what each package installed. RPM-based systems (Red Hat Enterprise Linux, Fedora, SUSE and their relatives) use rpm --verify. Debian-based systems (Debian, Ubuntu) use dpkg --verify and the separate debsums tool. This guide explains what each one compares, how to read the results, and where each stops.

Why it matters

A restore can go wrong in ways that package checks are well placed to find (our reading):

  • Missing files. A path was excluded from the backup, or the restore skipped it.
  • Changed contents. A file came from a different recovery point than its neighbours, or the media was damaged.
  • Lost permissions or ownership. A file-level copy did not carry modes, owners or groups.

These checks do not establish complete recovery of:

  • data under /home, /srv, databases and application directories that no package owns;
  • configuration you wrote yourself in files no package installed;
  • a trustworthy pre-incident baseline when package records and files were restored or changed together. Some internal database inconsistencies can be detected, for example by dpkg --audit, but a consistent local record is not independent proof of its original correctness.

Knowing which side of that line each problem sits on decides what else your recovery test needs.

What rpm --verify compares

The rpm manual page describes verify mode as "comparing information about the installed files in the package with information about the files taken from the package metadata stored in the rpm database." It continues: "Among other things, verifying compares the size, digest, permissions, type, owner and group of each file. By default, only files with discrepancies are displayed."

Reading the output

Each reported line is "a string of 9 result characters", an optional attribute marker, then the file name. The manual explains the characters: "A single " . " (period) means the test passed, while a single " ? " (question mark) indicates the test could not be performed (e.g. file permissions prevent reading)." Any other character is a failure:

Character Meaning (from the manual)
S file size differs
M mode differs (includes permissions and file type)
5 digest (formerly MD5 sum) differs
D device major/minor number mismatch
L readlink path mismatch
U user ownership differs
G group ownership differs
T mtime differs
P capabilities differ

A file that is not present at all is reported as missing. The attribute letter tells you what kind of file it is; the two that matter most here are c for a configuration file and m, which the manual defines as "%missingok - file missing is not a verify failure". Documentation (d), licence (l) and ghost (g) files are also marked.

Ownership checks use local accounts

The manual notes, beside the options that skip ownership checks, that "only local passwd (5) and group (5) databases are consulted." On a server whose accounts come from a directory service, ownership results need care (our reading).

Scriptlets

Verify mode can run a package's own verification script. The manual lists --noscripts as "Don't execute the %verifyscript scriptlet (if any)." Running package scripts is more than reading files, so add --noscripts for a purely read-only check of a restored system (our recommendation).

Ignoring expected configuration changes

Configuration files are meant to be edited. The manual's examples show both views: rpm --verify --noconfig openssh-server verifies a package "ignoring changes in configuration", and rpm --verify --configfiles --verbose logrotate lists "all config files of the installed logrotate package, showing both changed and unchanged files."

What dpkg --verify compares

The dpkg manual says --verify "Verifies the integrity of package-name or all packages if omitted, by comparing information from the files installed by a package with the files metadata information stored in the dpkg database (since dpkg 1.17.2)."

The scope is narrower than rpm's. The manual states: "Currently the only functional check performed is an md5sum verification of the file contents against the stored value in the files database. It will only get checked if the database contains the file md5sum."

Reading the output

dpkg uses the rpm format by default, but the manual notes "that might change in the future", so scripts should name the format explicitly with --verify-format rpm. It prints "a line for every path that failed any check." Position by position:

  • Position 3, 5: "The digest check failed, which means the file contents have changed."
  • Position 2, M: a heuristic only. The manual says the mode check "can only be partially emulated via a very simple heuristic" and "will currently never succeed as it does not have enough information available."
  • Positions 1 and 4 to 9: "These checks are currently not supported, will always be ‘ ? ’."
  • missing appears "when the file is not present or its metadata cannot be fetched".
  • The attribute c means "The pathname is a conffile."

The practical consequence: on Debian and Ubuntu, dpkg --verify tells you about changed contents and missing files, but not about lost owners or permissions (our reading of the manual). A restore that flattened every file to root ownership would not show up in this check.

dpkg --audit

dpkg --audit checks the database itself. The manual says it "searches for packages that have been installed only partially on your system or that have missing, wrong or obsolete control data or files." It suggests fixes, which you should read rather than run on a restored system until you know the cause (our recommendation).

What debsums adds

debsums is a separate Debian package. Its manual describes it as checking "installed Debian package files against MD5 checksum lists from /var/lib/dpkg/info/*.md5sums." Useful options:

  • -s (silent): "Only report errors."
  • -c (changed): "Report changed file list to stdout".
  • -a (all): "Also check configuration files (normally excluded)."
  • -e (config): "Only check configuration files."
  • -l (list missing): lists "packages (or debs) which don't have an MD5 sums file."

The last one matters: a package without a checksum list cannot be checked by this method, so debsums -l tells you where coverage stops.

Two caveats from the manual shape how you read results. First, "Files which have been replaced by another package may be erroneously reported as changed." Second, "debsums is intended primarily as a way of determining what installed files have been locally modified by the administrator or damaged by media errors and is of limited use as a security tool." For integrity checking from known-good media, the manual points to tools such as AIDE, integrit, Samhain and Tripwire.

Do not use the --generate option with keep while assessing a restored system; it writes checksum files into the package database directory.

The blind spot: the database came back too

On a restored server, the package database was restored along with everything else. These tools therefore compare restored files with a restored record (our reading). That finds files that are missing, damaged or out of step with the record. It cannot tell you whether the record and the files together match the server as it was before the incident.

Two ways to close that gap (our recommendation):

  1. Keep a package list outside the server. On a schedule, save the output of rpm -qa or dpkg-query -W (which the manual says gives "one line per matching package", name and version) to a location independent of the server and its backups. After a restore, compare it with the same command on the restored system.
  2. Keep a baseline of verify output. Save the output of a verify run from the healthy server. Expected configuration differences will then appear in both, and new differences stand out.

For files no package owns, the package tools are silent. Checking those needs a separate method, such as hashes recorded for your application and data directories, and the restore test below.

Read-only checks

Run in a Bash shell as root or with sudo, so that unreadable files do not show as ?. Keep the full output and any error messages; do not discard standard error.

# RPM-based systems: verify all packages, no scriptlets
sudo rpm -Va --noscripts

# RPM: verify one package, ignoring configuration changes
sudo rpm --verify --noscripts --noconfig openssh-server

# RPM: which package owns a reported file
rpm -qf /usr/sbin/sshd

# Debian-based systems: verify contents of all packages
sudo dpkg --verify --verify-format rpm

# Debian: check the package database for partial installs
sudo dpkg --audit

# Debian: list changed files, including configuration files
sudo debsums -ca

# Debian: list packages that cannot be checked this way
debsums -l

# Debian: which package owns a reported file
dpkg -S /usr/sbin/sshd

-Va combines verify with -a, all installed packages (our understanding of rpm's option grouping; rpm --verify --all is the long form). A full run reads every packaged file and may take some time on a large server.

Safe restore rehearsal

Do this in an authorised, isolated test environment, not on production (our recommendation).

  1. Build a test server of the same distribution and role, with sample application files you create for the purpose. Record SHA-256 hashes of those sample files with sha256sum.
  2. Record the baseline: the package list (rpm -qa or dpkg-query -W) and the verify output, saved off the server.
  3. Back it up with your normal method and settings, including your exclusions.
  4. Restore to a separate machine or virtual machine on an isolated network with no route to production systems or shared storage.
  5. Run the read-only checks above on the restored system and compare them with the baseline.
  6. Compare the sample file hashes with step 1.

Diagnosing what you find

One result can have several causes; check each before acting (our reading):

  • missing on packaged files: the path was excluded from the backup; the restore did not complete; or the file was removed on the source before the backup ran (the baseline shows this). If the backup never captured the file, no restore of that recovery point will bring it back. The fix is a new backup with corrected scope, or reinstalling the package from a trusted repository.
  • 5 (digest) on a binary or library: the file came from a different point in time than the database; it was replaced outside the package manager on the source; the media or transfer was damaged; or it was tampered with. Compare with the baseline and with a second recovery point before deciding.
  • M, U or G on RPM systems: the backup or restore method did not keep modes or ownership, or the account names do not resolve the same way on the restored system.
  • Differences only in c files: often expected administrator changes, which the baseline will show (our reading).

Reinstalling packages to correct differences changes the system, so make that a separate, reviewed step after diagnosis. Have a qualified person review the procedure before adapting it to a production server.

Worked example (illustrative)

The following is invented to show the pattern. An engineering firm restores a Debian file server to new hardware after a disk failure. It boots and shares files. dpkg --verify reports a dozen missing files under a cache directory used by a printing package, and printing fails. The backup job had excluded that directory as cache.

Because dpkg --verify does not check ownership, the firm also compares the owner and mode of key directories with a listing saved before the incident, and finds the share directories correct. They reinstall the printing package from the distribution repository, review the backup exclusion, and add both the package list and a directory listing to the material they keep off the server.

Risks and limits

  • Package checks cover only files packages installed. Data, custom configuration and software installed by other means are not checked.
  • The comparison is with the local package database. If that database is damaged or out of step, results can mislead.
  • dpkg checks only contents, and only for files with stored checksums. rpm checks more attributes, but ownership uses local accounts only.
  • These tools are not intrusion detection. The debsums manual says so plainly.
  • Commands and output formats here come from current manual pages; older releases may differ.
  • No commands in this guide were run in a lab. Test every step in an isolated environment first.

Sources

All accessed 14 November 2026.

Related future topics

  • Keeping a server's package list and configuration baseline outside its own backups
  • Choosing a file-integrity checker for Linux servers
  • Restoring Linux file ownership and permissions after a file-level copy