Back to tutorials
Tutorial

Linux VPS Automated Security Patching Tutorial: Complete Setup with Unattended Upgrades and Custom Notification Scripts for 2026

Learn to configure automated security patching on Linux VPS with unattended-upgrades, email notifications, and rollback strategies. 2026 guide.

By Anurag Singh
Updated on May 08, 2026
Category: Tutorial
Share article
Linux VPS Automated Security Patching Tutorial: Complete Setup with Unattended Upgrades and Custom Notification Scripts for 2026

Understanding Automated Security Patching on Linux VPS

Security vulnerabilities emerge constantly across the Linux ecosystem. Manual patching becomes unmanageable when you're running multiple VPS instances or can't monitor update cycles around the clock.

Automated security patching handles critical updates without your direct intervention. The system downloads, tests, and applies security patches while logging every action for your review.

This tutorial covers complete setup on Ubuntu 24.04 and AlmaLinux 9. We'll focus on unattended-upgrades for Debian-based systems and dnf-automatic for Red Hat family distributions.

You'll configure email notifications, set up rollback procedures, and implement custom monitoring scripts.

Prerequisites and System Requirements

Your VPS needs these components before starting:

  • Root or sudo access on Ubuntu 24.04 or AlmaLinux 9
  • Mail transfer agent (Postfix or similar) configured for notifications
  • At least 2GB free disk space for package downloads and rollback snapshots
  • Stable internet connection for package repositories

Verify your current system version:

lsb_release -a (Ubuntu)
cat /etc/almalinux-release (AlmaLinux)

Check available disk space:

df -h /

A HostMyCode VPS with 4GB RAM and SSD storage provides optimal performance for automatic patching operations.

Installing and Configuring Unattended Upgrades on Ubuntu

Ubuntu's unattended-upgrades package handles automatic security updates with granular control. You can specify which packages to update and when.

Install the required packages:

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

Enable automatic updates:

sudo dpkg-reconfigure -plow unattended-upgrades

Select "Yes" when prompted to enable unattended upgrades.

Edit the main configuration file:

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

Configure these essential settings:

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

Unattended-Upgrade::DevRelease "false";
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::MinimalSteps "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";

Unattended-Upgrade::Mail "admin@yourdomain.com";
Unattended-Upgrade::MailOnlyOnError "false";

This configuration restricts updates to security patches only. It prevents automatic reboots during business hours.

The system sends email notifications for all update activities.

Setting Up DNF Automatic on AlmaLinux

AlmaLinux uses dnf-automatic for package management. The setup process differs from Ubuntu but achieves similar results.

Install dnf-automatic:

sudo dnf install dnf-automatic

Configure the main settings:

sudo nano /etc/dnf/automatic.conf

Modify these key parameters:

[commands]
upgrade_type = security
random_sleep = 3600
network_online_timeout = 60
download_updates = yes
apply_updates = yes

[emitters]
emit_via = email,motd

[email]
email_from = system@yourdomain.com
email_to = admin@yourdomain.com
email_host = localhost

Enable and start the service:

sudo systemctl enable dnf-automatic.timer
sudo systemctl start dnf-automatic.timer

Verify the timer status:

sudo systemctl status dnf-automatic.timer

The timer runs daily with randomized delays. This prevents simultaneous updates across multiple servers.

Creating Custom Notification Scripts

Standard email notifications provide basic information. Custom scripts deliver detailed reports with system impact analysis.

Create a notification script directory:

sudo mkdir -p /usr/local/scripts/patching

Build the notification script:

sudo nano /usr/local/scripts/patching/notify-updates.sh

#!/bin/bash

HOSTNAME=$(hostname)
DATETIME=$(date '+%Y-%m-%d %H:%M:%S')
LOGFILE="/var/log/unattended-upgrades/unattended-upgrades.log"
UPDATES_APPLIED=$(tail -50 "$LOGFILE" | grep -c "Installing:")
REBOOT_REQUIRED="$([ -f /var/run/reboot-required ] && echo 'YES' || echo 'NO')"

# Generate system status report
cat << EOF > /tmp/update-report.txt
Security Update Report - $HOSTNAME
Generated: $DATETIME

