Zum Inhalt

Linux Package Management Internals: APT/dpkg, DNF5/RPM, Pacman, DEB822 Keyrings & Flatpak Sandboxing

Executive Summary: Treating a package manager as a black-box install command leads to broken dependency graphs, untrusted global GPG keys (apt-key deprecation), and unverified third-party binaries. This architectural reference compares the low-level package database engines (dpkg, rpm, libalpm) and high-level SAT dependency solvers (apt, dnf5, pacman, zypper), detailing DEB822 Signed-By keyrings, APT Priority Pinning, file integrity verification (dpkg -V / rpm -Va), and Bubblewrap-sandboxed Flatpak isolation.

  • Low-Level DB vs. SAT Solver


    Understand how apt, dnf5, and zypper resolve dependency DAGs before delegating archive extraction to dpkg (/var/lib/dpkg) and rpm.

  • Scoped Signed-By Keyrings


    Replace deprecated global apt-key trust with repository-scoped binary keyrings (/etc/apt/keyrings/*.gpg) inside DEB822 .sources files.

  • APT Pinning & Version Locks


    Pin mission-critical packages (docker-ce, postgresql, kernel modules) via /etc/apt/preferences.d/ or apt-mark hold.

  • Cryptographic File Auditing


    Verify every installed binary and /etc configuration file on disk against package SHA-256/MD5 manifests (dpkg --verify, rpm -Va).


1. Architecture: How Linux Package Managers Verify & Mutate System State

Every modern Linux package manager operates as a two-layer stack: 1. The Repository & Dependency Solver (apt, dnf5, zypper, pacman -S): Downloads GPG-signed repository metadata (InRelease, repomd.xml), constructs a Directed Acyclic Graph (DAG) of Depends, Conflicts, and Provides, and downloads .deb / .rpm / .pkg.tar.zst archives. 2. The Local Transaction Engine (dpkg, rpm, libalpm): Unpacks the archive payload (data.tar.zst), executes maintainer scripts (preinst, postinst, prerm, postrm), and updates the local state database (/var/lib/dpkg/status or /var/lib/rpm/rpmdb.sqlite):

%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
    subgraph RemoteRepo["HTTPS Mirror + GPG Signature"]
        InRelease["Signed Metadata<br/>(InRelease / repomd.xml)"]
        PkgPool["Compressed Package<br/>(.deb / .rpm / .pkg.tar.zst)"]
    end

    subgraph Solver["High-Level SAT Solver (apt / dnf5)"]
        KeyVerify["Verify Repository GPG<br/>(/etc/apt/keyrings/*.gpg)"]
        DAG["Compute Dependency DAG<br/>& Check Pin Priorities"]
    end

    subgraph LocalEngine["Local State DB (dpkg / rpm)"]
        Scripts["Run preinst / postinst<br/>& systemd Triggers"]
        StateDB[("/var/lib/dpkg/status<br/>+ File Hash Manifests")]
    end

    InRelease --> KeyVerify
    PkgPool --> DAG
    KeyVerify --> DAG
    DAG --> Scripts
    Scripts --> StateDB

Cross-Distribution Rosetta Stone

Operation Debian / Ubuntu (apt + dpkg) Fedora / RHEL (dnf5 + rpm) Arch Linux (pacman) openSUSE (zypper + rpm)
Refresh & Full Upgrade apt update && apt full-upgrade dnf upgrade --refresh pacman -Syu zypper ref && zypper dup
Which Package Owns File? dpkg -S /usr/bin/ss rpm -qf /usr/bin/ss pacman -Qo /usr/bin/ss rpm -qf /usr/bin/ss
List Files in Installed Pkg dpkg -L openssh-server rpm -ql openssh-server pacman -Ql openssh rpm -ql openssh
Verify Binary Integrity dpkg --verify (debsums -c) rpm -Va pacman -Qkk rpm -Va
Remove Orphaned Deps apt autoremove --purge dnf autoremove pacman -Rns $(pacman -Qdtq) zypper packages --unneeded

2. Hardened Third-Party Repository Onboarding (DEB822 + Scoped Keyrings)

Historically, tutorials instructed users to run curl ... | sudo apt-key add -. That was a severe security flaw: any key added to /etc/apt/trusted.gpg was unconditionally trusted to sign packages for every repository on the system, including deb.debian.org (libc6, linux-image, systemd).

Modern Debian/Ubuntu systems scope each third-party GPG key strictly to its own repository via the Signed-By field inside a DEB822 .sources file:

Onboarding a Third-Party Repository with Isolated Keyring Trust
# 1. Create the restricted keyrings directory (0755) and download/dearmor the vendor GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# 2. Create a DEB822 .sources definition scoped strictly to /etc/apt/keyrings/docker.gpg
cat << 'EOF' | sudo tee /etc/apt/sources.list.d/docker.sources
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: bookworm
Components: stable
Architectures: amd64
Signed-By: /etc/apt/keyrings/docker.gpg
EOF

3. APT Priority Pinning (preferences.d) & Version Holding

When mixing stable repositories with bookworm-backports or third-party vendor repositories, use APT Pinning to control exactly which repository wins version resolution:

  • P >= 1000: Forces installation even if it constitutes a downgrade.
  • 990 <= P < 1000: Preferred target release (beats installed version unless installed version is newer).
  • 500: Default priority for standard repositories.
  • 100: Default priority for currently installed packages and -backports.
  • P < 0: Prevents the package from ever being installed.
/etc/apt/preferences.d/99-pin-postgresql.pref
# Prefer official PostgreSQL PGDG repository (Priority 900) over Debian default packages (500)
Package: postgresql-* libpq5
Pin: origin apt.postgresql.org
Pin-Priority: 900
Inspecting Candidate Priorities & Locking Package Versions
# 1. Inspect all available versions of a package, their source URLs, and computed Pin-Priorities
apt-cache policy postgresql-17

# 2. Prevent a mission-critical package from being upgraded during unattended-upgrades
sudo apt-mark hold kubelet kubeadm kubectl
apt-mark showhold

4. Auditing File Integrity & Sandboxed Flatpak Overrides

During incident response or troubleshooting, verify whether any packaged binary or /etc configuration file has been modified on disk since installation:

Auditing Modified Binaries & Config Files Against Package Manifests
# On Debian/Ubuntu: List any file whose checksum, size, or permissions differ from dpkg database
# ('??5?????? c /etc/ssh/sshd_config' means the MD5/SHAchecksum of config file 'c' was modified)
sudo dpkg --verify

# On Fedora/RHEL/openSUSE: Verify all installed RPMs (S=Size, 5=Checksum, M=Mode, U=User, G=Group)
sudo rpm -Va

# On Arch Linux: Verify all file properties and permissions against MTREE manifests
sudo pacman -Qkk | grep -v "0 altered files"

Controlling Flatpak Bubblewrap (bwrap) Sandbox Permissions

When running desktop applications via Flatpak on a Linux workstation, never blindly accept filesystem=host permissions. Inspect and restrict application sandbox capabilities using flatpak info --show-permissions and flatpak override:

Auditing & Restricting Flatpak Sandbox Permissions
# 1. Inspect active filesystem, socket, and device permissions of a Flatpak application
flatpak info --show-permissions org.mozilla.firefox

# 2. Revoke full home-directory access and grant access ONLY to ~/Downloads
flatpak override --user --nofilesystem=home --filesystem=~/Downloads org.mozilla.firefox