Hello Reader,
I'm recreating my 24 year old perl scipt in bash to allow someone to validate all of the installed rpms on a system against both the local rpm DB and the repository it came from. This should allow a certain since of comfort on if any core system packages have been manipulated.
#!/bin/bash
# Files to store results
VERIFIED="verified"
FAILURES="failures"
DEBUG="debug"
# Clean previous results
> "$VERIFIED"
> "$FAILURES"
> "$DEBUG"
# Iterate over installed RPM packages
for package in $(rpm -qa); do
echo "Processing package: $package"
# Find repository URL
repo_url=$(dnf repoquery -q --location "$package" 2>/dev/null | head -n 1)
if [[ -z "$repo_url" ]]; then
echo "Repository URL not found for package: $package" | tee -a "$FAILURES"
echo "$repo_url $package" | tee -a "$DEBUG"
continue
fi
# Get local file hashes from RPM database
rpm -ql --dump "$package" | while read -r line; do
file_path=$(echo "$line" | awk '{print $1}')
rpm_hash=$(echo "$line" | awk '{print $4}')
# Skip directories and non-executable files
if [[ ! -x "$file_path" ]]; then
continue
fi
if [[ ! -f "$file_path" ]]; then
continue
fi
if [[ -h "$file_path" ]]; then
continue
fi
# Calculate local disk hash
disk_hash=$(sha256sum "$file_path" 2>/dev/null | awk '{print $1}')
if [[ "$disk_hash" != "$rpm_hash" ]]; then
echo "Hash mismatch (Local RPM DB) - Package: $package, File: $file_path" | tee -a "$FAILURES"
echo "$dish_hash $rpm_hash $package $file_path" | tee -a "$DEBUG"
continue
fi
# Get repository RPM hash
repo_hash=$(rpm -qp --dump "$repo_url" 2>/dev/null | grep " $file_path " | awk '{print $4}')
if [[ -z "$repo_hash" ]]; then
echo "File not found in repository RPM - Package: $package, File: $file_path" | tee -a "$FAILURES"
echo "$repo_hash $repo_url $file_path" | tee -a "$DEBUG"
continue
fi
if [[ "$disk_hash" == "$repo_hash" ]]; then
echo "Verified - Package: $package, File: $file_path" >> "$VERIFIED"
else
echo "Hash mismatch (Repository) - Package: $package, File: $file_path" | tee -a "$FAILURES"
echo "$disk_hash $repo_hash $package $file_path" | tee -a "$DEBUG"
fi
done
done
echo "Verification complete. Results are stored in '$VERIFIED' and '$FAILURES'."