Updates Applied: $UPDATES_APPLIED packages
Reboot Required: $REBOOT_REQUIRED
System Load: $(uptime | awk '{print $10,$11,$12}')
Disk Usage: $(df -h / | tail -1 | awk '{print $5}')

Recent Update Activity:
$(tail -20 "$LOGFILE" | grep -E "(Installing:|Removing:|Configuring:)")

EOF

# Send email notification
mail -s "[$HOSTNAME] Security Updates Applied" admin@yourdomain.com < /tmp/update-report.txt

# Clean up
rm /tmp/update-report.txt

Make the script executable:

sudo chmod +x /usr/local/scripts/patching/notify-updates.sh

This script generates comprehensive reports including package counts and system health metrics. It also shows reboot requirements.

Implementing Pre and Post Update Hooks

Hook scripts run before and after updates. They let you stop services, create snapshots, or verify system integrity.

Create pre-update hooks:

sudo nano /etc/apt/apt.conf.d/51unattended-upgrades-pre

DPkg::Pre-Install-Pkgs {"/usr/local/scripts/patching/pre-update.sh";};

Build the pre-update script:

sudo nano /usr/local/scripts/patching/pre-update.sh

#!/bin/bash

# Create system snapshot
echo "$(date): Creating pre-update snapshot" >> /var/log/patching.log

# Stop non-critical services
systemctl stop apache2 2>/dev/null || true
systemctl stop nginx 2>/dev/null || true

# Record current package state
dpkg -l > /var/backups/packages-$(date +%Y%m%d).list

# Check disk space
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
if [ "$FREE_SPACE" -lt 1048576 ]; then
    echo "WARNING: Low disk space detected" >> /var/log/patching.log
fi

Create post-update verification:

sudo nano /usr/local/scripts/patching/post-update.sh

#!/bin/bash

# Restart stopped services
systemctl start apache2 2>/dev/null || true
systemctl start nginx 2>/dev/null || true

# Verify critical services
for service in ssh networking; do
    if ! systemctl is-active "$service" >/dev/null; then
        echo "ERROR: $service is not running" >> /var/log/patching.log
    fi
done

# Send completion notification
/usr/local/scripts/patching/notify-updates.sh

echo "$(date): Update cycle completed" >> /var/log/patching.log

Make scripts executable:

