[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Package update notification script.



Hi All,

I have written a small Perl script to check for package updates, 
I know that this kind of thing has been done before (usually with much 
smaller shell scripts) but I did this more for fun than size or 
originality :) I have found it useful so I thought I would share it with 
the folks here. This script should work on any APT based system, tested on 
Red Hat (apt-rpm) and Debian.

This script can be run from Cron and will email a list of packages that 
need to be updated. You need to adjust some variables at the start of the 
script controlling the SMTP server to use to send mail and the address to 
send it to. The other options should be fine for most sites. It does not 
print anything unless debugging is on or there are errors. All results are 
sent via an email.

The script requires the Perl Net::SMTP module which is part of Perl 5.6. 
Please find the script (sec_update.pl) attached or at :

http://homepages.nildram.co.uk/~xinit/sec_update

Hope some people find it useful!

Regards, Fred.


#!/usr/bin/perl -w
# sec_update.pl
# 
# sec_update.pl -- Check for available security updates on systems running APT
#
# BEGIN LICENSE BLOCK
#
#  Copyright (c) 2004 Fred Clausen
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of version 2 of the GNU General Public License
#  as published by the Free Software Foundation.
#
#  A copy of that license should have arrived with this
#  software, but in any event can be snarfed from www.gnu.org.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
# END LICENSE BLOCK
# 
# TODO: 
# * Verify remote mail server accepted the message for delivery

#### User configurable options #######
my $apt_get = "/usr/bin/apt-get"; # Location of apt.
my $smtpserver = "localhost"; # SMTP server to use when sending messages.
my $admin_address = 'admin@example.com'; # Email address to send the messages to.
my $debug = 0;
#### End user configrable options ####

use strict;
use Net::SMTP;

my $uid = `id -u`;
my $if = `ifconfig`;
my $host = $ENV{HOSTNAME};

sub check_sys {
   	if (! -x "$apt_get") {
		die "Error apt-get on $host (executable $apt_get) not found or not executable, please modify \$apt_get \n";
	} elsif ($uid != 0) {
		die "This script must be run as the root user \n";
	}
}	

sub check_online {
	if (system("ping -c 1 $smtpserver > /dev/null")) { 
		print "Cannot contact $smtpserver or we are offline, exiting... \n"; 
		exit (0);
	}
}
		
sub debug {
	my $msg;
	if ($debug) {
		while(@_) {
			$msg = shift;
			print "$msg";
		}
	}
}

sub get_updates {
	my (@untested, @package_list, $size);

	debug ("Getting Update List \n");
	system ("apt-get update > /dev/null");
	system ("apt-get -y --dry-run upgrade > /tmp/apt.output");
	
	open (APTOUT, "</tmp/apt.output");
	while (<APTOUT>) {
		@untested = split;
		if ($untested[0] eq "Inst") {
            push (@package_list, $untested[1]);
        }
    }
	close (APTOUT);
	unlink ("/tmp/apt.output") || die "Cannot clean up /tmp/apt.output : $! \n";
	$size = @package_list;
	debug ("Got Update List \n");
	return \@package_list, $size;
}

sub send_message {
	my $to_upgrade = $_[0];
	my $size = $_[1];
	my $i;
	
	if ($size > 0) {
		debug ("Preparing Email message \n");
	    my $smtp = Net::SMTP->new("$smtpserver") || die "Could not open connection to $smtpserver: $! \n";
		$smtp->mail ("root\@$host");	
	    $smtp->to ("$admin_address");	
		$smtp->data();
		$smtp->datasend ("Subject: [$0] Machine $host needs package updates.
Dear Administrator,

On machine $host, there are $size packages out of date that need to be upgraded. 

They are: \n
");
	debug ("Number packages: $size \n");
	debug ("Host: $host \n");
	for ($i=0;$i < $size;$i++) {
		$smtp->datasend ("Package $i: $to_upgrade->[$i] \n");
	}
	$smtp->datasend ("\nBest regards, \nsec_update.pl\n\n");
	$smtp->datasend ("Info: \n");
	$smtp->datasend ("$if \n");
	$smtp->dataend();
	$smtp->quit();
	debug ("Email message sent\n");
	} else {
		debug ("No updates found, exiting... \n");
		exit (0);
	}
}

my ($to_upgrade, $size);
			
check_sys;
check_online;
($to_upgrade, $size) = get_updates;
send_message ($to_upgrade, $size);

debug ("Normal exit... \n");
exit 0;

Reply to: