Automatic / Unattended (Security) Updates in Debian

If you follow current IT security vulnerabilities and security breaches, you’ll probably agree that keeping systems up to date is becoming increasingly important. Unattended upgrades for Debian/Ubuntu have been around for as long as I can remember and it’s a pretty easy way to achieve that. Here’s how.

Installation

You will need to install unattended-upgrades

apt-get install unattended-upgrades 

I also install apt-config-auto-update which is the replacement for update-notifier-common and allows automatic reboot. Then I install apt-listchanges and postfix (local-only configuration, you may want to install bsd-mailx or mailutils instead)

Configuration

Use the following command to enable automatic updates:

dpkg-reconfigure --priority=low unattended-upgrades 

Now take a look at: /etc/apt/apt.conf.d/50unattended-upgrades. E.g.

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

Origins-Pattern is the most important part. Because here you define what you will do automatically. Only security updates? Everything? You may also add custom repositories here.

Do not forget to add an E-Mail so you know what’s going on:

Unattended-Upgrade::Mail "";

You should be very careful with the following setting; However, automatic restarts could be handy. I wouldn’t use this for my host systems (hypervisor). But I don’t see a problem for specific virtual machines. Depending on your monitoring infrastructure, you may want to pick an out-of-office time, but still a time in which you can respond quickly if something goes wrong. Don’t use this for critical systems.

// Automatically reboot *WITHOUT CONFIRMATION* if
//  the file /var/run/reboot-required is found after the upgrade
Unattended-Upgrade::Automatic-Reboot "true";

// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
//  Default: "now"
Unattended-Upgrade::Automatic-Reboot-Time "06:00";

Assuming that you do not want automatic reboots the needrestart package might become useful to you. It will tell you when a restart of services is required. So consider to additionally install needrestart.

I strongly recommend to run:

unattended-upgrade --dry-run --debug

After you edited the above configuration. It will show you for which package repositories it does automatic updates. Also it will help you to configure e.g. custom package repositories if you use any.

That’s all.

Mail Example #1

If you configured everything correctly and your mail is also configured correctly you should soon receive E-Mails similar to the following one. Here the system upgraded a few php8.3-* packages

Unattended upgrade result: All upgrades installed

Packages that were upgraded:
 php8.3-bcmath php8.3-cli php8.3-common php8.3-fpm php8.3-intl
 php8.3-opcache php8.3-readline php8.3-sqlite3 php8.3-sqlite3-dbgsym

Package installation log:
Log started: 2024-02-18  06:40:12
apt-listchanges: Reading changelogs...
apt-listchanges: Reading changelogs...
Preparing to unpack .../0-php8.3-sqlite3-dbgsym_8.3.3-1+0~20240216.17+debian12~1.gbp87e37b_amd64.deb ...
Unpacking php8.3-sqlite3-dbgsym (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) over (8.3.2-1+0~20240120.16+debian12~1.gbpb43448) ...
Preparing to unpack .../1-php8.3-sqlite3_8.3.3-1+0~20240216.17+debian12~1.gbp87e37b_amd64.deb ...
Unpacking php8.3-sqlite3 (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) over (8.3.2-1+0~20240120.16+debian12~1.gbpb43448) ...
Preparing to unpack .../2-php8.3-readline_8.3.3-1+0~20240216.17+debian12~1.gbp87e37b_amd64.deb ...
Unpacking php8.3-readline (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) over (8.3.2-1+0~20240120.16+debian12~1.gbpb43448) ...
Preparing to unpack .../3-php8.3-opcache_8.3.3-1+0~20240216.17+debian12~1.gbp87e37b_amd64.deb ...
Unpacking php8.3-opcache (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) over (8.3.2-1+0~20240120.16+debian12~1.gbpb43448) ...
Preparing to unpack .../4-php8.3-intl_8.3.3-1+0~20240216.17+debian12~1.gbp87e37b_amd64.deb ...
Unpacking php8.3-intl (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) over (8.3.2-1+0~20240120.16+debian12~1.gbpb43448) ...
Preparing to unpack .../5-php8.3-cli_8.3.3-1+0~20240216.17+debian12~1.gbp87e37b_amd64.deb ...
Unpacking php8.3-cli (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) over (8.3.2-1+0~20240120.16+debian12~1.gbpb43448) ...
Preparing to unpack .../6-php8.3-fpm_8.3.3-1+0~20240216.17+debian12~1.gbp87e37b_amd64.deb ...
Unpacking php8.3-fpm (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) over (8.3.2-1+0~20240120.16+debian12~1.gbpb43448) ...
Preparing to unpack .../7-php8.3-bcmath_8.3.3-1+0~20240216.17+debian12~1.gbp87e37b_amd64.deb ...
Unpacking php8.3-bcmath (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) over (8.3.2-1+0~20240120.16+debian12~1.gbpb43448) ...
Preparing to unpack .../8-php8.3-common_8.3.3-1+0~20240216.17+debian12~1.gbp87e37b_amd64.deb ...
Unpacking php8.3-common (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) over (8.3.2-1+0~20240120.16+debian12~1.gbpb43448) ...
Setting up php8.3-common (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...
Setting up php8.3-sqlite3 (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...
Setting up php8.3-readline (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...
Setting up php8.3-bcmath (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...
Setting up php8.3-opcache (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...
Setting up php8.3-sqlite3-dbgsym (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...
Setting up php8.3-intl (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...
Setting up php8.3-cli (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...
Setting up php8.3-fpm (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...
Processing triggers for man-db (2.11.2-2) ...
Processing triggers for php8.3-cli (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...
Processing triggers for php8.3-fpm (8.3.3-1+0~20240216.17+debian12~1.gbp87e37b) ...

Running kernel seems to be up-to-date.

No services need to be restarted.

No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.
Log ended: 2024-02-18  06:40:34



Unattended-upgrades log:
Starting unattended upgrades script
Allowed origins are: origin=Debian,codename=bookworm-updates, origin=Debian,codename=bookworm-proposed-updates, origin=Debian,codename=bookworm,label=Debian, origin=Debian,codename=bookworm,label=Debian-Security, origin=Debian,codename=bookworm-security,label=Debian-Security, origin=Debian Backports,codename=bookworm-backports,label=Debian Backports, origin=deb.sury.org,a=bookworm
Initial blacklist:
Initial whitelist (not strict):
Packages that will be upgraded: php8.3-bcmath php8.3-cli php8.3-common php8.3-fpm php8.3-intl php8.3-opcache php8.3-readline php8.3-sqlite3 php8.3-sqlite3-dbgsym
Writing dpkg log to /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
All upgrades installed

In the above example all repositories as well as deb.sury.org are enabled for unattended upgrades.

Mail Example #2

Here is a good example. My Firewall’s use suricata and the current update requires me to choose if I want to keep two configuration files or install the package maintainers version. Instead of just doing the update – unattended upgrades puts them on hold:

Unattended upgrade result: No packages found that can be upgraded
 unattended and no pending auto-removals

Packages with upgradable origin but kept back:
 Debian Backports stable-backports:
  suricata

Unattended-upgrades log:
Starting unattended upgrades script
Allowed origins are: [..]
Initial blacklist:
Initial whitelist (not strict):
Package suricata has conffile prompt and needs to be upgraded manually
package suricata not upgraded
No packages found that can be upgraded unattended and no pending auto-removals
Package suricata is blacklisted.

Another cool thing, on login you see that there are updates available:

1 updates could not be installed automatically. For more details,
see /var/log/unattended-upgrades/unattended-upgrades.log

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.