sudo chmod +x /usr/local/scripts/patching/*.sh

Configuring Package Hold and Exclusions

Some packages require manual oversight before updates. You can exclude specific packages or hold them at current versions.

For Ubuntu, edit the unattended-upgrades configuration:

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

Add package exclusions:

Unattended-Upgrade::Package-Blacklist {
    "kernel*";
    "mysql-server*";
    "postgresql*";
    "nginx";
};

On AlmaLinux, modify the dnf-automatic configuration:

sudo nano /etc/dnf/automatic.conf

[commands]
exclude = kernel* mysql* postgresql* nginx

Hold specific packages manually:

sudo apt-mark hold nginx (Ubuntu)
sudo dnf versionlock add nginx (AlmaLinux)

This prevents automatic updates for critical services that need controlled maintenance windows.

Our managed VPS hosting service handles these complex update scenarios with expert oversight.

Monitoring and Log Analysis

Effective automated security patching requires continuous monitoring of update activities and system health.

Create a log analysis script:

sudo nano /usr/local/scripts/patching/analyze-logs.sh

#!/bin/bash

LOGDIR="/var/log"
REPORT_FILE="/tmp/patching-analysis.txt"

echo "Automated Patching Analysis - $(date)" > "$REPORT_FILE"
echo "=========================================" >> "$REPORT_FILE"

# Count recent updates
UPDATES_WEEK=$(grep -c "Installing:" "$LOGDIR/unattended-upgrades/unattended-upgrades.log" 2>/dev/null || echo "0")
echo "Updates applied this week: $UPDATES_WEEK" >> "$REPORT_FILE"

# Check for errors
ERRORS=$(grep -c "ERROR" "$LOGDIR/unattended-upgrades/unattended-upgrades-dpkg.log" 2>/dev/null || echo "0")
echo "Update errors encountered: $ERRORS" >> "$REPORT_FILE"

# Reboot requirements
if [ -f /var/run/reboot-required ]; then
    echo "REBOOT REQUIRED" >> "$REPORT_FILE"
    cat /var/run/reboot-required.pkgs >> "$REPORT_FILE" 2>/dev/null
fi

# System health check
echo "\nSystem Health:" >> "$REPORT_FILE"
echo "Load Average: $(uptime | awk '{print $10,$11,$12}')" >> "$REPORT_FILE"
echo "Memory Usage: $(free -h | grep Mem | awk '{print $3"/"$2}')" >> "$REPORT_FILE"
echo "Disk Usage: $(df -h / | tail -1 | awk '{print $5}')" >> "$REPORT_FILE"

cat "$REPORT_FILE"

Set up weekly monitoring:

sudo crontab -e

Add this line:

0 8 * * 1 /usr/local/scripts/patching/analyze-logs.sh | mail -s "Weekly Patching Report" admin@yourdomain.com

Rollback and Recovery Procedures

Automatic patching occasionally causes issues. Proper rollback procedures restore system functionality quickly.

Create a rollback script:

sudo nano /usr/local/scripts/patching/rollback.sh

#!/bin/bash

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 "
    echo "Example: $0 nginx"
    exit 1
fi

PACKAGE="$1"

echo "Rolling back package: $PACKAGE"

# For Ubuntu/Debian
if command -v apt >/dev/null; then
    apt list --installed | grep "$PACKAGE"
    read -p "Proceed with rollback? (y/N): " confirm
    if [ "$confirm" = "y" ]; then
        apt install "$PACKAGE"=
        apt-mark hold "$PACKAGE"
    fi
fi

# For AlmaLinux/RHEL
if command -v dnf >/dev/null; then
    dnf history list "$PACKAGE"
    read -p "Enter transaction ID to rollback: " transaction_id
    if [ -n "$transaction_id" ]; then
        dnf history rollback "$transaction_id"
        dnf versionlock add "$PACKAGE"
    fi
fi

echo "Rollback completed. Package held at current version."

Make it executable:

sudo chmod +x /usr/local/scripts/patching/rollback.sh

For system-wide rollbacks, consider filesystem snapshots before major updates.

This comprehensive backup tutorial covers advanced snapshot strategies.

Testing and Validation

Verify your setup with controlled tests before relying on it for production systems.

Force a test run:

sudo unattended-upgrade --dry-run (Ubuntu)
sudo dnf-automatic (AlmaLinux)

Check notification delivery:

/usr/local/scripts/patching/notify-updates.sh

Verify log rotation and cleanup:

ls -la /var/log/unattended-upgrades/

Test rollback procedures on a development server first.

Our Indian VPS hosting provides affordable test environments for validation.

Professional automated security patching requires solid infrastructure and expert configuration. HostMyCode's managed VPS hosting includes enterprise-grade automatic security patching with 24/7 monitoring and expert rollback support.

Frequently Asked Questions

How often should automated security patching run?

Daily updates provide the best protection against emerging threats. Configure updates during low-traffic hours (2-4 AM) to minimize service impact.

Critical security patches should apply immediately. Routine updates can run on scheduled intervals.

What happens if automatic patching breaks my application?

Proper rollback procedures restore functionality quickly. Hold problematic packages to prevent future automatic updates.

Schedule manual testing during maintenance windows. Always test on development servers first.

Should kernel updates be included in automatic patching?

Exclude kernel updates from automatic patching unless you have comprehensive testing procedures. Kernel updates require reboots and can affect hardware compatibility.

Handle kernel updates manually during scheduled maintenance windows.

How do I monitor automatic patching across multiple VPS instances?

Centralized logging aggregates update reports from multiple servers. Configure each VPS to send notifications to a central monitoring system.

Use tools like rsyslog or journald for log forwarding to a dedicated monitoring server.

Can automatic patching work with custom applications?

Yes, but requires careful configuration. Use pre-update hooks to stop custom services.

Post-update hooks verify application functionality. Test compatibility thoroughly before enabling automatic updates on production systems running custom software.

Linux VPS Automated Security Patching Tutorial: Complete Setup with Unattended Upgrades and Custom Notification Scripts for 2026 | HostMyCode