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 🙂
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'"); } ?>