How to enable automatic security updates¶
This guide makes a server install security updates on its own every day, and decides what happens when an update needs a reboot.
That's sound practice on Debian, Ubuntu and the RHEL family, whose security updates are small fixes backported to the release you run. It isn't on Arch and Gentoo: there, every update can be a new upstream version, and some need manual steps, so an unattended upgrade can leave the system broken with nobody watching. For those two, this guide automates the check (which updates and security advisories are pending) and leaves the upgrade to you. Patching strategy explains the reasoning.
Before you begin¶
- You have a shell with
sudoon the machine, and it can reach its package repositories. - Decide whether the machine may reboot itself after an update that needs it (a new kernel, or a core library). If services on it can't tolerate an unannounced reboot, keep automatic reboots off and schedule them yourself.
Test on a less important machine first
An automatic update can restart services or, with automatic reboots on, reboot the machine at the configured time. Turn this on for a test or staging machine first, and for production machines once you've seen a few days of updates go through. Have a way to reach the console in case a machine doesn't come back after a reboot.
Steps¶
-
Install the tools.
Ubuntu (cloud images and server installations) and Debian's cloud images already have
unattended-upgradesinstalled and enabled; the command does nothing there. A Debian server installed with the Debian installer usually doesn't have it.checkupdates(frompacman-contrib, which usesfakeroot) lists pending updates without touching the system's package database, andarch-auditlists installed packages with known vulnerabilities:<!-- verify-setup
A reader's Gentoo system has a Portage tree; the lab image doesn't.¶
emerge-webrsync -q →
glsa-check(fromapp-portage/gentoolkit) tests the system against Gentoo Linux Security Advisories, and a cron daemon runs it every day:sudo emerge --getbinpkg --noreplace app-portage/gentoolkit sys-process/cronie sudo rc-update add cronie default sudo rc-service cronie startWith the systemd profile (not verified), use
sudo systemctl enable --now cronie.serviceinstead of the last two commands. -
Turn on the daily job and choose what it installs.
Create the file
/etc/apt/apt.conf.d/20auto-upgradeswith this content, which makes APT refresh its package lists and rununattended-upgradeevery day:Which updates are installed is set by the origin patterns in
/etc/apt/apt.conf.d/50unattended-upgrades; the defaults are the ones you want here. Check them:- On Debian, the patterns select the security archive (
label=Debian-Security) and the release itself (label=Debian), which receives only point-release updates: tested bug and security fixes. - On Ubuntu,
Allowed-Originsselects the release pocket (which doesn't change after the release) and the-securitypocket, plus the Ubuntu Pro ESM security pockets if the machine is attached to Ubuntu Pro. Ordinary-updatesaren't installed automatically.
To keep a package from being upgraded automatically, add it to
Unattended-Upgrade::Package-Blacklistin a file of your own, as in the next step.In
/etc/dnf/automatic.conf, limit the job to security updates and let it apply them, not only download them:sudo sed -i -e 's/^upgrade_type = .*/upgrade_type = security/' -e 's/^apply_updates = .*/apply_updates = yes/' /etc/dnf/automatic.conf grep -E '^(upgrade_type|apply_updates|download_updates)' /etc/dnf/automatic.confupgrade_type = securityinstalls only updates that carry a security advisory (RHSA on RHEL, ALSA on AlmaLinux, RLSA on Rocky Linux).emit_via = stdio, the default, sends the job's report to the journal.Create a service that reports pending updates and fixed vulnerabilities, and downloads the packages so that the update you run later is quick. Create the file
/etc/systemd/system/check-updates.servicewith this content:[Unit] Description=Report pending package updates and security advisories Wants=network-online.target After=network-online.target [Service] Type=oneshot # checkupdates exits with 2 when there are no updates. SuccessExitStatus=2 ExecStart=/usr/bin/checkupdates --download ExecStart=/usr/bin/arch-audit --upgradablecheckupdates --downloadsyncs a temporary copy of the package database and downloads the new packages into pacman's cache; it never changes the installed system or its database, so it can't cause a partial upgrade.arch-audit --upgradablelists installed packages with vulnerabilities that a newer package already fixes.Then create a timer for it,
/etc/systemd/system/check-updates.timer:Create the file
/etc/cron.d/glsa-check, which syncs the Gentoo repository every morning and reports the security advisories that affect the system:# Sync the Gentoo repository and report the GLSAs that affect this system. MAILTO=root 30 5 * * * root /usr/sbin/emaint --auto sync >/dev/null && /usr/sbin/glsa-check --quiet --test all 2>&1 | grep -v 'not affected'Cron mails each run's output to
root, which needs a working mail transfer agent.glsa-checkreportsThis system is not affected by any of the listed GLSAseven with--quiet, so thegrep -vdrops that line, and cron sends mail only when there's something to read.emaint --auto syncuses the sync method configured in/etc/portage/repos.conf(or Portage's defaults). - On Debian, the patterns select the security archive (
-
Decide what happens when an update needs a reboot.
By default
unattended-upgradesnever reboots: it installs a new kernel, and you reboot when convenient. (On Ubuntu the file/run/reboot-requiredappears when a reboot is pending.) To let the machine reboot itself at a quiet time when an update requires it, create the file/etc/apt/apt.conf.d/52unattended-upgrades-local:// Local settings; later files override 50unattended-upgrades. Unattended-Upgrade::Automatic-Reboot "true"; Unattended-Upgrade::Automatic-Reboot-Time "04:00";Leave this file out to keep reboots manual.
By default
dnf-automaticnever reboots (reboot = never). To reboot when an installed update needs it, such as a new kernel or core library:The reboot is run with
reboot_command, by defaultshutdown -r +5with a message to logged-in users. Leave the setting atneverto keep reboots manual;sudo dnf needs-restarting -rtells you whether one is pending.Nothing is installed automatically, so there's nothing to reboot for. After you update, reboot if the update included the kernel package (
linux, or the one you use, such aslinux-lts): the running kernel stays the old one until you do.Nothing is installed automatically, so there's nothing to reboot for. After you update, a reboot is needed if you installed and selected a new kernel.
-
Enable the schedule.
The daily runs are started by
apt-daily.timer(package lists) andapt-daily-upgrade.timer(upgrades), which are enabled by default. Check:The upgrade runs at 06:00 plus a random delay of up to an hour, unless you change the timer with
sudo systemctl edit apt-daily-upgrade.timer.The timer runs at 06:00 plus a random delay of up to an hour. Don't also enable
dnf-automatic-install.timeror the other variants: they do the same job with fixed settings, overridingapply_updates.Cronie reads
/etc/cron.d/by itself; no further step is needed.
Verify¶
Run unattended-upgrade once in dry-run mode, which shows the origins it allows and what it would install, without installing anything:
$ sudo unattended-upgrade --dry-run --debug
...
Allowed origins are: origin=Debian,codename=trixie,label=Debian, origin=Debian,codename=trixie,label=Debian-Security, origin=Debian,codename=trixie-security,label=Debian-Security
...
pkgs that look like they should be upgraded:
...
After the first real run, the log is in /var/log/unattended-upgrades/unattended-upgrades.log, and the packages it installed are listed in /var/log/apt/history.log.
See which security updates are pending, which is what the next run will install:
After the first run, read its report in the journal:
Run the check once and read its report:
When the report shows updates, read the Arch Linux news for any manual steps, then update the whole system at once with sudo pacman -Syu, and reboot if the kernel was updated.
Test the system against the advisories now:
When advisories affect the system, read the news (eselect news read), then update with sudo emerge --ask --update --deep --newuse @world, merge configuration changes with dispatch-conf, and rebuild or restart what the update affected.
Troubleshooting¶
Debian or Ubuntu doesn't install anything, although updates are available.
Run sudo unattended-upgrade --dry-run --debug and look for the package: it's skipped if its origin doesn't match the patterns, if it's held or blacklisted, or if upgrading it would prompt about a changed configuration file.
Check that /etc/apt/apt.conf.d/20auto-upgrades contains both lines with "1".
dnf-automatic downloads updates but doesn't install them.
Check apply_updates = yes in /etc/dnf/automatic.conf, and that only dnf-automatic.timer is enabled (systemctl list-timers 'dnf-automatic*'): dnf-automatic-download.timer and dnf-automatic-notifyonly.timer never install.
The machine rebooted unexpectedly.
Automatic reboots are on. Check Unattended-Upgrade::Automatic-Reboot (Debian and Ubuntu, with apt-config dump) or reboot in /etc/dnf/automatic.conf, and the times in Automatic-Reboot-Time or the dnf-automatic.timer schedule.
checkupdates fails with Cannot find the fakeroot binary.
Install fakeroot, as in step 1.
Related¶
- Explanation: Patching strategy
- Explanation: How PAM works
- How-to guide: How to harden the SSH server