Automatic Security Updates on Linux
Keep Linux patched automatically with unattended-upgrades and dnf-automatic, trusted repositories, and a reduced package surface.
Unpatched software is the single most common way attackers get in. Most breaches do not rely on novel zero-days; they reuse public exploits for vulnerabilities that were fixed weeks or months earlier. The defensive answer is unglamorous but decisive: patch quickly, patch automatically, and shrink the amount of software you have to patch in the first place. This article covers automatic security updates on Debian/Ubuntu and RHEL/Fedora, repository trust, and surface reduction.
Why patching is the highest-value control
The window between a vulnerability disclosure and active exploitation in the wild has collapsed to days, sometimes hours. That makes patch latency a measurable risk. Define a patch SLA and hold to it: critical/exploited CVEs within 48 hours, high severity within 7 days, the rest within 30 days. Automation exists so that the routine 80% never needs a human, leaving your team to handle only the exceptions that genuinely require change control.
Patching pairs with the rest of your posture. A patched but sprawling host is still a large target, so combine fast updates with the service minimization covered in services and systemd hardening and the detection layer in intrusion detection.
Debian and Ubuntu: unattended-upgrades
Install the tooling and the companion that restarts services after a library is upgraded:
sudo apt update
sudo apt install -y unattended-upgrades needrestart apt-listchanges
Edit /etc/apt/apt.conf.d/50unattended-upgrades to control which origins are auto-applied. Keep it to security origins only:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
};
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
Unattended-Upgrade::Mail "root";
Unattended-Upgrade::MailReport "on-change";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Enable the scheduled runs by writing /etc/apt/apt.conf.d/20auto-upgrades:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
Always test before trusting it in production:
sudo unattended-upgrade --dry-run --debug
needrestart detects daemons running against deleted (old) library files and restarts them, so a patched OpenSSL actually takes effect without a full reboot. Set it to list-and-prompt interactively, or a (automatic) for unattended hosts in /etc/needrestart/needrestart.conf.
RHEL and Fedora: dnf-automatic
sudo dnf install -y dnf-automatic
Edit /etc/dnf/automatic.conf to actually apply security updates rather than only download them:
[commands]
upgrade_type = security
apply_updates = yes
random_sleep = 360
[emitters]
emit_via = email
[email]
email_to = root
Enable the timer (not a service you start by hand):
sudo systemctl enable --now dnf-automatic.timer
systemctl list-timers dnf-automatic.timer
Repository trust and pinning
Automatic updates are only as safe as the repositories they pull from. Use GPG-signed repositories exclusively and verify keys out of band before importing them:
# Debian/Ubuntu: list trusted keys
apt-key list 2>/dev/null
ls -l /etc/apt/keyrings/ /etc/apt/trusted.gpg.d/
# RHEL/Fedora: confirm gpgcheck is on
grep -r gpgcheck /etc/yum.repos.d/
Avoid unsigned or random third-party repositories; each one is a supply-chain entry point. When you must use a third-party repo, pin it so it cannot silently override the distribution. On Debian, use /etc/apt/preferences.d/ with a Pin-Priority below 500 for non-essential origins.
Reducing the package surface
Every installed package is potential attack surface and patch workload. Audit and prune:
# List what is installed
dpkg -l # Debian/Ubuntu
rpm -qa # RHEL/Fedora
# Remove a package and its config
sudo apt purge -y telnet rsh-client
sudo dnf remove -y telnet
# Clean up orphaned dependencies
sudo apt autoremove --purge
sudo apt-mark showauto
Tracking vulnerabilities
Know what is outstanding before the scanner tells you:
apt list --upgradable # Debian/Ubuntu
sudo debsecan --suite $(lsb_release -cs) --only-fixed
sudo dnf updateinfo list security # RHEL/Fedora
Feed these results into the audit trail required by compliance benchmarks so patch status is evidenced, not assumed.
Verify
Confirm automation is active and a dry run is clean:
# Debian/Ubuntu
systemctl status unattended-upgrades.service
cat /var/log/unattended-upgrades/unattended-upgrades.log
sudo unattended-upgrade --dry-run
# RHEL/Fedora
systemctl list-timers dnf-automatic.timer
journalctl -u dnf-automatic.service --since "-7d"
If the logs show security origins being applied on schedule and your dry run reports no errors, automatic patching is working. Revisit the configuration whenever you add a new repository or major service.