Automatic Security Updates

    Enable automatic security patching across all major Linux distributions on your Cloud VPS

    Unpatched software is one of the most common attack vectors in cloud VPS environments. When a critical vulnerability is disclosed, the window between public disclosure and active exploitation can be measured in hours. Automatic security updates ensure patches are applied as soon as they become available, dramatically reducing your exposure.

    Note: Automatic updates apply to security patches only. Kernel updates typically require a reboot. Consider live-patching solutions such as KernelCare, Canonical Livepatch, or kpatch to avoid scheduled reboots.

    1

    Quick Reference

    DistributionToolPackage ManagerUpdate Method
    Ubuntu / Debianunattended-upgradesaptBuilt-in
    RHEL / AlmaLinux / Rockydnf-automaticdnfBuilt-in
    CentOS Stream 9dnf-automaticdnfBuilt-in
    Fedoradnf-automaticdnfBuilt-in
    openSUSE / SLESzypper + cronzypperCron-based
    Arch Linuxpacman + timerpacmanManual setup
    2

    Prerequisites

    • Root or sudo access to the VPS instance
    • A working network connection with DNS resolution configured correctly
    • Package repositories enabled and reachable — run a manual update first to confirm
    • A valid email address or notification endpoint (optional but recommended) for update alerts
    • A recent snapshot or backup of the VPS before enabling automatic updates for the first time
    3

    Ubuntu and Debian

    Ubuntu and Debian use the unattended-upgrades package, which integrates tightly with APT. Ubuntu ships with this pre-installed on most cloud images, while Debian may require manual installation.

    Installation

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

    Configuration

    Edit /etc/apt/apt.conf.d/50unattended-upgrades:

    Ubuntu — Enable security origins
    Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}-security";
    };
    Debian — Enable security origins
    Unattended-Upgrade::Origins-Pattern {
        "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
    };

    Optional: Automatic Reboot

    Auto-reboot after kernel updates
    Unattended-Upgrade::Automatic-Reboot "true";
    Unattended-Upgrade::Automatic-Reboot-Time "03:00";

    Optional: Email Notifications

    Configure email alerts
    Unattended-Upgrade::Mail "admin@example.com";
    Unattended-Upgrade::MailReport "on-change";

    Remove Unused Dependencies

    Auto-cleanup old packages
    Unattended-Upgrade::Remove-Unused-Dependencies "true";
    Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

    Enable the Update Timer

    Create /etc/apt/apt.conf.d/20auto-upgrades
    APT::Periodic::Update-Package-Lists "1";
    APT::Periodic::Unattended-Upgrade "1";
    APT::Periodic::Download-Upgradeable-Packages "1";
    APT::Periodic::AutocleanInterval "7";

    Alternatively, enable defaults interactively: sudo dpkg-reconfigure -plow unattended-upgrades

    Verification

    Test and verify
    # Dry-run to confirm configuration
    sudo unattended-upgrades --dry-run --debug
    
    # Check logs for past updates
    cat /var/log/unattended-upgrades/unattended-upgrades.log
    journalctl -u apt-daily-upgrade.service
    
    # Check timer status
    systemctl status apt-daily-upgrade.timer
    4

    RHEL, AlmaLinux, and Rocky Linux

    These distributions use dnf-automatic to handle automated package updates, wrapping DNF with a systemd timer.

    Installation

    Install dnf-automatic
    sudo dnf install -y dnf-automatic

    Configuration

    Edit /etc/dnf/automatic.conf:

    Apply security updates only
    [commands]
    upgrade_type = security
    apply_updates = yes
    download_updates = yes

    Email Notifications

    Configure email delivery
    [emitters]
    emit_via = email
    
    [email]
    email_from = root@yourvps.example.com
    email_to = admin@example.com
    email_host = localhost

    For logging only (no email), set emit_via = stdio and review output in the journal.

    Enable and Verify

    Enable the install timer
    sudo systemctl enable --now dnf-automatic-install.timer
    
    # Verify
    sudo systemctl status dnf-automatic-install.timer
    sudo dnf updateinfo list security
    journalctl -u dnf-automatic-install.service

    💡 Timer variants: dnf-automatic.timer (download only), dnf-automatic-install.timer (download and install), dnf-automatic-notifyonly.timer (notify only). Use the -install variant for fully automatic patching.

    5

    CentOS Stream 9

    CentOS Stream 9 follows the same dnf-automatic workflow as RHEL. Install dnf-automatic, configure /etc/dnf/automatic.conf with upgrade_type = security and apply_updates = yes, then enable the dnf-automatic-install.timer.

    The only notable difference is that CentOS Stream tracks slightly ahead of RHEL releases, so security patches may appear in the repositories a few days earlier.

    6

    Fedora

    Fedora also uses dnf-automatic with the same configuration file and timer structure as RHEL. Fedora's faster release cycle means security updates are frequent.

    Install and enable
    sudo dnf install -y dnf-automatic
    sudo nano /etc/dnf/automatic.conf
    # Set: upgrade_type = security, apply_updates = yes
    
    sudo systemctl enable --now dnf-automatic-install.timer
    Verify
    sudo systemctl list-timers dnf-*
    sudo dnf updateinfo list security

    ⚠️ Fedora Lifecycle: Fedora releases are supported for approximately 13 months. Ensure you upgrade to the next release before end-of-life using sudo dnf system-upgrade.

    7

    openSUSE and SLES

    openSUSE Leap, Tumbleweed, and SUSE Linux Enterprise Server use zypper. Automatic security updates can be configured using a systemd timer or a cron job.

    Method 1: Systemd Timer (Recommended)

    Create /etc/systemd/system/zypper-security-update.service
    [Unit]
    Description=Automatic zypper security patch
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/zypper --non-interactive patch --category security
    Create /etc/systemd/system/zypper-security-update.timer
    [Unit]
    Description=Daily security patch timer
    
    [Timer]
    OnCalendar=*-*-* 03:30:00
    RandomizedDelaySec=1800
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    Enable the timer
    sudo systemctl daemon-reload
    sudo systemctl enable --now zypper-security-update.timer

    Method 2: Cron Job

    Add a cron job for zypper
    echo "30 3 * * * root /usr/bin/zypper --non-interactive patch --category security 2>&1 | logger -t zypper-auto" | sudo tee /etc/cron.d/zypper-security

    Verification

    Check status
    sudo systemctl status zypper-security-update.timer
    sudo zypper list-patches --category security

    💡 In enterprise SLES environments managed by SUSE Manager, automatic patching is typically handled through the management server's scheduling system rather than local zypper timers.

    8

    Arch Linux

    ⚠️ Rolling Release Warning: Arch does not offer security-only updates. An automatic update applies all available package upgrades, which may include major version bumps. Test in a staging environment first and always maintain current backups.

    Create /etc/systemd/system/pacman-update.service
    [Unit]
    Description=Automatic pacman system upgrade
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/pacman -Syu --noconfirm
    Create /etc/systemd/system/pacman-update.timer
    [Unit]
    Description=Daily system upgrade timer
    
    [Timer]
    OnCalendar=*-*-* 04:00:00
    RandomizedDelaySec=1800
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    Enable and verify
    sudo systemctl daemon-reload
    sudo systemctl enable --now pacman-update.timer
    
    # Verify
    sudo systemctl status pacman-update.timer
    journalctl -u pacman-update.service --since today
    9

    Post-Configuration Best Practices

    Handling Kernel Updates and Reboots

    • Scheduled reboots: Configure auto-reboot (where available) during a maintenance window such as 3:00 AM
    • Live kernel patching: Use KernelCare, Canonical Livepatch, or kpatch for high-availability workloads
    • Reboot detection: Install needrestart (Debian/Ubuntu) or needs-restarting (RHEL family) to identify when reboots are required

    Monitoring and Alerting

    • Review systemd timer logs weekly with journalctl
    • Configure email notifications to receive alerts when patches are applied or errors occur
    • Use external monitoring (Uptime Kuma, Prometheus, or your provider's monitoring) to detect unexpected downtime

    Backup Strategy

    Take VPS snapshots on a regular schedule, ideally before the update window. Tools like restic or borgbackup provide file-level backup redundancy.

    Excluding Packages

    • Ubuntu/Debian: Add packages to Unattended-Upgrade::Package-Blacklist in 50unattended-upgrades
    • RHEL/Fedora: Add exclude = package_name under [commands] in automatic.conf
    • openSUSE/SLES: Use zypper locks: zypper addlock package_name
    • Arch: Add packages to the IgnorePkg line in /etc/pacman.conf
    10

    Troubleshooting

    Timer Not Active

    Confirm the timer unit is enabled and scheduled:

    systemctl list-timers --all | grep -i auto
    systemctl list-timers --all | grep -i dnf
    systemctl list-timers --all | grep -i zypper

    If not listed, re-enable with systemctl enable --now followed by the timer unit name.

    Updates Failing Silently

    Check the journal for error output:

    journalctl -u unattended-upgrades.service --since yesterday
    journalctl -u dnf-automatic-install.service --since yesterday

    Common causes: stale repository metadata, disk space exhaustion, or dpkg/rpm lock conflicts from a concurrent manual operation.

    Package Conflicts

    If an update fails due to a dependency conflict, the tool will skip conflicting packages and log the error. Resolve manually and the next automatic run picks up the remaining updates.

    Network Issues

    If the VPS cannot reach package repositories, updates will fail. Verify DNS resolution and outbound HTTPS connectivity. Ensure outbound access to your distribution's mirror network is permitted in your firewall configuration.

    Testing Your Configuration

    1. Run the update tool manually in dry-run or verbose mode to confirm it targets the correct repositories
    2. Verify the systemd timer (or cron job) is active and scheduled for the expected time
    3. Wait for one full cycle and check logs to confirm updates were applied without errors
    4. If email notifications are configured, confirm you receive the test notification
    5. Confirm excluded packages remain at their current version after the update cycle