Tutorial

Automatic Security Updates on Debian/Ubuntu VPS

Security & Monitoring10 min read5 steps

A VPS exposed to the internet without an update policy is an open attack surface. Critical vulnerabilities are exploited within hours of a CVE being published, long before any manual intervention is possible. Configuring **unattended-upgrades** on every Debian or Ubuntu server in your fleet is the simplest way to mechanically reduce that exposure window, without giving up control over what gets applied.

Contents· Why automate security patches1/10
  1. 01Why automate security patches
  2. 02Concrete benefits for agencies managing a client fleet
  3. 03How unattended-upgrades works
  4. 04Prerequisites
  5. 05Install and configure unattended-upgrades
  6. 06Configuring email notifications
  7. 07Monitor required reboots with needrestart
  8. 08Automatic reboot for kernel patches
  9. 09Manual vs automatic updates: comparison
  10. 10Deploy and manage unattended-upgrades across a multi-VPS fleet

Why automate security patches

The lifecycle of a vulnerability is short. Between the publication of a critical CVE and the first mass exploitation attempts, the window is now measured in hours. For an agency managing ten, twenty, or fifty VPS instances, waiting for a scheduled manual intervention each week means offering several days of exposure on every machine.

Regulation reinforces this requirement. The European Cyber Resilience Act requires operators of connected products to demonstrate a documented and enforced patch policy. For agencies hosting client applications, the absence of patch traceability may engage their contractual liability in the event of an incident.

The technical argument is straightforward: the majority of Linux server compromises exploit vulnerabilities for which a patch has been available for more than 30 days. The unattended-upgrades tool, included in Debian and Ubuntu repositories, automatically installs security patches from official repositories — without touching major version upgrades or packages you have explicitly excluded.

Concrete benefits for agencies managing a client fleet

  • Reduced remediation time: security patches are applied within hours of publication in stable repositories, without a maintenance ticket.
  • Automatic traceability: each installation is recorded in /var/log/unattended-upgrades/, available at any time for an audit or client report.
  • Controlled scope: only updates labelled security are applied by default — version upgrades remain under manual control.
  • Reduced operational burden: a fleet of 50 VPS no longer requires 50 weekly SSH connections for apt upgrade.
  • Documentable compliance: the policy is defined in a versionable configuration file, reproducible via Ansible or any configuration management tool.
  • Targeted notifications: installation errors or required reboots can trigger an email, without flooding the team with routine reports.

How unattended-upgrades works

unattended-upgrades is a Debian/Ubuntu daemon that runs via a systemd timer (or cron on older systems). It queries the configured APT repositories, filters packages according to the allowed origins defined in its configuration, then installs updates without user interaction.

The filtering logic relies on APT Release files. Each repository exposes metadata (Origin, Suite, Codename) that unattended-upgrades compares against its whitelist. By default on Ubuntu, only the ${distro_id}:${distro_codename}-security origins are enabled — which corresponds exactly to the official Canonical security archives, without including backport updates or third-party packages.

The process runs in three phases: updating the APT cache (apt-get update), resolving dependencies for eligible packages, installing with detailed logging. In case of error (dependency conflict, locked package, insufficient disk space), the installation stops and a notification can be sent according to the configuration. System integrity is never compromised: unattended-upgrades never forces conflict resolution.

Prerequisites

The configuration described in this article applies to Debian 11/12 and Ubuntu 22.04/24.04 LTS. Older systems (Debian 10, Ubuntu 20.04) are compatible but their upstream support is approaching end of life — a migration is recommended before investing in their configuration.

Required access: SSH connection with root rights or a sudo account. No external dependencies are needed for basic operation; SMTP configuration is optional and only comes into play for email notifications.

If you manage your fleet with Ansible, the steps described below can be reproduced directly in a dedicated role — the configuration file structure is stable across major versions of Debian and Ubuntu.

Install and configure unattended-upgrades

  1. Install the package

    On Debian and Ubuntu, the package is available in standard repositories:

    apt-get update
    apt-get install -y unattended-upgrades apt-listchanges

    The apt-listchanges package is optional but recommended: it allows including a change summary in email notifications.

  2. Configure allowed origins

    Edit /etc/apt/apt.conf.d/50unattended-upgrades. The Unattended-Upgrade::Allowed-Origins section controls which repositories are eligible. On Ubuntu 22.04, the recommended minimal configuration:

    Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}-security";
        "${distro_id}ESMApps:${distro_codename}-apps-security";
        "${distro_id}ESM:${distro_codename}-infra-security";
    };

    On Debian 12, replace with:

    Unattended-Upgrade::Allowed-Origins {
        "Debian:${distro_codename}-security";
    };

    To exclude sensitive packages (for example a custom kernel or a pinned PHP version):

    Unattended-Upgrade::Package-Blacklist {
        "linux-image";
        "php8.2-fpm";
    };
  3. Enable the periodic timer

    The file /etc/apt/apt.conf.d/20auto-upgrades controls execution frequency. Create it or verify its contents:

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

    The value "1" means daily execution. On Ubuntu, the apt-daily-upgrade.timer service is enabled automatically after this configuration. Check its status:

    systemctl status apt-daily-upgrade.timer
  4. Check the logs

    Installation logs are written to /var/log/unattended-upgrades/. The main file:

    tail -50 /var/log/unattended-upgrades/unattended-upgrades.log

    A successful line looks like:

    2026-09-25 04:12:31,847 INFO Packages that will be upgraded: libssl3 openssl
    2026-09-25 04:12:45,021 INFO Package libssl3 upgraded to 3.0.2-0ubuntu1.17

    In case of failure, the unattended-upgrades-dpkg.log file retains the full dpkg output for diagnosis.

  5. Test on-demand execution

    To trigger an immediate run without waiting for the timer and verify the configuration is operational:

    unattended-upgrade --dry-run --debug 2>&1 | head -60

    The --dry-run option simulates installation without making any changes. Remove it for a real execution:

    unattended-upgrade -v

    If the output shows No packages found that can be upgraded unattended, the system is up to date or no eligible package is waiting — this is the expected result on a recently provisioned server.

