Skip to content
Serverküche
Search

Loading search … (only available on the published site).

Security Difficulty: Beginner

unattended-upgrades: automatic security updates for Debian

Debian installs security updates automatically: set up unattended-upgrades, control the reboot, and verify it really runs.

· 5 min read ·Duration: approx. 20 minutes
Table of contents

“Remember to install updates weekly” – this sentence from the maintenance sections of the other tutorials is the first one people forget. That’s exactly why the server now takes it over itself: unattended-upgrades installs security updates automatically. That closes the most dangerous gap in self-hosting – the server that runs unpatched for months.

What are we building?

By the end, your Debian 13 automatically pulls security updates daily and installs them without your involvement. You decide whether and when the server reboots for necessary kernel updates, and you know how to verify that the automation really kicks in. What gets automated are security updates and the conservative stable point releases; larger upgrades of your other software stay deliberately in your hands.

Prerequisites

Step by step

Step 1: Install the package

Terminal
sudo apt update
sudo apt install -y unattended-upgrades apt-listchanges

apt-listchanges shows the changelogs on updates – useful if you later do check manually what changed.

Step 2: Enable the automation

The simplest way to switch on the daily run:

Terminal
sudo dpkg-reconfigure -plow unattended-upgrades

Choose Yes in the dialog. That creates the file /etc/apt/apt.conf.d/20auto-upgrades with this content:

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

The 1 means “daily”: update package lists and run unattended upgrades. It’s triggered via the systemd timers apt-daily.timer (package lists) and apt-daily-upgrade.timer (upgrade run) – no separate cron job needed.

Step 3: Define what gets updated

Take a look at /etc/apt/apt.conf.d/50unattended-upgrades:

Terminal
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

On Debian 13, three sources are active in the Origins-Pattern block by default:

INI
Unattended-Upgrade::Origins-Pattern {
  "origin=Debian,codename=${distro_codename},label=Debian";
  "origin=Debian,codename=${distro_codename},label=Debian-Security";
  "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
};

The two Debian-Security lines ensure timely security updates – the actual purpose. The first line (label=Debian) covers the conservative stable updates that only arrive with Debian point releases; so it’s not a risky rolling update, but well-seasoned. If you really want only security updates, comment out the first line with //.

Two options are worth setting explicitly here. Clean up old kernels/packages automatically, otherwise /boot eventually fills up (Remove-Unused-Kernel-Packages is already the default in code, but only appears commented out in the file – set explicitly, the decision is documented):

INI
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";

And the most important point – the automatic reboot:

INI
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";

Automatic reboot – decide deliberately

Some security updates (especially kernel) only take effect after a reboot. With Automatic-Reboot "true" the server then reboots on its own – always set an Automatic-Reboot-Time when you do: without it, the server reboots immediately after the upgrade run (the code default is "now"; the 02:00 in the example file is only a commented-out suggestion). Choose a time with low usage. If you want no automatic reboots, leave the option at "false" and reboot yourself when /var/run/reboot-required exists. Both are defensible – it just has to be a deliberate decision.

For the automatic reboot to be able to trigger on Debian at all, one building block is still missing: unattended-upgrades only reboots if the marker file /var/run/reboot-required exists – and Debian 13 does not create it on kernel updates by default (the responsible hook comes from an Ubuntu helper package that doesn’t exist in Debian; only individual packages like dbus set the file themselves). A two-liner closes the gap:

Terminal
sudo tee /etc/kernel/postinst.d/zz-reboot-required > /dev/null <<'EOF'
#!/bin/sh
touch /var/run/reboot-required
EOF
sudo chmod +x /etc/kernel/postinst.d/zz-reboot-required

The hook runs after every kernel installation and sets the marker file. From now on, both Automatic-Reboot and the manual check of /var/run/reboot-required work reliably – without the hook, the automatic reboot would simply never trigger on kernel updates.

Step 4: Do a dry run

Test what unattended-upgrades would do, without a real installation:

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

In the debug output, this line is decisive (on a fresh Debian 13, shortened):

Ausgabe
Allowed origins are: origin=Debian,codename=trixie,label=Debian, origin=Debian,codename=trixie,label=Debian-Security, origin=Debian,codename=trixie-security,label=Debian-Security
[...]
No packages found that can be upgraded unattended and no pending auto-removals

The Debian-Security sources must appear there. If something is listed, the configuration applies; if the run finds nothing to do (as above), there’s simply no security update pending right now.

When things go wrong

The dry run reports No packages found that can be upgraded unattended. Usually perfectly normal – no security update is currently pending. Check the configuration anyway via the Allowed origins are: line in the --debug run. If no security origins appear there, the Origins-Pattern from step 3 isn’t right.

Updates come, but the server never reboots despite a kernel update. Either Automatic-Reboot is set to "false" (default) – then set it to "true" (step 3) – or the marker file is never set because the kernel hook /etc/kernel/postinst.d/zz-reboot-required from step 3 is missing. Without it, Debian doesn’t create /var/run/reboot-required on kernel updates, and the automatic reboot never triggers.

/boot fills up, updates fail. Old kernels pile up. Set Remove-Unused-Kernel-Packages "true" (step 3); clean up once with sudo apt autoremove --purge.

A package is stubbornly held back (kept back). unattended-upgrades doesn’t install updates that would remove other packages. You resolve such cases deliberately by hand with sudo apt upgrade and check what happens.

Maintenance & backups

  • Still check anyway: automation doesn’t replace attention. Take a monthly look at the log /var/log/unattended-upgrades/unattended-upgrades.log and occasionally run sudo apt update && sudo apt upgrade for the non-security-critical updates.
  • Plan for reboots: if you use automatic reboots, make sure your services survive a reboot cleanly (restart: unless-stopped in Docker Compose if you run containers).
  • No dedicated backup needed, but note whether you enabled automatic reboots – it later explains why the server was briefly gone at night.

Last updated: Jul 19, 2026

You might also like

Hardening SSH access
Security Beginner

Hardening SSH access

Key-based login instead of passwords and no root login: the most important moves to harden the front door to your …

· 4 min read
Installing Docker on Debian
Containers Beginner

Installing Docker on Debian

Install Docker Engine and Docker Compose cleanly from the official repository – the foundation for most self-hosting …

· 3 min read
First steps with a netcup VPS
Basics Beginner

First steps with a netcup VPS

From a freshly ordered netcup server to a ready-to-use system: SSH login, system updates, a sudo user and the most …

· 4 min read