How to Set Up Automatic Security Updates on Linux
Configuring unattended-upgrades (Debian/Ubuntu) and dnf-automatic (RHEL/Fedora) to apply security patches automatically, with sane limits on scope.
Automatically applying security-only patches — while leaving feature updates for deliberate, reviewed maintenance windows — is a well-supported, standard practice across major Linux distributions. This covers both major package-manager families.
Step 1 (Debian/Ubuntu): install unattended-upgrades
sudo apt install unattended-upgrades apt-listchanges
Step 2 (Debian/Ubuntu): configure which updates apply automatically
// /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::Automatic-Reboot "false";
Restricting Allowed-Origins to the security repository specifically — not the general updates repository — is what keeps this “security patches only,” rather than silently pulling in feature updates unattended.
Step 3 (Debian/Ubuntu): enable the periodic timer
// /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Step 4 (Debian/Ubuntu): do a dry run before trusting it
sudo unattended-upgrade --dry-run --debug
Step 5 (RHEL/Fedora): install dnf-automatic
sudo dnf install dnf-automatic
Step 6 (RHEL/Fedora): configure for security-only, apply-don’t-just-notify
# /etc/dnf/automatic.conf
[commands]
upgrade_type = security
apply_updates = yes
[emitters]
emit_via = stdio
upgrade_type = security mirrors the Debian-side origin restriction; apply_updates = yes actually installs rather than merely notifying (the tool’s default is notify-only).
Step 7 (RHEL/Fedora): enable the timer
sudo systemctl enable --now dnf-automatic.timer
Step 8 (both): decide on reboot policy deliberately
# Debian/Ubuntu
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
Kernel security patches often require a reboot to take effect — leaving Automatic-Reboot off means patches are downloaded and installed but not fully active until a manual reboot; enabling it with a scheduled time trades that gap for an automatic, unattended restart at a chosen low-traffic hour.
Step 9 (both): monitor that it’s actually running
# Debian/Ubuntu
cat /var/log/unattended-upgrades/unattended-upgrades.log
# RHEL/Fedora
journalctl -u dnf-automatic
Confirming these logs show recent, successful runs — not just that the service is configured — catches a silently-broken automatic update pipeline before it matters.
Why “security-only, automatic” is the sensible default and “everything, automatic” usually isn’t
Security patches are narrowly scoped and tested specifically for safe, low-risk application; general feature updates carry a meaningfully higher chance of an unexpected behavior change landing unattended in production. Restricting automation to the security channel specifically — while still handling feature updates through a deliberate, reviewed process — captures nearly all of the safety benefit of automatic patching with much less of the risk.
Step 10: get notified of what was actually installed, not just that a run completed
// /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Mail "[email protected]";
Unattended-Upgrade::MailReport "on-change";
# /etc/dnf/automatic.conf
[emitters]
emit_via = email
[email]
email_from = [email protected]
email_to = [email protected]
Configuring these tools to email a report on every run that actually changed something (rather than every run regardless of outcome, which trains you to ignore the notifications) means a genuinely unattended pipeline still produces a visible record of exactly which packages were touched and when — useful both for routine awareness and as the first thing to check if something breaks shortly after an automatic update window.
Step 11: catch services that need restarting after a library update
sudo apt install needrestart
A security patch to a shared library (OpenSSL, glibc) fixes the vulnerability on disk immediately, but any already-running process that loaded the old version into memory keeps using the vulnerable code until it’s restarted — patched-but-still-vulnerable is a real, easy-to-miss state. needrestart, integrated into the Debian/Ubuntu unattended-upgrade pipeline, scans for exactly this condition after an update and can be configured to automatically restart the affected services (or just report which ones need it, for a more conservative unattended posture), closing the gap between “patch installed” and “patch actually in effect.”
Step 12: treat servers as a fleet, not identical automatic-update twins
Applying identical unattended automatic-update policy to every server in a fleet means a single bad security patch (rare, but not unprecedented) can degrade every instance simultaneously with no canary to catch it first. Staggering automatic-update windows across a fleet, or deliberately excluding a small canary subset from full automation and reviewing its outcome before the rest of the fleet’s scheduled window arrives, keeps most of unattended patching’s real benefit — average time-to-patch across the fleet stays low — while avoiding the specific failure mode of one problematic patch taking down everything at once.
Step 13: exclude specific packages that need manual review regardless
// /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Package-Blacklist {
"linux-image-*";
"postgresql-*";
};
Some packages warrant a deliberate look before any update, even a security one — a database engine where an update might change on-disk format compatibility, or a kernel image where you’d rather control exactly when a reboot-requiring change lands. An explicit package blacklist carves out these specific exceptions from otherwise-broad automatic coverage, which is a more precise tool than disabling automation entirely just because one or two packages in the mix need special handling. Revisit the blacklist periodically, too — a package excluded years ago for a since-resolved reason quietly accumulates unpatched security updates indefinitely if nobody ever circles back to ask whether the original exclusion reason still applies, and an exclusion list that only ever grows is itself a sign the review step has stopped happening.
Related:
- How to Set Up Security Monitoring on Linux with auditd
- How to Set Up Full-Disk Encryption on Linux with LUKS
Sources: