Debian GNU/Linux · Packages & updates

Install security updates automatically

When it fails: Security updates are not installed automatically. Fixes wait for a human to apply them, often for weeks, while the vulnerabilities they close are public.

CB-DEB-PKG-007mediumactiveautomatedautomated fixprofile core

As released in v0.1.0 beta · pre-release. Current state.

Description

unattended-upgrades installs available updates without human action. Two systemd timers drive it: apt-daily.timer refreshes the package lists and apt-daily-upgrade.timer installs the updates, when APT::Periodic::Update-Package-Lists and APT::Periodic::Unattended-Upgrade are not 0. Which updates are installed is set by Unattended-Upgrade::Origins-Pattern; Debian's default includes the security suite.

Installed and enabled by default on the Debian 12 and 13 cloud images. A Debian installer setup installs it only when chosen during installation.

Rationale

Most compromises exploit vulnerabilities for which a fix already exists. Installing security fixes daily and automatically closes that window without depending on a manual process. Debian security updates are minimal backported fixes, designed to be installed without review.

Impact

Services are restarted by their package when updated, which can cause a short interruption. The system is not rebooted (Unattended-Upgrade::Automatic-Reboot is false by default), so kernel and libc fixes still need a planned reboot. Organisations that deploy updates with a central patch management tool can exclude this control in their tailoring file and document it.

Setting

Location/etc/apt/apt.conf.d/20auto-upgrades, /etc/apt/apt.conf.d/50unattended-upgrades
DefaultEnabled on cloud images, depends on the installer choice otherwise
Recommendedunattended-upgrades installed, both APT::Periodic options set to 1, security origin allowed, timers enabled

Audit

  1. dpkg -s unattended-upgrades shows Status: install ok installed.
  2. apt-config dump APT::Periodic shows Update-Package-Lists and Unattended-Upgrade set to 1 (or another non-zero value).
  3. apt-config dump Unattended-Upgrade::Origins-Pattern contains label=Debian-Security or a -security codename.
  4. systemctl is-enabled apt-daily.timer apt-daily-upgrade.timer prints enabled twice.
  5. unattended-upgrade --dry-run --debug lists the security origin among the allowed ones.

Automated: every check must pass. Scanners report each check by its id.

package

unattended-upgrades package.

name: unattended-upgrades
state: installed

periodic

APT::Periodic options, as merged by apt-config.

script: |
  eval "$(apt-config shell L APT::Periodic::Update-Package-Lists U APT::Periodic::Unattended-Upgrade)" || exit 3
  echo "Update-Package-Lists=${L:-unset} Unattended-Upgrade=${U:-unset}"
  case ${L:-0}:${U:-0} in 0:* | *:0 | false:* | *:false | no:* | *:no) exit 1 ;; esac

origins

Origins allowed to unattended-upgrades.

script: |
  o=$(apt-config dump Unattended-Upgrade::Origins-Pattern Unattended-Upgrade::Allowed-Origins 2>/dev/null | grep -E '::(Origins-Pattern|Allowed-Origins):: ')
  printf '%s\n' "$o" | grep -Ei 'Debian-Security|-security' || { echo "no security origin allowed"; exit 1; }

lists-timer

Timer that refreshes the package lists.

unit: apt-daily.timer
state: enabled

upgrade-timer

Timer that installs the updates.

unit: apt-daily-upgrade.timer
state: enabled

Remediation

  1. apt-get install unattended-upgrades.
  2. Write /etc/apt/apt.conf.d/20auto-upgrades with APT::Periodic::Update-Package-Lists "1"; and APT::Periodic::Unattended-Upgrade "1"; (this is what dpkg-reconfigure -plow unattended-upgrades does), and remove any later setting to 0.
  3. If Unattended-Upgrade::Origins-Pattern was customised, add back "origin=Debian,codename=${distro_codename}-security,label=Debian-Security"; in /etc/apt/apt.conf.d/50unattended-upgrades.
  4. systemctl enable --now apt-daily.timer apt-daily-upgrade.timer.
Restartnone
Disruptionlow

Rollback

Set both APT::Periodic options to 0 in /etc/apt/apt.conf.d/20auto-upgrades, or purge unattended-upgrades.

package

Generated from check package: the engine writes the fix for every output, it sets the expected value and the check runs again after.

periodic

f=/etc/apt/apt.conf.d/20auto-upgrades
cb_backup "$f"
printf '%s\n' 'APT::Periodic::Update-Package-Lists "1";' 'APT::Periodic::Unattended-Upgrade "1";' >"$f"

lists-timer

Generated from check lists-timer: the engine writes the fix for every output, it sets the expected value and the check runs again after.

upgrade-timer

Generated from check upgrade-timer: the engine writes the fix for every output, it sets the expected value and the check runs again after.

Handwritten code reads parameters from CB_<NAME> environment variables. Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.

References

Mappings

FrameworkIDRelationNote
ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0R61partialR61 asks for a regular and reactive security update process; this control automates the Debian part of it.
NIST SP 800-53 Rev. 55.1.1SI-2(5)equivalent

How this control relates to the other framework's: equivalent, stricter, looser, partial or related.

Threats mitigated

People and lifecycle

Authors
Verified2026-10-18 by Sn0wAlice on 12, Proxmox VM, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64. Passes on stock; purged package, missing 20auto-upgrades and disabled upgrade timer detected; fix reinstalls, rewrites 20auto-upgrades and enables the timer; kept after reboot.
Verified2026-10-18 by Sn0wAlice on 13, Proxmox VM, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64. Passes on stock; purged package, missing 20auto-upgrades and disabled upgrade timer detected; fix reinstalls, rewrites 20auto-upgrades and enables the timer; kept after reboot.
Introduced inv0.1.0
Created, updated2026-10-18, 2026-10-18
Translationsfr