Skip to content
All articles

Automatic Linux Security Updates with unattended-upgrades and dnf-automatic

How to install security updates automatically on Debian, Ubuntu, RHEL and AlmaLinux, control reboots and service restarts, and prove the updates actually ran.

M By Max · 6 min read
Automatic Linux Security Updates with unattended-upgrades and dnf-automatic

Most business Linux servers should install security updates automatically. On Debian and Ubuntu that job belongs to unattended-upgrades; on Red Hat Enterprise Linux and AlmaLinux it belongs to dnf-automatic. Configured well, they apply security fixes daily, email you what changed, restart affected services and reboot only inside a window you choose. The two things that go wrong are servers that should not be auto-updated (databases and pinned applications) and servers where everyone assumes updates are running when they stopped weeks ago. This guide covers both, with commands for Debian 12/13, Ubuntu 24.04 and RHEL/AlmaLinux 9 and 10.

Why automate security updates

Patching is the most effective routine control you have, and it is also the easiest to forget. Automatic security updates close the gap between a fix being published and someone remembering to log in. Feature upgrades and major version changes still deserve a human, but routine security fixes for OpenSSL, the C library, SSH or the kernel should not wait for the next maintenance meeting. If you are still building the basics, start with our Linux server hardening essentials.

Debian and Ubuntu: unattended-upgrades

Ubuntu Server installs and enables unattended-upgrades by default for security updates. On Debian, install and enable it:

sudo apt update
sudo apt install unattended-upgrades apt-listchanges
sudo dpkg-reconfigure -plow unattended-upgrades

The last command writes /etc/apt/apt.conf.d/20auto-upgrades, which should contain:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

Choose which updates are installed

The allowed sources live in /etc/apt/apt.conf.d/50unattended-upgrades.

  • Ubuntu allows ${distro_id}:${distro_codename}-security plus the Ubuntu Pro ESM security pockets by default; -updates is commented out. That is a sensible security-only default.
  • Debian 12 and 13 allow three origins by default: the security archive (label=Debian-Security) and also the main release (label=Debian), which delivers stable point-release updates. If you want security fixes only, comment out the line that ends in label=Debian"; and keep the two Debian-Security lines.

Email reports and clean-up

Put your own settings in a separate file so package upgrades do not overwrite them, for example /etc/apt/apt.conf.d/52unattended-upgrades-local:

Unattended-Upgrade::Mail "[email protected]";
Unattended-Upgrade::MailReport "on-change";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

MailReport accepts always, only-on-error or on-change. Email only works if the server can send mail: install a package that provides mailx (such as bsd-mailx) and configure a relay to your mail provider. Test it before relying on it.

Automatic reboots inside a window

Kernel and C library updates only take full effect after a reboot. unattended-upgrades can reboot for you when /var/run/reboot-required exists:

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:30";

Upgrades themselves run from the apt-daily-upgrade.timer systemd timer. Check when it fires and move it if needed:

systemctl list-timers 'apt-daily*'
sudo systemctl edit apt-daily-upgrade.timer

In the override, clear and redefine the schedule:

[Timer]
OnCalendar=
OnCalendar=*-*-* 02:00
RandomizedDelaySec=30m

Service restarts with needrestart

Updating a library does not help a running process that still has the old copy loaded. needrestart finds those processes and restarts their services. Since Ubuntu 24.04 LTS it restarts affected services automatically by default, including during unattended upgrades. On Debian it is optional (sudo apt install needrestart), and when run non-interactively in its default mode it only lists what needs a restart.

To exclude a service you want to restart yourself, such as PostgreSQL, add a file in /etc/needrestart/conf.d/, for example zz-local.conf:

$nrconf{override_rc}->{qr(^postgresql)} = 0;

Run sudo needrestart -r l at any time to list what still needs a restart.

Test before you trust it

sudo unattended-upgrade --dry-run --debug

Logs are written to /var/log/unattended-upgrades/, and package actions to /var/log/dpkg.log.

Rack of business servers in a data center

RHEL and AlmaLinux 9 and 10: dnf-automatic

RHEL 9 and 10 and their rebuilds such as AlmaLinux use DNF 4, which provides dnf-automatic:

sudo dnf install dnf-automatic

Edit /etc/dnf/automatic.conf:

