Detecting Security Upgrades on Ubuntu

In my article on unattended upgrades I described how to set up an Ubuntu system to install security upgrades automatically. This is convenient for small setups, but in an enterprise environment you typically want to perform some QA before applying the change. A better solution is to have your monitoring system generate an alert if security upgrades are available. In this article,  we're going to build an Icinga plugin to hook into your monitoring/alerting system.

Our approach is very simple: We use the update-notifier-common package to keep the package index up to date and its apt-check tool to check whether security updates are available. So let's install the package:

# apt-get install update-notifier-common

In /etc/apt/apt.conf.d/10periodic, we make sure that the package index is updated daily by running apt-get update daily:

APT::Periodic::Update-Package-Lists "1";

The number indicates the update interval in days - setting the value to "0" disables the feature. If you like, you can have the system download upgradable packages without installing them:

APT::Periodic::Download-Upgradeable-Packages "1";

Once that is done, we give apt-check a try:

$ /usr/lib/update-notifier/apt-check --human-readable
7 packages can be updated.
0 updates are security updates.

This is the message you may have seen when logging into an Ubuntu server via SSH. For our script, we use apt-check without the --human-readable flag to make its output easier to parse.

So, are we done? Not quite - the apt-check mechanism relies on the fact that package indexes are up to date. Suppose your machine has lost its internet connection for some reason or your internal package repository doesn't work. We definitely want to be notified in these cases, too.

Fortunately, update-notifier-common has us covered. It uses the  APT::Update::Post-Invoke-Success hook to touch a status file if the package index download worked (see /etc/apt/apt.conf.d/15update-stamp):

APT::Update::Post-Invoke-Success {"touch /var/lib/apt/periodic/update-success-stamp 2>/dev/null || true";};

All we need to do is check the mtime of update-success-stamp and alert the monitoring system if it hasn't changed in the last day.

With all of these mechanisms in place, we can write a script that satisfies Nagios/Icinga conventions:

$ ./check_updates
OK - no security updates available (7 regular updates).

I have published the script on GitHub - feel free to tweak it as needed.