Set Up Automatic Security Updates on Ubuntu with unattended-upgrades
Configure Ubuntu's unattended-upgrades to install security patches automatically: a minimal Allowed-Origins override, dry-run verification, and the silent-failure mistakes to avoid.
16 Sept 2025, 20:51 UTC

If you want Ubuntu to install security patches without you logging in, the supported answer is unattended-upgrades: a package that runs during a scheduled window, reads a config file listing which APT origins may auto-install, and applies those updates quietly. It ships with Ubuntu Server and Desktop, so for most systems the job is configuration, not installation. This guide shows a minimal, security-only setup, explains how the mechanism actually decides what to install, and covers the limits and mistakes that cause silent failure.
Confirm the package and service exist
Run these on the target machine (a normal user shell is fine for checks; configuration edits need sudo):
dpkg -l | grep unattended-upgrades
systemctl status unattended-upgrades.service
If the package is missing, install it with sudo apt install unattended-upgrades. The service is normally triggered by a systemd timer (apt-daily-upgrade.timer) rather than running constantly, so an "inactive (dead)" status between runs is expected, not a fault.
How the mechanism decides what to install
Two files matter:
/etc/apt/apt.conf.d/50unattended-upgrades— the main configuration, including theAllowed-Originslist./etc/apt/apt.conf.d/20auto-upgrades— the on/off switch read by the daily APT jobs.
APT assigns every repository an "origin" and "archive" (also called suite), visible via apt-cache policy. unattended-upgrades only installs packages whose repository matches an entry in Allowed-Origins. This is the key control: you are not saying "update everything," you are saying "only update packages that come from these trusted pockets." For Ubuntu, the security pocket is typically expressed as ${distro_id}:${distro_codename}-security, which resolves to something like Ubuntu:jammy-security.
Worked configuration: security updates only
Rather than editing the shipped 50unattended-upgrades (which a package update may prompt about), drop in an override file. Files in apt.conf.d are read in lexical order, and later values win. Create /etc/apt/apt.conf.d/51my-unattended with sudo:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::Remove-Unused-Dependencies "false";
Unattended-Upgrade::Automatic-Reboot "false";
Then make sure the daily switch is on in /etc/apt/apt.conf.d/20auto-upgrades:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
The first line refreshes package lists daily; the second permits the unattended run. Both are required — enabling the upgrade without the list refresh means the tool evaluates stale metadata.
Two deliberate choices above: Automatic-Reboot "false" means kernel updates are installed but the machine never reboots itself, so you control when the new kernel takes effect (watch for /var/run/reboot-required). Leaving unused-dependency removal off avoids the tool auto-removing a package that a manually built tool silently depends on.
Verify before and after
Do not trust the config by inspection. Preview the decision logic with a dry run (needs sudo, safe to run anytime — it changes nothing):
sudo unattended-upgrade --dry-run --debug
The debug output shows which origins were matched and which packages, if any, would be installed. If nothing is pending, the run exits quietly — that is a pass, not an error. After real runs, check the log:
less /var/log/unattended-upgrades/unattended-upgrades.log
You should see entries naming the packages installed and noting whether a reboot is required. If the log is empty for days while apt list --upgradable shows pending security updates, something is misconfigured — usually an origin string mismatch.
Limits
- APT only. Snap packages update through snapd's own schedule, and Flatpak/AppImage/third-party tarballs are untouched. A fully patched system needs those channels handled separately.
- Matching repositories only. A PPA or vendor repo is not auto-updated unless you add its exact origin string to
Allowed-Origins— find it withapt-cache policy. - Disk space. A full
/bootor root filesystem causes failed kernel installs. Checkdf -h /bootperiodically on long-lived servers. - Running services. Library updates restart some services via needrestart, but long-running processes may keep old libraries mapped until restarted. Plan restarts for stateful services like databases.
Common mistakes
- Guessing origin strings. Writing
Ubuntu:securityinstead ofUbuntu:jammy-securitymatches nothing and fails silently. Always copy the exacto=anda=values fromapt-cache policyoutput. - Editing only one of the two files. A perfect
Allowed-Originslist does nothing ifAPT::Periodic::Unattended-Upgradeis not"1". - Disabling the timer. Masking
apt-daily-upgrade.timer(sometimes done to stop "apt lock" conflicts) disables unattended upgrades entirely. - Enabling aggressive cleanup blindly.
Remove-Unused-Packages "true"can remove kernels or dependencies that locally compiled software needs. Review withapt autoremove --dry-runbefore enabling anything similar. - Assuming config changes apply instantly. The new rules take effect on the next timer run; force an immediate check with the dry-run command above rather than waiting and hoping.
With the override file, the periodic switch, and one verified dry run, you have a security-only auto-update setup that is easy to audit and easy to extend later by adding more origins deliberately.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.