Wednesday, January 2, 2008

A Simple CGI Script To Check Network Hosts' Status

Today, I thought I'd put out another script that might be helpful to at least a few of us out there. As you may recall, in an earlier post we went over a script that checked network hosts' ports non-maliciously. This is a combination of that with a little something extra.

Okay, there are a few extra elements here. The main function of the script is to check that all the servers in the @hostnames array are up and running. This is done as simply as possible, using ping. The second thing it checks is that FTP is up and running on all hosts (We're assuming that you're running this from a box on your network that has access - through firewalls, router acl's and whatnot - to all of the servers listed). Thirdly, it looks at a subset of servers that you define within the script, and tries to determine if HTTP is up and running.

This script is slightly more complicated than the other, as it uses the Perl Socket and CGI modules and also makes use of signal handling (Touched on in more detail in this previous post. Finally, we do some while loop tagging to control the flow.

Of course, this script can be modified easily to include other system checks. I wrote this to get a quick feel for the health of the network and get an easy read on any problems at whatever time I chose to open the page in my web browser.

Hopefully, you'll find this useful. I've commented the script near all the parts that can/should be edited (IN CAPITALS FOR EASE OF VIEWING). Otherwise, it's pretty much self explanatory.

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# whatup.cgi - 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

use CGI;
use Socket;
require 5.002;

# FILL THIS ARRAY WITH ALL THE HOSTNAMES YOU WANT TO MONITOR

@hostnames = qw(host1 host2 host3 hosta hostb hostc hostn);

foreach $pingable_host (@hostnames) {
$answer=`/usr/sbin/ping $pingable_host 1 1`;
if ( $answer=~ /alive/ ) {
$is_it_up_or_not[$a] = 1;
$a++;
} else {
$is_it_up_or_not[$a] = 0;
$a++;
}
}

use CGI;

$whatup_cgi = new CGI;
@ports = qw(21 80);
$date = `date`;

print $whatup_cgi->header();
print "<html><head><meta HTTP-EQUIV=\"REFRESH\" CONTENT=\"300; URL=/whatup.cgi\"><title>What's Up?</title></head>\n";
print "<body BGCOLOR=\"#000000\" TEXT=\"#00FF00\" LINK=\"#FFFF00\" VLINK=\"#FF0000\" ALINK=\"#BECD8C\">\n";
print "<p>\n";
print "<br><hr><br>\n";
print "<p>\n";
print "<center><FONT COLOR=\"#FF0000\"><H3>Your Immediate Guide to What's Up On Our Network!</h3></FONT></center>\n";
print "<center><FONT COLOR=\"#BECD8C\"><H4>$date</h4></FONT></center>\n";
print "<p>\n";
print "<br><hr><br>\n";
print "<p>\n";

$b=0;
$c=0;

$SIG{'ALRM'} = 'next_goround';
OUTER: foreach $host (@hostnames) {
if ( $is_it_up_or_not[$b] ) {
print "<hr>\n";
print "<h3><font color=\"#BECD8C\">$host is Up!</font></h3>";
} else {
print "<hr>\n";
print "<h3><font color=\"#FF0000\">$host is Down!</font></h3>";
}
print "<ul>";
$CONNECTION_PORT = "NEXT_UP_IS${c}SOCK";

# IN THE BELOW IF STATEMENT, USE REGULAR EXPRESSIONS TO MATCH ALL HOST NAMES
# THAT YOU WANT TO BE CHECKED FOR HTTP. ALL HOSTS ARE CHECKED FOR FTP

if ( $host=~ /host[1-3]/ || $host=~ /host[ab]/ ) {
foreach $portno (@ports) {
$port = $portno;
if ($port =~ /\D/) {
$port = getservbyname($port, 'tcp');
}
$iaddr = inet_aton($host);
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('tcp');
socket($CONNECTION_PORT, PF_INET, SOCK_STREAM, $proto);
if ( $is_it_up_or_not[$b] ) {
connect($CONNECTION_PORT, $paddr) unless alarm 10;
if ( $success_or_failure ) {
next;
}
alarm 0;
}
if ($port == 21 && ! $success_or_failure ) {
$portname = "FTP";
if ( $is_it_up_or_not[$b] ) {
$create_socket = send($CONNECTION_PORT, "user anonymous username\@xyz.com", 40) unless alarm 10;
alarm 0;
}
} else {
$portname = "HTTP";
if ( $is_it_up_or_not[$b] ) {
$create_socket = send($CONNECTION_PORT, "GET /index.html HTTP/1.0", 40) unless alarm 10;
alarm 0;
}
}
close($CONNECTION_PORT);
if ( ! $is_it_up_or_not[$b] && ! $success_or_failure ) {
print "<li><h3><font color=\"#FF0000\">$portname is Down!</h3></font></ul>";
$b++;
next OUTER;
}
if ($create_socket) {
print "<li><h3><font color=\#FFFF00\">$portname is Up!</h3></font>";
} else {
print "<li><h3><font color=\"#FF0000\">$portname is Down!</h3></font>";
}
$c++;
$success_or_failure = 0;
}
print "</ul>\n";
} else {
$port = 21;
if ($port =~ /\D/) {
$port = getservbyname($port, 'tcp');
}
$iaddr = inet_aton($host);
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('tcp');
socket($CONNECTION_PORT, PF_INET, SOCK_STREAM, $proto);
if ( $is_it_up_or_not[$b] ) {
connect($CONNECTION_PORT, $paddr) unless alarm 10;
alarm 0;
}
if ( $is_it_up_or_not[$b] && ! $success_or_failure ) {
$create_socket = send($CONNECTION_PORT, "user anonymous username\@xyz.com", 40) unless alarm 10;
alarm 0;
}
$portname = "FTP";
close($CONNECTION_PORT);
if ( ! $is_it_up_or_not[$b] && ! $success_or_failure ) {
print "<li><h3><font color=\"#FF0000\">$portname is Down!</h3></font></ul>";
$b++;
next OUTER;
}
if ($create_socket) {
print "<li><h3><FONT COLOR=\"#FFFF00\">$portname is Up!</h3></font>";
} else {
print "<li><h3><font color=\"#FF0000\">$portname is Down!</h3></font>";
}
print "</ul>\n";
$c++;
$success_or_failure = 0;
}
$b++;
}

$whatup_cgi->end_html();

sub next_goround {

close($CONNECTION_PORT);
return $success_or_failure = 1;
}


, Mike