[commands]
upgrade_type = security
download_updates = yes
apply_updates = yes
reboot = when-needed

[emitters]
emit_via = email,motd

[email]
email_from = [email protected]
email_to = [email protected]
email_host = localhost
  • upgrade_type = security installs only updates that carry a security advisory. This depends on the repository publishing advisory (updateinfo) metadata, which RHEL and AlmaLinux do. Check what is pending with sudo dnf updateinfo list --security.
  • reboot = when-needed reboots only when an update requires it, such as a new kernel or systemd. The default reboot_command waits five minutes and warns logged-in users. The reboot option is available in current RHEL 9 and 10 packages; if your server rejects it, update dnf first.
  • emit_via controls reporting. Email again needs a working local relay.

Then enable the timer that follows your config file:

sudo systemctl enable --now dnf-automatic.timer
systemctl list-timers 'dnf-automatic*'

There are also dnf-automatic-notifyonly.timer, dnf-automatic-download.timer and dnf-automatic-install.timer, which override the config file's behaviour. Enable only one. To move the schedule, use sudo systemctl edit dnf-automatic.timer as shown above. To see whether a reboot is pending, run sudo dnf needs-restarting -r. (On Fedora 41 and later, DNF5 replaces this with its own automatic plugin, so check the Fedora documentation.)

Kernel live patching

Live patching applies fixes for serious kernel vulnerabilities to the running kernel without a reboot. It reduces reboots; it does not eliminate them.

  • Ubuntu: Livepatch is part of Ubuntu Pro. On an attached LTS machine, enable it with sudo pro enable livepatch. Canonical patches high and critical kernel CVEs only, and only for supported kernels for a limited period, so you still install new kernels and reboot regularly.
  • RHEL: Red Hat ships live patches as kpatch-patch packages for supported kernels. Install the DNF plugin and subscribe automatically with sudo dnf install kpatch-dnf and sudo dnf kpatch auto.
  • Debian and AlmaLinux: live patching is available from third-party commercial services. Evaluate them like any other vendor.

When not to auto-update

Automation is the default, not a rule for every server.

  • Databases: a security update to PostgreSQL, MariaDB or MySQL restarts the database. Many businesses prefer to apply these in a maintenance window after a backup. Exclude them from service restarts (as above) or hold them and patch on a schedule.
  • Pinned application versions: if a vendor certifies a specific version, hold it. On Debian/Ubuntu, sudo apt-mark hold <package> (unattended-upgrades respects holds). On RHEL/AlmaLinux, install python3-dnf-plugin-versionlock and run sudo dnf versionlock add <package>.
  • Clusters and redundant pairs: stagger the timers so both nodes never reboot at the same time.
  • Hypervisors and storage hosts: reboots take every guest down with them. Patch them on a schedule after moving or shutting down workloads, and keep tested backups.
  • Servers with out-of-tree kernel modules: a new kernel can break a driver that is built separately. Test those on a staging machine first.

A held package is a manual job you have now promised to do. Put it on a calendar and record it in your patch policy.

Make sure updates actually ran

A timer that silently failed months ago looks exactly like one that works. Check, and then automate the checking:

On Debian and Ubuntu:

systemctl status apt-daily-upgrade.timer
sudo tail -n 50 /var/log/unattended-upgrades/unattended-upgrades.log
ls /var/run/reboot-required 2>/dev/null && echo "Reboot pending"

On RHEL and AlmaLinux:

systemctl status dnf-automatic.timer
sudo journalctl -u dnf-automatic.service --since "7 days ago"
sudo dnf history list | head
sudo dnf needs-restarting -r

Then have your monitoring alert when:

  • security updates have been pending for more than a few days,
  • a reboot has been pending longer than your policy allows,
  • the update service failed, or no report email arrived on schedule,
  • a disk is nearly full (a common reason updates stop).

Review the update emails weekly; they are also your evidence for audits and cyber insurance questionnaires.

If you want automatic patching set up, staged and monitored across your Linux servers, request a free IT assessment. Core Florida IT manages and patches business servers for companies across Miami-Dade and South Florida through our server setup and repair and managed IT support services.

Sources

Keep reading

Let's make your IT the strongest part of your business.

Book a free, no-obligation IT assessment. We'll show you exactly where you stand and what to fix first.

Call Free assessment