Configuring email notifications

Email notifications allow the team to receive an alert when an update fails or when a reboot is required. They send nothing on silent success — which avoids flooding the inbox with daily reports.

In /etc/apt/apt.conf.d/50unattended-upgrades, enable the option:

Unattended-Upgrade::Mail "[email protected]";
Unattended-Upgrade::MailReport "only-on-error";

The only-on-error value (recommended) only sends an email in case of error. The on-change value sends an email with each installation. The always value sends an email even when nothing is installed — avoid this on a fleet of several dozen machines.

For sending to work, the server must have a local MTA capable of relaying emails. On a minimal VPS, postfix in satellite mode is the lightest option:

apt-get install -y postfix
# Choose "Satellite system" in the wizard
# Enter the SMTP relay of your provider or infrastructure

Alternatively, msmtp can serve as a relay to a transactional service (Mailgun, Postmark, SendGrid) without installing a full MTA.

Monitor required reboots with needrestart

Some security patches — especially those for the kernel, libc, or OpenSSL — require a reboot to be fully active. The needrestart tool detects services and processes still using the old versions in memory.

Install it with:

apt-get install -y needrestart

After each update, needrestart lists the services to restart. In automatic mode ($nrconf{restart} = 'a'; in /etc/needrestart/needrestart.conf), it restarts the affected services without intervention. For kernels, it never reboots the machine automatically without explicit configuration — this is the expected behavior on a production VPS.

Combine needrestart with unattended-upgrades notifications: an email indicating that a reboot is required allows the team to schedule the intervention at the right time, without urgency but without delay.

Automatic reboot for kernel patches

Automatic reboot after a kernel patch is the most delicate decision in an update policy. It ensures the fix is active immediately, but it interrupts running services — which may be unacceptable for certain workloads.

In /etc/apt/apt.conf.d/50unattended-upgrades, the relevant options:

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";

Automatic-Reboot-Time schedules the reboot at an off-peak hour. Automatic-Reboot-WithUsers "false" prevents rebooting if a user session is open — useful for development machines, less relevant for a production server without permanent interactive connections.

Essential precautions before enabling this option:
- Verify that your services restart automatically at boot (systemctl is-enabled <service>).
- Test the full reboot time on a staging server before deploying to production.
- If your application requires a specific startup order (database before application), document and test this scenario.
- For a multi-VPS fleet, stagger reboot times — see the next section.

Manual vs automatic updates: comparison

Scroll the table

CriterionManual updateAutomatic update (unattended-upgrades)
Application delayDepends on maintenance schedule — often 3 to 7 daysA few hours after publication in stable repositories
TraceabilityDepends on the thoroughness of maintenance notesAutomatic timestamped log in `/var/log/unattended-upgrades/`
Regression riskControlled: each update is validated before applicationLow on stable security patches, mitigated by blacklist
Operational burdenHigh on a fleet of more than 5 VPSNegligible once the configuration is deployed
Active kernel patchesImmediate if reboot is scheduledRequires automatic reboot configuration or manual intervention
Critical CVE coverageInsufficient if the cycle is weeklyOptimal — patches are applied in the narrowest possible window
Documentable complianceDifficult to prove without additional toolingLog files and versionable, auditable configuration

Deploy and manage unattended-upgrades across a multi-VPS fleet

The configuration described so far applies to a single server. For a fleet of dozens of client VPS instances, reproducibility and coordination become challenges in their own right.

Automate with Ansible

A simple Ansible role is sufficient to deploy the configuration across the entire fleet in minutes. Store the 50unattended-upgrades and 20auto-upgrades files in templates/ and make reboot options configurable via inventory variables:

- name: Deploy unattended-upgrades
  hosts: vps_clients
  become: true
  tasks:
    - name: Install unattended-upgrades
      apt:
        name: [unattended-upgrades, apt-listchanges]
        state: present
        update_cache: true
    - name: Deploy configuration
      template:
        src: 50unattended-upgrades.j2
        dest: /etc/apt/apt.conf.d/50unattended-upgrades
        owner: root
        mode: '0644'
    - name: Deploy apt-periodic
      copy:
        src: 20auto-upgrades
        dest: /etc/apt/apt.conf.d/20auto-upgrades
        owner: root
        mode: '0644'

Stagger reboots

If automatic reboot is enabled, do not configure the same time on all your servers. A simultaneous reboot of 30 VPS can generate unusual reconnection load on your infrastructure and complicate diagnosis if problems arise. Distribute times over a two-hour window (02:00 to 04:00) using an Ansible variable per group or per server.

Test on staging before the production fleet

For configurations that enable automatic reboot or modify the package blacklist, validate first on a representative staging server. A VPS at 99 DH/month dedicated to configuration testing avoids propagating a configuration error across the entire fleet.

Centralize alerts

Rather than receiving individual emails from each server, configure an email alias that aggregates alerts into a single monitoring channel. If your infrastructure already uses a log aggregator (Loki, OpenSearch), unattended-upgrades log files can be forwarded there via a lightweight agent for a centralized fleet view.

For more on securing your VPS, see our Linux hardening checklist and our CrowdSec vs Fail2ban comparison. If you also manage self-hosted applications, the self-hosted application patch routine complements this approach with the application layers.

Manage a client VPS fleet without friction

ServOrbit.com offers managed VPS from 99 DH/month, with automated provisioning and a centralized dashboard for agencies and resellers.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab