Overview
Package management is foundational to Linux system administration. Debian-based systems use apt/dpkg, while Red Hat-based systems use yum/dnf/rpm. Understanding both package management ecosystems — their principles and usage — along with repository management, dependency resolution, package building, version pinning, and offline installation, is a prerequisite for efficient operations. This article systematically compares the two ecosystems and dives into practical package building and mirror optimization.
apt/dpkg Ecosystem
Architecture
apt (high-level frontend)
│
├── apt-get → package install/remove/update
├── apt-cache → package query/search
└── apt → unified command (user-friendly)
│
dpkg (low-level tool)
│
├── dpkg → .deb package install/remove
├── dpkg-deb → .deb package operations
└── dpkg-query → package query
│
aptitude (alternative frontend, optional)
apt vs apt-get
# apt combines apt-get and apt-cache with friendlier output
# Common comparison:
# Install
$ apt install nginx # New (recommended for interactive use)
$ apt-get install nginx # Old (recommended for scripts)
# Search
$ apt search nginx
$ apt-cache search nginx
# View package info
$ apt show nginx
$ apt-cache show nginx
# Update index
$ apt update
$ apt-get update
# Upgrade
$ apt upgrade # Upgrade installed packages (no removal)
$ apt full-upgrade # Upgrade (may remove packages to resolve dependencies)
$ apt-get dist-upgrade # Equivalent to full-upgrade
In scripts, use
apt-get/apt-cachefor stable output format; for interactive use,aptis more user-friendly.
Basic Operations
# Install packages
$ apt install nginx
$ apt install nginx=1.24.0-1ubuntu1 # Install specific version
$ apt install -y nginx # Auto-confirm
$ apt install --no-install-recommends nginx # Don't install recommended packages
# Remove
$ apt remove nginx # Remove but keep config
$ apt purge nginx # Remove and delete config
$ apt autoremove # Remove unneeded dependencies
$ apt autoclean # Clean obsolete deb files
$ apt clean # Clean all deb files
# Update
$ apt update # Update package index
$ apt upgrade # Upgrade all packages
$ apt full-upgrade # Upgrade (including dependency changes)
$ apt install --only-upgrade nginx # Upgrade only specific package
# Query
$ apt list --installed # Installed packages
$ apt list --upgradable # Upgradable packages
$ apt show nginx # Package details
$ apt search "web server" # Search
$ apt depends nginx # View dependencies
$ apt rdepends nginx # View reverse dependencies
$ apt policy nginx # View version and source
dpkg Low-Level Operations
# Install deb packages
$ dpkg -i package.deb # Install
$ dpkg -i --force-depends package.deb # Ignore dependencies (not recommended)
# Remove
$ dpkg -r package # Remove (keep config)
$ dpkg -P package # Remove (delete config)
# Query
$ dpkg -l # List all installed packages
$ dpkg -l nginx # View specific package status
$ dpkg -L nginx # List files installed by package
$ dpkg -S /usr/sbin/nginx # Find which package owns a file
$ dpkg -s nginx # View package details
$ dpkg -I package.deb # View deb package info
$ dpkg -c package.deb # View deb package contents
# Extract (without installing)
$ dpkg -x package.deb /tmp/extract
$ dpkg -e package.deb /tmp/extract/DEBIAN # Extract control files
apt Package States
$ dpkg -l nginx
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-==============-============-=================================
ii nginx 1.24.0-1 amd64 high performance web server
| Field | Value | Meaning |
|---|---|---|
| Desired | i | Should be installed |
| Status | i | Installed |
| Err | (none) | No error |
Combined ii | Properly installed | |
rc | Removed but config kept | |
hi | Installed and held | |
un | Not installed |
Fixing Broken Dependencies
# Fix dependencies
$ apt --fix-broken install
$ apt-get -f install
# Reconfigure installed packages
$ dpkg --configure -a
# Force reinstall
$ apt install --reinstall nginx
$ dpkg --force-all -i package.deb # Last resort
yum/dnf/rpm Ecosystem
Architecture
dnf (successor to yum, Fedora/RHEL 8+)
│
├── dnf → package install/remove/update
├── dnf-config-manager → repository management
└── dnf-utils → utility tools (repoquery, etc.)
│
yum (RHEL 7 and below)
│
rpm (low-level tool)
│
├── rpm → .rpm package install/remove
├── rpm2cpio → extract rpm
└── rpmbuild → build rpm
yum vs dnf
# dnf commands are largely compatible with yum
# Key improvements:
# - Faster dependency resolution (libsolv)
# - Better memory usage
# - Modular support
# - Clearer error messages
# Common commands (work with both yum/dnf)
$ dnf install nginx
$ dnf remove nginx
$ dnf update nginx
$ dnf update # Update all packages
$ dnf search nginx
$ dnf info nginx
$ dnf list installed
$ dnf list available
$ dnf history # Operation history
$ dnf history undo 5 # Undo operation #5
Basic Operations
# Install
$ dnf install nginx
$ dnf install nginx-1.24.0 # Specific version
$ dnf install -y nginx # Auto-confirm
$ dnf install --nogpgcheck nginx # Skip GPG check (not recommended)
$ dnf reinstall nginx # Reinstall
# Remove
$ dnf remove nginx # Remove
$ dnf autoremove # Remove unneeded dependencies
$ dnf remove --noautoremove nginx # Don't auto-remove dependencies
# Update
$ dnf check-update # Check for available updates
$ dnf update # Update all
$ dnf upgrade # Same as update
$ dnf update --security # Only security updates
# Query
$ dnf list nginx # View package
$ dnf info nginx # Package details
$ dnf search "web server" # Search
$ dnf provides /usr/sbin/nginx # Find which package provides a file
$ dnf repoquery --requires nginx # View dependencies
$ dnf repoquery --whatrequires nginx # Reverse dependencies
$ dnf history # Operation history
$ dnf grouplist # Package group list
$ dnf groupinstall "Development Tools" # Install package group
rpm Low-Level Operations
# Install
$ rpm -ivh package.rpm # Install
$ rpm -Uvh package.rpm # Upgrade install
$ rpm -Fvh package.rpm # Only upgrade if already installed
$ rpm -ivh --nodeps package.rpm # Ignore dependencies (not recommended)
$ rpm -ivh --force package.rpm # Force reinstall
# Remove
$ rpm -e package # Remove
$ rpm -e --nodeps package # Remove ignoring dependencies (dangerous)
# Query
$ rpm -qa # List all installed packages
$ rpm -q nginx # Check if installed
$ rpm -qi nginx # Package details
$ rpm -ql nginx # Files installed by package
$ rpm -qc nginx # Configuration files
$ rpm -qd nginx # Documentation files
$ rpm -qf /usr/sbin/nginx # Which package owns a file
$ rpm -qR nginx # Dependencies
$ rpm -q --whatrequires nginx # Reverse dependencies
$ rpm -q --changelog nginx # Changelog
# Verify
$ rpm -V nginx # Verify file integrity
$ rpm -Va # Verify all packages
# S=size changed M=permission changed 5=MD5 changed T=time changed
rpm Package Verification
$ rpm -V nginx
S.5....T. c /etc/nginx/nginx.conf
# Field meanings:
# S - File size changed
# 5 - MD5 checksum changed
# L - Symlink changed
# T - Modification time changed
# D - Device changed
# U - User changed
# G - Group changed
# M - Permission changed
# . - This attribute unchanged
# Second column:
# c - Configuration file
# d - Documentation file
# g - Ghost file (should not exist)
# l - License file
# r - Readme file
# (empty) - Regular file
Repository Management
apt Repository Management
# View configured repositories
$ apt policy
$ cat /etc/apt/sources.list
$ ls /etc/apt/sources.list.d/
# Add repository (traditional method)
$ echo "deb http://archive.ubuntu.com/ubuntu noble main restricted universe multiverse" >> /etc/apt/sources.list
# Add PPA
$ add-apt-repository ppa:nginx/stable
$ apt update
# Add repository (recommended method)
# /etc/apt/sources.list.d/nginx.list
deb [arch=amd64 signed-by=/etc/apt/keyrings/nginx.gpg] https://nginx.org/packages/ubuntu noble nginx
# Import GPG key
$ curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /etc/apt/keyrings/nginx.gpg
# Disable repository
# Comment out the line with #
# Or use apt preferences
# Update index
$ apt update
apt Repository Priority
# /etc/apt/preferences.d/nginx
Package: nginx
Pin: release o=nginx
Pin-Priority: 1001
# Priority explanation:
# 1001+ - Allow downgrade
# 990 - Default (installed version preferred)
# 500 - Standard priority
# 100 - Unofficial repository
# <0 - Refuse installation
# View priority
$ apt policy nginx
dnf/yum Repository Management
# View configured repositories
$ dnf repolist
$ dnf repolist --all
# Repository config file
$ ls /etc/yum.repos.d/
# /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
# Enable/disable repository
$ dnf config-manager --enable nginx-stable
$ dnf config-manager --disable nginx-stable
# Temporarily enable repository
$ dnf --enablerepo=nginx-stable install nginx
# Add repository
$ dnf config-manager --add-repo https://nginx.org/packages/centos/nginx.repo
# Import GPG key
$ rpm --import https://nginx.org/keys/nginx_signing.key
dnf Modularity
# View available modules
$ dnf module list
# Node.js module example
$ dnf module list nodejs
Name Stream Profiles Summary
nodejs 18 common [d], development, minimal Javascript runtime
nodejs 20 common [d], development, minimal Javascript runtime
# Enable module stream
$ dnf module enable nodejs:20
# Install module
$ dnf module install nodejs:20/common
# Switch module stream
$ dnf module reset nodejs
$ dnf module enable nodejs:18
$ dnf module install nodejs:18
Dependency Resolution
apt Dependency Resolution
# View dependencies
$ apt depends nginx
$ apt-cache depends nginx
# View reverse dependencies
$ apt rdepends nginx
$ apt-cache rdepends nginx
# View dependency tree
$ apt-cache depends --recurse nginx | head -50
# Find out why a package is installed
$ apt why nginx
# nginx <depends> nginx-core
# nginx-core <depends> nginx
# View package recommends and suggests
$ apt show nginx | grep -E "Depends|Recommends|Suggests"
dnf Dependency Resolution
# View dependencies
$ dnf repoquery --requires nginx
$ dnf repoquery --requires --recursive nginx
# Reverse dependencies
$ dnf repoquery --whatrequires nginx
# View package provides
$ dnf repoquery --provides nginx
# View package files
$ dnf repoquery --list nginx
# Dependency tree
$ dnf repoquery --requires --resolve --recursive nginx
Dependency Conflict Handling
# apt: Simulate installation to see conflicts
$ apt install -s nginx
# dnf: Use --best to show best available version
$ dnf install --best nginx
# dnf: Use --allowerasing to allow removing conflicting packages
$ dnf install --allowerasing nginx
# View conflict details
$ dnf install nginx --assumeno # Simulate, answer no
Package Building
Building deb Packages
Directory Structure
mypackage/
├── DEBIAN/
│ ├── control # Package info (required)
│ ├── postinst # Post-installation script
│ ├── prerm # Pre-removal script
│ ├── postrm # Post-removal script
│ ├── preinst # Pre-installation script
│ ├── conffiles # Configuration file list
│ ├── md5sums # File checksums (auto-generated)
│ └── triggers # Triggers
├── usr/
│ ├── bin/
│ │ └── myapp # Executable
│ ├── lib/
│ │ └── myapp/
│ │ └── config.yaml
│ └── share/
│ └── man/
│ └── man1/
│ └── myapp.1
└── etc/
└── myapp/
└── config.conf
control File
# mypackage/DEBIAN/control
Package: myapp
Version: 1.0.0
Architecture: amd64
Maintainer: Admin <admin@sre.wang>
Installed-Size: 1024
Depends: libc6 (>= 2.34), libssl3
Recommends: logrotate
Suggests: myapp-doc
Conflicts: oldapp
Replaces: oldapp
Section: utils
Priority: optional
Description: My Application
A custom application for server management.
.
Features:
- Feature 1
- Feature 2
Maintenance Scripts
#!/bin/bash
# mypackage/DEBIAN/postinst
set -e
case "$1" in
configure)
# Create user
if ! id myapp &>/dev/null; then
useradd --system --no-create-home --shell /usr/sbin/nologin myapp
fi
# Set permissions
chown myapp:myapp /var/lib/myapp
chmod 750 /var/lib/myapp
# Enable service
systemctl enable myapp.service
systemctl start myapp.service
echo "myapp installed successfully"
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0
Building
# Ensure correct permissions for control files
$ chmod 755 mypackage/DEBIAN/postinst
$ chmod 755 mypackage/DEBIAN/prerm
# Generate md5sums
$ cd mypackage
$ find . -type f ! -path './DEBIAN/*' -exec md5sum {} \; | sed 's/\.\///' > DEBIAN/md5sums
# Build deb package
$ dpkg-deb --build mypackage
# Or
$ dpkg -b mypackage myapp_1.0.0_amd64.deb
# Verify
$ dpkg-deb --info myapp_1.0.0_amd64.deb
$ dpkg-deb --contents myapp_1.0.0_amd64.deb
# Check with lintian
$ lintian myapp_1.0.0_amd64.deb
Building with debhelper (Advanced)
# Install build tools
$ apt install debhelper dh-make devscripts
# Initialize package
$ dh_make --createorig -p myapp_1.0.0
# Edit files in debian/ directory
# debian/control
# debian/rules
# debian/changelog
# Build
$ dpkg-buildpackage -us -uc -b
Building rpm Packages
spec File
# myapp.spec
Name: myapp
Version: 1.0.0
Release: 1%{?dist}
Summary: My Application
License: MIT
URL: https://sre.wang
Source0: %{name}-%{version}.tar.gz
BuildRequires: gcc
BuildRequires: make
Requires: openssl
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
%description
A custom application for server management.
%prep
%setup -q
%build
make %{?_smp_mflags}
%install
make install DESTDIR=%{buildroot}
install -D -m 644 config/myapp.service %{buildroot}%{_unitdir}/myapp.service
install -D -m 644 config/myapp.conf %{buildroot}%{_sysconfdir}/myapp/myapp.conf
%files
%{_bindir}/myapp
%{_unitdir}/myapp.service
%dir %{_sysconfdir}/myapp
%config(noreplace) %{_sysconfdir}/myapp/myapp.conf
%doc README.md
%license LICENSE
%post
%systemd_post myapp.service
%preun
%systemd_preun myapp.service
%postun
%systemd_postun_with_restart myapp.service
%changelog
* Wed Jul 10 2026 Admin <admin@sre.wang> - 1.0.0-1
- Initial release
Building
# 1. Prepare build environment
$ dnf install rpmdevtools rpmbuild
$ rpmdev-setuptree
# 2. Directory structure
~/rpmbuild/
├── BUILD/
├── RPMS/
├── SOURCES/
│ └── myapp-1.0.0.tar.gz
├── SPECS/
│ └── myapp.spec
└── SRPMS/
# 3. Place source code
$ cp myapp-1.0.0.tar.gz ~/rpmbuild/SOURCES/
$ cp myapp.spec ~/rpmbuild/SPECS/
# 4. Build
$ rpmbuild -ba ~/rpmbuild/SPECS/myapp.spec
# -ba: Build src.rpm and binary rpm
# -bb: Build only binary rpm
# -bs: Build only src.rpm
# 5. View
$ ls ~/rpmbuild/RPMS/x86_64/
myapp-1.0.0-1.el9.x86_64.rpm
# 6. Verify
$ rpm -qpi ~/rpmbuild/RPMS/x86_64/myapp-1.0.0-1.el9.x86_64.rpm
$ rpm -qpl ~/rpmbuild/RPMS/x86_64/myapp-1.0.0-1.el9.x86_64.rpm
deb vs rpm Package Building Comparison
| Feature | deb | rpm |
|---|---|---|
| Control file | DEBIAN/control | spec file |
| Script location | DEBIAN/ directory | Inside spec file |
| Dependency declaration | Depends/Recommends | Requires |
| Config file marking | conffiles | %config(noreplace) |
| Build tool | dpkg-deb / debhelper | rpmbuild |
| Source package | .dsc + .orig.tar.gz | .src.rpm |
| Changelog | debian/changelog | %changelog |
Version Pinning
apt Version Pinning
# Method 1: apt-mark hold
$ apt-mark hold nginx
$ apt-mark showhold
$ apt-mark unhold nginx
# Method 2: dpkg --set-selection
$ echo "nginx hold" | dpkg --set-selections
$ dpkg --get-selections | grep hold
# Method 3: apt preferences (more fine-grained)
# /etc/apt/preferences.d/hold-nginx
Package: nginx
Pin: release *
Pin-Priority: -1
# Priority < 0 refuses installation/upgrade
# Pin specific version
# /etc/apt/preferences.d/pin-nginx
Package: nginx
Pin: version 1.24.0*
Pin-Priority: 1001
dnf/yum Version Pinning
# Method 1: versionlock plugin
$ dnf install python3-dnf-plugin-versionlock
$ dnf versionlock add nginx
$ dnf versionlock list
$ dnf versionlock delete nginx
$ dnf versionlock clear
# Method 2: Exclude in repo
# /etc/yum.repos.d/centos.repo
[baseos]
exclude=nginx kernel*
# Method 3: dnf config
# /etc/dnf/dnf.conf
exclude=nginx
Offline Installation
Method 1: Download deb Packages and Dependencies
# Download package and all dependencies
$ apt download nginx
$ apt-get install --download-only -o Dir::Cache=/tmp/packages nginx
# Or
$ apt install --reinstall --download-only nginx
# Better approach: use apt-rdepends
$ apt install apt-rdepends
$ apt-rdepends nginx | grep -v "^ " | awk '{print $1}' | xargs apt download
# Using dpkg-offline
$ apt install dpkg-offline
$ dpkg-offline /path/to/iso nginx
# Install offline packages
$ dpkg -i /tmp/packages/*.deb
$ apt --fix-broken install # Fix dependencies (if needed)
Method 2: Download rpm Packages and Dependencies
# Download package and dependencies
$ dnf install --downloadonly --downloaddir=/tmp/packages nginx
# Using repotrack
$ dnf install dnf-utils
$ repotrack nginx -p /tmp/packages
# Install offline packages
$ rpm -Uvh /tmp/packages/*.rpm
# Or
$ dnf localinstall /tmp/packages/*.rpm
Method 3: Create Local Repository
# apt local repository
$ apt install dpkg-dev
$ mkdir -p /opt/local-repo
$ cp *.deb /opt/local-repo/
$ cd /opt/local-repo && dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
# Configure repository
# /etc/apt/sources.list.d/local.list
deb [trusted=yes] file:///opt/local-repo ./
$ apt update
$ apt install myapp
# dnf local repository
$ dnf install createrepo
$ mkdir -p /opt/local-repo
$ cp *.rpm /opt/local-repo/
$ createrepo /opt/local-repo
# Configure repository
# /etc/yum.repos.d/local.repo
[local]
name=Local Repository
baseurl=file:///opt/local-repo
gpgcheck=0
enabled=1
$ dnf install myapp
Method 4: Using Snapshots/Mirrors
# apt-mirror: full mirror
$ apt install apt-mirror
# /etc/apt/mirror.list
deb http://archive.ubuntu.com/ubuntu noble main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu noble-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu noble-security main restricted universe multiverse
$ apt-mirror
# Downloads to /var/spool/apt-mirror/
# reposync: mirror dnf repository
$ dnf install dnf-utils
$ reposync --repoid=baseos --download_path=/opt/mirror
$ createrepo /opt/mirror/baseos
Mirror Optimization
Selecting the Fastest Mirror
# apt: netselect-apt
$ apt install netselect-apt
$ netselect-apt noble
# Auto-selects the fastest Ubuntu mirror
# Or manual testing
$ time curl -sI http://archive.ubuntu.com/ubuntu/ > /dev/null
$ time curl -sI http://mirrors.aliyun.com/ubuntu/ > /dev/null
$ time curl -sI http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ > /dev/null
# dnf: fastestmirror plugin
# /etc/dnf/dnf.conf
fastestmirror=True
$ dnf clean all
$ dnf makecache
Configuring Regional Mirrors
# Ubuntu/Debian mirror sources
# /etc/apt/sources.list
deb https://mirrors.aliyun.com/ubuntu/ noble main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ noble-updates main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ noble-security main restricted universe multiverse
# Or Tsinghua mirror
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ noble main restricted universe multiverse
# Debian
deb https://mirrors.aliyun.com/debian/ bookworm main contrib non-free non-free-firmware
deb https://mirrors.aliyun.com/debian/ bookworm-updates main contrib non-free non-free-firmware
deb https://mirrors.aliyun.com/debian-security/ bookworm-security main contrib non-free non-free-firmware
# RHEL/CentOS mirror sources
# /etc/yum.repos.d/CentOS-Base.repo
[baseos]
name=CentOS Stream $releasever - BaseOS
baseurl=https://mirrors.aliyun.com/centos-stream/$releasever-stream/BaseOS/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
[appstream]
name=CentOS Stream $releasever - AppStream
baseurl=https://mirrors.aliyun.com/centos-stream/$releasever-stream/AppStream/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
# AlmaLinux/Rocky Linux
# Usually have regional mirrors available, refer to official docs
Mirror Cache Optimization
# apt: cache configuration
# /etc/apt/apt.conf.d/99-cache
Dir::Cache "/var/cache/apt";
Dir::Cache::archives "archives";
APT::Install-Recommends "false"; # Reduce unnecessary packages
APT::Install-Suggests "false";
APT::Get::Install-Suggests "false";
# Clean cache
$ apt clean # Clean all downloaded deb files
$ apt autoclean # Clean only obsolete deb files
$ apt autoremove # Clean unneeded dependencies
# dnf: cache configuration
# /etc/dnf/dnf.conf
keepcache=True # Keep downloaded rpm files
cachedir=/var/cache/dnf
$ dnf clean all # Clean cache
$ dnf makecache # Rebuild cache
Using Proxy
# apt proxy
# /etc/apt/apt.conf.d/99proxy
Acquire::http::Proxy "http://proxy.sre.wang:8080";
Acquire::https::Proxy "http://proxy.sre.wang:8080";
# Or environment variables
$ export http_proxy=http://proxy.sre.wang:8080
$ export https_proxy=http://proxy.sre.wang:8080
$ apt update
# dnf proxy
# /etc/dnf/dnf.conf
proxy=http://proxy.sre.wang:8080
proxy_username=user
proxy_password=pass
Package Management Security
GPG Key Management
# apt: GPG keys
# Import key (new method)
$ install -d /etc/apt/keyrings
$ curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /etc/apt/keyrings/nginx.gpg
# Import key (old method, not recommended)
$ apt-key add nginx_signing.key
# View imported keys
$ apt-key list
# Delete key
$ apt-key del ABC12345
$ rm /etc/apt/keyrings/nginx.gpg
# dnf: GPG keys
$ rpm --import https://nginx.org/keys/nginx_signing.key
# View imported keys
$ rpm -qa gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n'
# Delete key
$ rpm -e gpg-pubkey-abc12345
Verifying Package Integrity
# apt: verification
$ apt install --allow-unauthenticated nginx # Disable verification (not recommended)
$ apt install nginx # Default verification
# dpkg verification
$ debsums nginx # Verify installed package files
$ debsums -c nginx # Check only changed files
# dnf: verification
$ dnf install --nogpgcheck nginx # Disable verification (not recommended)
# rpm verification
$ rpm -K package.rpm # Verify signature
$ rpm --checksig package.rpm
# Verify all installed packages
$ rpm -Va | grep -E "S\.5" | head -20
# Check if files have been tampered with
Real-World Examples
Example 1: Cross-Distribution Package Installation Script
#!/bin/bash
# install-packages.sh - Cross-distribution package installation
set -e
# Detect package manager
if command -v apt &>/dev/null; then
PKG_MGR="apt"
elif command -v dnf &>/dev/null; then
PKG_MGR="dnf"
elif command -v yum &>/dev/null; then
PKG_MGR="yum"
else
echo "Unsupported distribution"
exit 1
fi
# Package name mapping (package names may differ across distributions)
declare -A PACKAGES=(
["nginx"]="nginx"
["redis"]="redis-server" # Debian uses redis-server
["vim"]="vim"
["curl"]="curl"
["git"]="git"
)
# Install function
install_package() {
local name=$1
local apt_name=${2:-$1}
local dnf_name=${3:-$1}
case $PKG_MGR in
apt)
apt update && apt install -y "$apt_name"
;;
dnf|yum)
$PKG_MGR install -y "$dnf_name"
;;
esac
}
# Batch install
for pkg in nginx redis vim curl git; do
echo "Installing $pkg..."
install_package "$pkg"
done
echo "All packages installed."
Example 2: Building a Custom Nginx Package
#!/bin/bash
# build-nginx-deb.sh - Build Nginx deb package
set -e
VERSION="1.27.0"
NGINX_USER="www-data"
BUILD_DIR="/tmp/nginx-build"
PKG_DIR="$BUILD_DIR/nginx_$VERSION"
# 1. Prepare build environment
apt install -y build-essential libpcre3-dev zlib1g-dev libssl-dev dpkg-dev
# 2. Download source
mkdir -p $BUILD_DIR
cd $BUILD_DIR
wget http://nginx.org/download/nginx-$VERSION.tar.gz
tar xzf nginx-$VERSION.tar.gz
# 3. Compile
cd nginx-$VERSION
./configure \
--prefix=/usr/share/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--user=$NGINX_USER \
--group=$NGINX_USER \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_stub_status_module
make -j$(nproc)
make install DESTDIR=$PKG_DIR
# 4. Create DEBIAN directory
mkdir -p $PKG_DIR/DEBIAN
# 5. Create control file
cat > $PKG_DIR/DEBIAN/control << EOF
Package: nginx-custom
Version: $VERSION
Architecture: amd64
Maintainer: Admin <admin@sre.wang>
Depends: libc6, libpcre3, zlib1g, libssl3
Section: web
Priority: optional
Description: Custom Nginx $VERSION
Nginx built with custom configuration.
EOF
# 6. Create systemd service
mkdir -p $PKG_DIR/etc/systemd/system
cat > $PKG_DIR/etc/systemd/system/nginx.service << 'EOF'
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
# 7. Create postinst
cat > $PKG_DIR/DEBIAN/postinst << 'EOF'
#!/bin/bash
set -e
systemctl daemon-reload
systemctl enable nginx
systemctl start nginx
EOF
chmod 755 $PKG_DIR/DEBIAN/postinst
# 8. Generate md5sums
cd $PKG_DIR
find . -type f ! -path './DEBIAN/*' -exec md5sum {} \; | sed 's/\.\///' > DEBIAN/md5sums
# 9. Build
cd $BUILD_DIR
dpkg-deb --build $(basename $PKG_DIR)
echo "Package built: $BUILD_DIR/nginx_$VERSION.deb"
Example 3: Automated Security Updates
#!/bin/bash
# auto-security-update.sh - Automated security update
set -e
LOG="/var/log/security-update.log"
exec > >(tee -a $LOG) 2>&1
echo "=== Security Update $(date) ==="
if command -v apt &>/dev/null; then
# Debian/Ubuntu
apt update
# List only security updates
apt list --upgradable 2>/dev/null | grep -i security
# Use unattended-upgrades
apt install -y unattended-upgrades
echo 'APT::Periodic::Update-Package-Lists "1";' > /etc/apt/apt.conf.d/20auto-upgrades
echo 'APT::Periodic::Unattended-Upgrade "1";' >> /etc/apt/apt.conf.d/20auto-upgrades
unattended-upgrade --dry-run -v
elif command -v dnf &>/dev/null; then
# RHEL/CentOS
dnf check-update --security
# Install security updates
dnf update --security -y
# Use dnf-automatic
dnf install -y dnf-automatic
sed -i 's/apply_updates = no/apply_updates = yes/' /etc/dnf/automatic.conf
sed -i 's/upgrade_type = default/upgrade_type = security/' /etc/dnf/automatic.conf
systemctl enable --now dnf-automatic.timer
fi
echo "Security update completed."
Package Management Quick Reference
| Operation | apt/dpkg | dnf/yum/rpm |
|---|---|---|
| Install | apt install pkg | dnf install pkg |
| Remove | apt remove pkg | dnf remove pkg |
| Remove + config | apt purge pkg | dnf remove pkg |
| Update index | apt update | dnf makecache |
| Upgrade package | apt upgrade pkg | dnf update pkg |
| Upgrade all | apt full-upgrade | dnf update |
| Search | apt search keyword | dnf search keyword |
| Package info | apt show pkg | dnf info pkg |
| Installed list | apt list --installed | dnf list installed |
| Find file owner | dpkg -S file | rpm -qf file / dnf provides file |
| Package file list | dpkg -L pkg | rpm -ql pkg |
| Install local package | dpkg -i pkg.deb | dnf localinstall pkg.rpm |
| View dependencies | apt depends pkg | dnf repoquery --requires pkg |
| Reverse dependencies | apt rdepends pkg | dnf repoquery --whatrequires pkg |
| Pin version | apt-mark hold pkg | dnf versionlock add pkg |
| Operation history | cat /var/log/dpkg.log | dnf history |
| Clean cache | apt clean | dnf clean all |
Summary
Linux package management is a foundational system administration skill — both ecosystems have their characteristics but share the same concepts. Key takeaways:
- apt/dpkg and dnf/rpm are two parallel ecosystems: Debian-based uses apt, Red Hat-based uses dnf (successor to yum), with dpkg and rpm as their respective low-level tools.
- Prefer high-level frontends:
apt/dnfhandle dependency resolution;dpkg/rpmonly handle individual packages. - Repository management is operations-critical: Properly configuring repository sources, GPG keys, and priorities is the prerequisite for safely using third-party software.
- Understand dependency resolution with
Depends/Requires:apt depends/dnf repoquery --requiresto view dependencies;apt why/dnf repoquery --whatrequiresto find installation reasons. - Package building requires understanding directory structure and control files: deb uses
DEBIAN/control, rpm uses spec files; maintenance scripts handle service start/stop and permissions. - Version pinning prevents accidental upgrades:
apt-mark hold/dnf versionlockto lock critical packages, avoiding compatibility issues from automatic upgrades. - Offline installation has multiple approaches: Download deb/rpm with dependencies, create local repositories, or use apt-mirror/reposync for mirroring.
- Mirror optimization improves installation speed: Use regional mirrors, configure cache, select fastest mirror.
- Security updates are an operations baseline: Use unattended-upgrades/dnf-automatic for automated security patching.
- GPG verification is the security foundation: Never use
--allow-unauthenticated/--nogpgcheck; ensure package sources are trusted.
The golden rule of package management: minimal installation, maximum control. Install only the packages you need, pin critical package versions, regularly clean unneeded dependencies, and keep the system clean and manageable.