Automatic Security Updates with unattended-upgrades
How to set up unattended-upgrades on Ubuntu Server for automatic security patches, plus the honest trade-off around automatic reboots you need to plan for.
13 December 2024 4 min read
Keeping an unmanaged VPS patched is entirely your responsibility – there’s no managed team doing it for you. unattended-upgrades is Ubuntu’s official tool for automating security patching, so you get critical fixes applied without having to log in and run apt upgrade yourself on a regular basis. Here’s how to set it up properly, including the trade-off that catches people out.
Installing it
On most Ubuntu Server installs, unattended-upgrades is already installed, but not necessarily enabled. Install (or reinstall) it with:
sudo apt update
sudo apt install unattended-upgrades apt-listchanges
Then run the configuration helper, which enables periodic updates and writes the base config for you:
sudo dpkg-reconfigure --priority=low unattended-upgrades
The two key config files
Two files control this feature, and it’s worth knowing what each one does.
/etc/apt/apt.conf.d/20auto-upgrades
This is the switch that turns periodic updating on and tells apt how often to run its checks. It should contain:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
The first line tells apt to refresh package lists daily; the second tells it to actually run unattended-upgrades daily. If dpkg-reconfigure didn’t create this file with those lines, add them yourself.
/etc/apt/apt.conf.d/50unattended-upgrades
This is where the actual behaviour is configured: which repositories are eligible for automatic upgrades, what gets excluded, notification settings, and reboot behaviour.
By default, the Allowed-Origins block is normally already set to cover security updates for your release, something like:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
};
Keeping automatic upgrades restricted to the security pocket, rather than also enabling the general updates pocket, is the safer default for a production server – it means you get security fixes automatically, while feature and non-security updates still wait for you to review and apply them manually.
Email notifications
To be told what’s been patched (or if something failed), set a mail address and, optionally, when to be notified – "always" sends a report after every run, "on-change" only sends one when something actually changed:
Unattended-Upgrade::Mail "you@example.com";
Unattended-Upgrade::MailReport "only-on-error";
This requires a working mail transport on the server (or a relay configured to send outbound mail) – if you haven’t set one up, the notification will simply fail to send, so it’s worth testing.
The trade-off: automatic reboots
Here’s the part that catches people out. Some security updates – most commonly kernel updates – require a reboot to take effect. By default, unattended-upgrades will not reboot your server automatically; it’ll patch the files and leave the reboot for you to do manually, which means a patched-but-still-vulnerable kernel can sit running for a while if nobody notices.
You can turn on automatic reboots, but be deliberate about it – an unscheduled reboot on a production VPS is downtime, and it will happen without warning if you don’t control the timing:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:30";
Automatic-Reboot is false by default and must be explicitly enabled. Automatic-Reboot-Time accepts "now" (reboot immediately if one is needed), a specific time in "hh:mm" format (reboot at the next occurrence of that time), or leave it unset to use the default of "now". For a production server, always set a specific low-traffic time rather than leaving it as "now" – you don’t want a reboot triggered in the middle of your busiest period.
If you’d rather not reboot automatically at all, you can instead check for pending reboots yourself as part of routine maintenance:
[ -f /var/run/reboot-required ] && cat /var/run/reboot-required
That file exists precisely when a reboot is pending, so it’s easy to check for in a script or monitoring job if you want visibility without ceding control of the reboot itself.
The honest summary
Enable unattended-upgrades restricted to security updates – it’s a genuinely low-effort way to close off a large class of risk on an unmanaged server. Decide deliberately on reboots: either enable them at a scheduled, low-traffic time, or leave them manual and make checking /var/run/reboot-required part of your routine. What you shouldn’t do is leave the defaults unconsidered – either accidentally never rebooting a patched kernel, or getting caught out by a reboot at an unpredictable moment.