Auto Discover (for Mona 3.0)

I wrote a autodiscover for Nagios Core in combination with NagiosQL (V 3.2.0) and requires nmap (https://nmap.org/).

There is one main (perl) script which scans the network and adds the found hosts to a database. It starts with a scan, then checks if the ip address exsists in NagiosQL and it checks its own database. If a host is found which doesn’t exsist in either database, it will check the hostname with a snmpget, using the community given on the webpage.

#!/usr/bin/perl -w

#Declaration of Perl Modules to use.
use strict;
use DBI;
use DBD::mysql;
use Net::SMTP;
use Net::SNMP;

#Declaration of used Constants/Variables
my ($msg_body, $msg_sender , $msg_rcpt, $sthm, $sql, @row, $dbh, $hostname, $output, $snmp, $sysName, $errstr, $r_sysNamei, $getcomm, $getaddress);

#mysql server
my $DBuser="<user1 for NagiosQL DB>";
my $DBpass="<Password for NagiosQL DB>";
my $dbhm=DBI->connect("dbi:mysql:db_nagiosql_v2","$DBuser","$DBpass",
{
PrintError => 1,
}
);
unless ( $dbhm ){
        die("connection does not work properly!");
}

#mysql server
my $DBuser2="<User for autodiscover DB>";
my $DBpass2="<Password for autodiscover DB>";
my $dbhm2=DBI->connect("dbi:mysql:autodiscover","$DBuser2","$DBpass2",
{
PrintError => 1,
}
);
unless ( $dbhm2 ){
        die("connection does not work properly!");
}

$getcomm = "SELECT value FROM autodiscover.config WHERE what = 'community'";
my ($comm) = $dbhm2->selectrow_array($getcomm);
if($comm eq '') { 
  print "Community not set!";
  exit;
}

$getaddress = "SELECT value FROM autodiscover.config WHERE what = 'address'";
my $sth = $dbhm2->prepare("$getaddress");
$sth->execute();
my $row;
while ($row = $sth->fetchrow_arrayref()) {
    my $addresses = "@$row[0]";

    if($addresses eq '') { 
       print "Address not set!";
       exit;
    } else {
       #print "$addresses \n";

       my $cmd = "fping -a -r 1 -g $addresses -q";
       my @output = `$cmd`;
       chomp @output;

       foreach my $address (@output)
       {

         $sql = "SELECT address FROM db_nagiosql_v2.tbl_host WHERE address = ?";
         @row = $dbhm->selectrow_array($sql,undef,$address);
         unless (@row) { 

            my $getexsist = "SELECT ip FROM autodiscover.FoundHosts WHERE ip = '$address'";
            my ($exsist) = $dbhm2->selectrow_array($getexsist);
             unless ($exsist) { 
            print "Address not found before: "; 
    
                my $sysname = &getsnmphostname($address,$comm);
                if($sysname) {
                           print "$address not found in exsisting config, hostname: $sysname \n";
                    my $query = "insert into autodiscover.FoundHosts(`id`, `ip`, `hostname`, `ignored`) values (?, ?, ?, ?) ";
                    # prepare your statement for connecting to the database
                    my $statement = $dbhm2->prepare($query);
                    # # execute your SQL statement
                    $statement->execute('', $address, $sysname, '0');
                } else {
                           print "$address not found in exsisting config, snmp does not work \n";
                    my $query = "insert into autodiscover.FoundHosts(`id`, `ip`, `hostname`, `ignored`) values (?, ?, ?, ?) ";
                    # prepare your statement for connecting to the database
                    my $statement = $dbhm2->prepare($query);
                    # # execute your SQL statement
                    $statement->execute('', $address, 'SNMP NA', '0');
                }
    
        } else {
            my $getignored = "SELECT ignored FROM autodiscover.FoundHosts WHERE ip = '$address'";
            my ($ignored) = $dbhm2->selectrow_array($getignored);
          if($ignored == '1'){
              print "$address ignored: $ignored \n";
          }else{
              print "$address NOT ignored: $ignored \n";
          }
            }    
         }
        }
     } 
}
$dbhm->disconnect();
$dbhm2->disconnect();





sub getsnmphostname {
    my $address = $_[0];
    my $comm = $_[1];
         my $ver='2';
         my $timeout='1';
         my $sysName  = '.1.3.6.1.2.1.1.5.0';

         ($snmp, $errstr) = Net::SNMP->session(
                            -hostname  => $address,
                            -version   => $ver,
                            -community => $comm,
                            -timeout   => $timeout,
                           );
          die("Could not create SNMP session: $errstr\n") unless($snmp);

          my $result = $snmp->get_request(
              -varbindlist => [
              "$sysName",
                ],
             ); 
             my $r_sysName = $result->{"$sysName"};
}

The MySQL database needed to use this script:

CREATE DATABASE IF NOT EXISTS `autodiscover` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE `autodiscover`;
-- --------------------------------------------------------

CREATE TABLE IF NOT EXISTS `config` (
  `id` tinyint(4) NOT NULL AUTO_INCREMENT,
  `what` varchar(25) NOT NULL,
  `value` varchar(25) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;
INSERT INTO `config` (`id`, `what`, `value`) VALUES
(1, 'community', 'public');

CREATE TABLE IF NOT EXISTS `FoundHosts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip` varchar(25) NOT NULL,
  `hostname` varchar(50) NOT NULL,
  `ignored` tinyint(4) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;


GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON autodiscover.* TO <user for autodiscover DB>@localhost IDENTIFIED by '<Password for autodiscover DB>';
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON db_nagiosql_v2.* TO <user for autodiscover DB>@localhost IDENTIFIED by '<Password for autodiscover DB>';
UPDATE mysql.user SET Password = OLD_PASSWORD('<Password for autodiscover DB>') WHERE Host = 'localhost' AND User = '<user for autodiscover DB>';
FLUSH PRIVILEGES;

I used some icons to make it more viewable 🙂

add info cancel search lock edit

This is all whats needed for the actual scan. Now it must be presented. I have added a new directory to the webbserver. (/var/www/html/autodiscover).

In this directory we need a directory “images” where the icons are placed.

First we have a config file, config.php:

<?PHP
$username = "<User for autodiscover DB>";
$password = "<Password for autodiscover DB>";
$host = "localhost";
$database = "autodiscover";
?>

And the index.php:

<?php // header("Content-type: text/html; charset=iso-8859-1");?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
 <meta http-equiv="Content-type" value="text/html; charset=iso-8859-1">
<title>AutoDiscover</title>
<link rel="Stylesheet" type="text/css" href="/thruk/themes/Thruk/stylesheets/all_in_one-2.02-1.css">
<?PHP
include("functions.php");
$function=$_GET["function"];
if($function=="removeFoundHost"){
 $ip=$_GET["ip"];
 showremoveFoundHost($ip);
 } else if($function=="IgnoreFoundHost"){
 $ip=$_GET["ip"];
 showIgnoreFoundHost($ip);
 } else if($function=="ActiveScan"){
 showActiveScan();
 } else if($function=="RemoveNetwork"){
 $ip=$_GET["ip"];
 showRemoveNetwork($ip);
 } else if($function=="AddNetwork"){
 $address=$_POST["address"];
 showAddNetwork($address);
 } else if($function=="ChangeCommunity"){
 $comm=$_POST["comm"];
 showChangeCommunity($comm);
 } else if($function=="MoreInfo"){
 $ip=$_GET["ip"];
 showMoreInfo($ip);
 } else if($function=="ChangeHostName"){
 $ip=$_GET["ip"];
 $hostname=$_GET["hostname"];
 showChangeHostName($ip,$hostname);
 } else if($function=="DoChangeHostName"){
 $hostname=$_POST["hostname"];
 $ip=$_GET["ip"];
 showDoChangeHostName($ip,$hostname);
 } else if($function=="AddHostToNagios"){
 $hostname=$_GET["hostname"];
 $ip=$_GET["ip"];
 showAddHostToNagios($ip,$hostname);
}
?>
</head>
<body>
<br>
<div id="layout">
De ingestelde communitystring is:
<?php showCommunity(); ?>

<br>
De te scannen netwerk(en):<br>
<?php showNetworks(); ?>
<form action="index.php?function=AddNetwork" method="POST">
<input type="text" name="address" value="">
<input type="image" src="images/add.png" width=20px alt="Submit Form" />
</form>
<a href=index.php?function=ActiveScan><img src=./images/search.png width=20px>Scan now!</a>
<br>
<br>
<table>
<tr><td><img src=./images/add.png width=20px></td><td>Add Host to NagiosQL (needs a little config at NagiosQL)</td></tr>
<tr><td><img src=./images/cancel.png width=20px></td><td>Delete Host from this list</td></tr>
<tr><td><img src=./images/info.jpg width=20px></td><td>Get more info of this Host</td></tr>
<tr><td><img src=./images/edit.png width=20px></td><td>Edit the Hostname</td></tr>
<tr><td><img src=./images/lock.png width=20px"></td><td>Move Host to Ignore list</td></tr>
</table>
<h2>New hosts:</h2>
<table>
<tr><td width=200>Address:</td><td width=200>Hostname </td><td colspan=3>Action</td</tr>
<?php showFoundHostsNI(); ?>
</table>
<h2>Ignored hosts:</h2>
<table>
<tr><td width=200>Address:</td><td width=200>Hostname </td><td colspan=3>Action</td</tr>
<?php showFoundHostsI(); ?>
</table>
</div>
</body>
</html>

And a functions.php:

<?PHP
include("config.php");
global $host,$username,$password;
$db = mysql_connect("$host","$username","$password");
mysql_select_db("$database");

if(!$db){
 die("Kan geen database verbinding maken... sorry!");
}


function showNetworks(){
 $result = mysql_query("SELECT value FROM config WHERE what='address'");
 $count = 0;
 while ($row = mysql_fetch_array($result)){
 $value = $row["value"];
 echo "Network: $value <a href=\"index.php?function=RemoveNetwork&ip=$value\"><img src=./images/cancel.png width=20px></a><br>";
 $count++;
 }
 if ($count==0){
 print "geen netwerken";

 }
}

function showCommunity(){
 $result = mysql_query("SELECT value FROM config WHERE what='community'");
 $count = 0;
 while ($row = mysql_fetch_array($result)){
 $value = $row["value"];
 echo "<form action=\"index.php?function=ChangeCommunity\" method=\"POST\">";
 echo "<input type=\"password\" name=\"comm\" value=\"$value\">";
 echo "<input type=\"image\" src=\"images/edit.png\" width=20px alt=\"Submit Form\" />";
 echo "</form>";
 $count++;
 }
 // echo "Geen community";
}

function showFoundHostsNI(){
 $result = mysql_query("SELECT ip,hostname,ignored FROM FoundHosts WHERE ignored = '0' ORDER BY ip ASC");
 $count = 0;
 while ($row = mysql_fetch_array($result)){
 $ip = $row["ip"];
 $hostname = $row["hostname"];
 $ignored = $row["ignored"];
 if ($ignored==0){
 echo "<tr><td>$ip</td>";
 echo "<td>$hostname</td>";
 echo "<td><a href=\"index.php?function=AddHostToNagios&ip=$ip&hostname=$hostname\"><img src=./images/add.png width=20px>";
 echo "<a href=\"index.php?function=removeFoundHost&ip=$ip\"><img src=./images/cancel.png width=20px></a>";
 echo "<a href=\"index.php?function=MoreInfo&ip=$ip\"><img src=./images/info.jpg width=20px alt=\"info\"></a>";
 echo "<a href=\"index.php?function=ChangeHostName&ip=$ip&hostname=$hostname\"><img src=./images/edit.png width=20px></a>";
 echo "<a href=\"index.php?function=IgnoreFoundHost&ip=$ip\"><img src=./images/lock.png width=20px alt=\"Ignore Host\"></a></td></tr>";
 }else{
 // echo "<tr><td>$ip</td><td>$hostname</td><td><input type=\"checkbox\" name=\"host\" value=\"ignored\" checked></td></tr>";
 }
 $count++;
 }
 if ($count==0){
 //echo "<tr><td>$ip</td><td>$hostname</td><td><input type=\"checkbox\" name=\"host\" value=\"ignored\" checked></td></tr>";
 }
}

function showFoundHostsI(){
 $result = mysql_query("SELECT ip,hostname,ignored FROM FoundHosts WHERE ignored = '1' ORDER BY ip ASC");
 $count = 0;
 while ($row = mysql_fetch_array($result)){
 $ip = $row["ip"];
 $hostname = $row["hostname"];
 $ignored = $row["ignored"];
 if ($ignored==0){
 echo "Hier klopt iets niet!";
 }else{
 echo "<tr><td>$ip</td>";
 echo "<td>$hostname</td>";
 echo "<td><a href=\"index.php?function=removeFoundHost&ip=$ip\"><img src=./images/cancel.png width=20px></a></td></tr>";
 }
 $count++;
 }
 if ($count==0){
 print "</table> <h2>There are no ignored hosts!";
 }
}

function showRemoveFoundHost($ip){
 mysql_query("DELETE FROM FoundHosts WHERE ip='$ip'");
 echo "Host permanent deleted";
}

function showIgnoreFoundHost($ip){
 mysql_query("UPDATE FoundHosts SET ignored='1' WHERE ip='$ip'");
 echo "Host ignored";
}

function showActiveScan(){
 echo "Active Scan";
 exec('/usr/local/bin/autodiscover.pl');
}


function showRemoveNetwork($ip){
 mysql_query("DELETE FROM config WHERE value='$ip'");
 echo "Network permanent deleted";
}

function showAddNetwork($address){
 if ($address==''){
 echo "Address cannot be empty!";
 } else {
 mysql_query("INSERT INTO `autodiscover`.`config` ( `id` , `what` , `value`) VALUES ( '', 'address', '$address')");
 echo "Network $address added";
 }
}

function showChangeCommunity($comm){
 mysql_query("UPDATE config SET value='$comm' WHERE what='community'");
 echo "Community changed to $comm";
}

function showMoreInfo($ip){
 echo "Show more info of $ip";
 $output = `/usr/bin/nmap -sT $ip -Pn`;
 echo "<pre>$output</pre>";
}

function showChangeHostName($ip,$hostname){
 echo "Change the hostname ($hostname) for $ip";
 echo "<form action=\"index.php?function=DoChangeHostName&ip=$ip\" method=\"POST\">";
 echo "<input type=\"text\" name=\"hostname\" value=\"$hostname\">";
 echo "<input type=\"image\" src=\"images/edit.png\" width=20px alt=\"Submit Form\" />";
 echo "</form>";
}

function showDoChangeHostName($ip,$hostname){
 echo "Hostname for $ip changed to $hostname";
 mysql_query("UPDATE FoundHosts SET hostname='$hostname' WHERE ip='$ip'");
}
function showAddHostToNagios($ip,$hostname){
 echo "Host $hostname with ip: $ip added to Nagios, go to <a target=_blank href=\"/nagiosQL/\">NagiosQL</a> to finish the job";
 mysql_query("INSERT INTO `db_nagiosql_v2`.`tbl_host` (`id`, `host_name`, `alias`, `display_name`, `address`, `parents`, `parents_tploptions`, `hostgroups`, `hostgroups_tploptions`, `check_command`, `use;
 mysql_query("DELETE FROM `autodiscover`.`FoundHosts` WHERE ip='$ip'");
}

?>