Note to Self

Linux/PHP and more
  • Home
  • Linux
  • Coding
  • Other
  • Archives

DHCPd/pools+snmp and mail alert

2010/09/28 | 14:56

This guide will show you a way of using DHCPd-pools and DHCPd-snmp for mailalerts if your leases are getting thin. A nicer way would be to do it in Cacti, but I’ve noticed that DHCPd-snmp lies in Cacti. I don’t know why yet, but dhcpd-pools seems to work.
EDIT: DHCPd-snmp lies when there is more than 1 range in a pool, then it will split the pools into two graphs with same name instead of combining them. DHCPd-pools on the other hand understands this and combines them into a bigger pool 🙂
Thanks to Kerolasa I updated this guide with new code working with v2.13 of dhcpd-pools. I still had to remove dynamic-bootp though

First of you need to download and install DHCPd-pools:

[bash]
sudo -s
apt-get install build-essential php5-cli libapache2-mod-php5
wget http://downloads.sourceforge.net/project/dhcpd-pools/dhcpd-pools-2.13.tgz&ts=1285676384&use_mirror=sunet
mkdir dhcp-snmp
cd dhcp-snmp
wget http://forums.cacti.net/download/file.php?id=7162&sid=215afb35532615dfd7e1493787e8face
unzip file.php\?id\=7162
#let this be for now
cd ..
tar xvf dhcpd-pools-2.13.tgz
cd dhcpd-pools-2.13
./configure
make
make install
sudo mkdir /home/checkDHCP
sudo touch /home/checkDHCP/changePercent.php
sudo touch /home/checkDHCP/checkDHCP.sh
sudo touch /home/checkDHCP/ignoredIPs
sudo touch /home/checkDHCP/ignoredIPs.php
sudo touch /home/checkDHCP/index.php
sudo echo "50" > /home/checkDHCP/percent.txt
sudo touch /home/checkDHCP/removeIPfromIgnored.php
sudo touch /home/checkDHCP/runScript.php
sudo touch /home/checkDHCP/sampleoutput.txt
sudo touch /home/checkDHCP/searchlog.txt
sudo touch /home/checkDHCP/sendFile
sudo chown -R www-data:www-data /home/checkDHCP
[/bash]

Now we can begin to code.

These files just contain values, let them be empty.
sendFile.txt
ignoredIPs.txt

checkDHCP.sh

[bash]
#!/bin/bash
#Skapat av Viktor Åström 2010-09-16

#Vars ligger alla filer
installDir="/home/checkDHCP"
percent=`cat $installDir/percent.txt`;
cp /etc/dhcp3/dhcpd.conf $installDir/dhcpd.conf
$installDir/dhcp2snmpconf.pl $installDir/dhcpd.conf > $installDir/dhcpd-snmp.conf

grep -Ev ‘#|leases:’ $installDir/dhcpd-snmp.conf > $installDir/test
sed ‘/^$/d’ $installDir/test > $installDir/test2
sort -n -k2 $installDir/test2 > $installDir/dhcpd-snmp2.conf
#Sedding dynamic-bootp is sadly still necessary, without it the output is all jibberish
sed s/dynamic-bootp-//g $installDir/dhcpd-snmp2.conf > $installDir/test
mv $installDir/test $installDir/dhcpd-snmp2.conf
rm $installDir/test
rm $installDir/test2

sed s/dynamic-bootp// $installDir/dhcpd.conf > $installDir/test
mv $installDir/test $installDir/dhcpd.conf
#sed s/range-// $installDir/dhcpd.conf > $installDir/test
#mv $installDir/test $installDir/dhcpd.conf

#Run dhcpd-pools to create sampleoutput files, the second file is for overview
/usr/local/bin/dhcpd-pools -c $installDir/dhcpd.conf -l /var/lib/dhcp3/dhcpd.leases -o $installDir/sampleoutput.txt
/usr/local/bin/dhcpd-pools -c $installDir/dhcpd.conf -l /var/lib/dhcp3/dhcpd.leases -o $installDir/sampleoutput2.txt -s p -r -f H

#Whom to send the email to
namn="your@email.com yournext@email.com"

#Find all instances where percent is above your chosen value
awk ‘ $8 > ‘"$percent"’ ‘ $installDir/sampleoutput.txt > $installDir/sendFile.txt

#Remove the first line
sed ‘1d’ < $installDir/sendFile.txt > $installDir/tmpfile ; mv $installDir/tmpfile $installDir/sendFile.txt

#Remove the two last lines
sed ‘$d’ < $installDir/sendFile.txt > $installDir/tmpfile ; mv $installDir/tmpfile $installDir/sendFile.txt
sed ‘$d’ < $installDir/sendFile.txt > $installDir/tmpfile ; mv $installDir/tmpfile $installDir/sendFile.txt

for ignoredIP in $(cat $installDir/ignoredIPs.txt); do
sed "/$ignoredIP/d" $installDir/sendFile.txt > $installDir/test
mv $installDir/test $installDir/sendFile.txt
done

cat $installDir/sendFile.txt | awk ‘{print $3}’ > $installDir/test2
cat $installDir/sendFile.txt | awk ‘{print "Searching for: "$3$4$5" found in "}’ > $installDir/test4
cat $installDir/sendFile.txt | awk ‘{print " MAX:"$6,"CUR:"$7, "PERCENT:"$8"%"}’ > $installDir/test
mv $installDir/test $installDir/sendFile.txt

for findIP in $(cat $installDir/test2); do
if [ "$(cat $installDir/dhcpd-snmp.conf | fgrep -i $findIP)" ]; then
cat $installDir/dhcpd-snmp.conf | fgrep -i $findIP >> $installDir/foundIPs.txt
paste -d "" $installDir/test4 $installDir/foundIPs.txt $installDir/sendFile.txt > $installDir/test3
fi
done

#Clean up
rm $installDir/foundIPs.txt
rm $installDir/test2
mv $installDir/test3 $installDir/sendFile.txt
rm $installDir/test4

#We only want to e-mail if more than 1 line in the file
if [ "$(cat $installDir/sendFile.txt | wc -l)" -gt 0 ]; then
for mailto in $namn; do
cat $installDir/sendFile.txt | /usr/bin/mail -s "DHCP-Telefoni lease warning > $percent%" $mailto
done
else
echo "No IP-ranges are above: " $percent"%" > $installDir/sendFile.txt
fi
exit 0
[/bash]

changePercent.php

[php]
<?php
$searchedFor = $_GET[‘search’];
if(ctype_digit($searchedFor))
{
$test = fopen("percent.txt","rw") or exit("Unable to open file!");
if (($searchedFor > 1) && ($searchedFor <= 100)) {
file_put_contents(‘percent.txt’, $searchedFor);
}
else
{
echo "please enter a value between 1-100";
}
fclose($test);
exec(‘sh checkDHCP.sh’);
}
header( ‘Location: http://192.168.1.254/checkTelefoniDHCP’ ) ;
?>
[/php]

ignoredIPs.php

[php]
<?php
$array = file(‘ignoredIPs.txt’);
$addItem = $_GET[‘search’];
if(valid_ip($addItem))
{
$addItem = "$addItem\n";
array_push ($array,$addItem);
natsort($array);
file_put_contents(‘ignoredIPs.txt’, $array);
exec(‘sh checkDHCP.sh’);
}
header( ‘Location: http://192.168.1.254/checkTelefoniDHCP’ ) ;
?>

<?php
function valid_ip($ip) {
return preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" .
"(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/", $ip);
}
?>
[/php]

index.php

[php]
<html>
<head>
<title>Telefoni checkDHCP</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div id="menu">
<h2>
DHCP-Telefoni-warning
</h2>
<?PHP
if ($_SERVER[‘PHP_AUTH_USER’] == "admin")
{
echo "<form action=\"ignoredIPs.php\" method=\"get\">\n";
echo "<fieldset>\n";
echo "<legend>1.Add single IP (beginning of range) to ignorelist:</legend>\n";
echo "<input type=\"text\" name=\"search\" id=\"search\">\n";
echo "<input type=\"submit\" value=\"Ok\" name=\"Ok\" id=\"addIPs\"> <input type=\"reset\" value=\"Reset\" name=\"Ok\" id=\"resetaddIPs\">\n";
echo "</fieldset>\n";
echo "</form>\n";
echo "<form action=\"removeIPfromIgnored.php\" method=\"get\">\n";
echo "<fieldset>\n";
echo "<legend>2.Remove IP from ignored list:</legend>\n";
echo "<input type=\"text\" name=\"search\" id=\"search\">\n";
echo "<input type=\"submit\" value=\"Ok\" name=\"Ok\" id=\"removeIPs\"> <input type=\"reset\" value=\"Reset\" name=\"Ok\" id=\"resetRemoveIPs\">\n";
echo "</fieldset>\n";
echo "</form>\n";
echo "<form action=\"changePercent.php\" method=\"get\">\n";
echo "<fieldset>\n";
echo "<legend>3.Change percent warning</legend>\n";
echo "<input type=\"text\" name=\"search\" id=\"search\">\n";
echo "<input type=\"submit\" value=\"Ok\" name=\"Ok\" id=\"changePercent\"> <input type=\"reset\" value=\"Reset\" name=\"Ok\" id=\"resetChangePercent\">\n";
echo "</fieldset>\n";
echo "</form>\n";
}
?>
</div>
<div id="iprange">
<h2>
<?PHP
$test = fopen("percent.txt","r") or exit("Unable to open file!");
echo "<div>These IP-ranges are ".fgets($test)."% full or more!</div>\n";
fclose($test);
?>
</h2>
<pre>
<?PHP
include("sendFile.txt");
?>
</pre>
</div>
<div id="ignoredip">
<h2>
Ignored IPs
</h2>
<pre>
<?PHP
include("ignoredIPs.txt");
?>
</pre>
</div>
<div id="output">
<?PHP
include("sampleoutput2.txt");
?>
</div>
<div id="header">
<ul>
<li id="selected"><a href="http://192.168.1.254/checkTelefoniDHCP">checkDHCP Telefoni</a></li>
<li><a href="http://192.168.1.254/manual.php">Manual</a></li>
</ul>
</div>
<div id="signature">
//Coded by Viktor &Aring;
</div>
<div id="poolnames">
<h2>
Pool Names
</h2>
<pre>
<?PHP
include("dhcpd-snmp2.conf");
?>
</pre>
</div>
</body>
</html>
[/php]

manual.php

[php]
<html>
<head>
<title>Manual – Telefoni checkDHCP</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div id="manual">
<h2>Manual – Telefoni checkDHCP</h2>
This script used dhcpd-pools & cacti-dhcp to generate a list of all available DHCP-pools on the server. It then merges the lists and checks if any of the lines in sampleoutput.txt is above the specified range. If so it sends an e-mail to NOC with a warning.
<br>
The menu is only for changing percent or adding a IPrange to ignore.
<br>
1. Add IP to ignore, this make the script ignore that IP-range and no e-mails will be sent.
<br>
2. Remove IP from ignore (mostly for testing).
<br>
3. Change the percent to send warnings on.
<br>
<h2>
FIELDS
</h2>
<b>shared net name</b>
<br>
Name of the shared-network for the range.
<br>
<b>first ip</b>
<br>
First IP in lease pool range.
<br>
<b>last ip</b>
<br>
Last IP in lease pool range.
<br>
<b>max</b>
<br>
Number of IPs which exist in a pool, shared network or all together.
<br>
<b>cur</b>
<br>
Number of leases currently in use.
<br>
<b>percent</b>
<br>
Percent of IPs currently in use compared to max.
<br>
<b>touch</b>
<br>
Number of IPs which appear in the lease file, but whos leases have expired. A touched IP is either expired or abandoned. The touched IP count is somewhat misleading when you try to determine if an IP pool is big enough; it is a better indicator of whether a pool is too large.
<br>
<b>t+c</b>
<br>
The sum of Touched and Currently in-use leases.
<br>
<b>t+c perc</b>
<br>
Percent of IPs either touched or currently in use, compared to max.
<br>
<b>bu</b>
<br>
Failover pair can allocate these addresses. The count appears only if there is failover configuration.
<br>
<b>bu perc</b>
<br>
Percent of addresses that failover pair can allocate. The percent appears only if there is failover configuration.
<br><br>
//Coded by Viktor &Aring;
</div>
<div id="header">
<ul>
<li><a href="http://192.168.1.254/checkTelefoniDHCP">checkDHCP Telefoni</a></li>
<li id="selected"><a href="http://192.168.1.254/manual.php">Manual</a></li>
</ul>
</div>
[/php]

removeIPfromIgnored.php

[php]
<?php
$lines = file(‘ignoredIPs.txt’);
$searchedFor = $_GET[‘search’];
if(valid_ip($searchedFor))
{
foreach ($lines as $line_num => $line)
{
if(stristr($line, $searchedFor)) {
print "<div>{$line} was removed from the ignorelist.</div>\n";
unset($lines[$line_num]);
file_put_contents(‘ignoredIPs.txt’, implode("", $lines));
$result = 1;
}
}
exec(‘sh checkDHCP.sh’);
}
header( ‘Location: http://192.168.1.254/checkTelefoniDHCP’ ) ;
?>

<?php
function valid_ip($ip) {
return preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" .
"(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/", $ip);
}
?>
[/php]

runScript.php

[php]
<?php
exec(‘sh checkDHCP.sh’);
header( ‘Location: http://192.168.1.254/checkTelefoniDHCP’ ) ;
?>

[/php]

style.css

[css]
<style type="text/css">
body {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
color: black;
background-color: white;
}
input {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
color: black;
background-color: white;
}
div {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
background:white;
color: black;
}
* {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
color: black;
background-color:white;
}
h2 {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 15px;
}
iframe {
background-color: white;
height: 100%;
width: 100%;
}
a:link { color: blue; text-decoration: none; }
a:visited { color: blue; text-decoration: none; }
a:active { color: blue; text-decoration: none; }
a:hover { color: blue; text-decoration: underline; }
fieldset {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
background:white;
color:black;
position:relative;
}
legend {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
background:white;
color:black;
padding:1px 2px;
}
#header ul {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
list-style: none;
padding: 0;
margin: 0;
}

#header li {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
display: inline;
margin: 0 2px 0 0;
}
#header a {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
padding: 0 1em;
text-decoration: none;
color: blue;
background: white;
}
#header a:hover {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
background: white;
color: blue;
text-decoration: underline;
}
#header #selected {
}
#header #selected a {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
padding-bottom: 2px;
text-decoration: underline;
font-weight: bold;
color: blue;
background: white;
}
#menu { position:absolute; width:340px; height:305px; z-index:1; left:30px; top:50px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#iprange { position:absolute; width:350px; height:140px; z-index:1; left:30px; top:330px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#ignoredip { position:absolute; width:350px; height:250px; z-index:1; left:30px; top:460px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#output { position:absolute; width:600px; height:750px; z-index:1; left:1060px; top:50px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#signature { position:absolute; width:200px; height:100px; z-index:1; left:30px; top:710px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#manual { position:absolute; width:1000px; height:1000px; z-index:1; left:30px; top:50px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
#poolnames { position:absolute; width:650px; height:750px; z-index:1; left:390px; top:50px; clip: rect(0 100% 100% 0); text-align: left;layer-background-color: transparent; background-color: transparent; overflow: auto}
</style>
[/css]

Ok, now we need to make apache access these pages and protect it. Also make sure www-data is owner (just in case anything got owned as other user while creating them).
[bash]
sudo chown -R www-data:www-data /home/checkDHCP
#But make sure to secure the php files:
chown root:root /home/checkDHCP/*.php
vim /etc/apache2/conf.d/dhcp-warning
Alias /checkInternetDHCP /home/checkDHCP

<Directory /home/checkDHCP>
Options FollowSymLinks Indexes
AllowOverride All
<Limit GET POST>
order deny,allow
deny from all
allow from 192.168.1.254
</Limit>
DirectoryIndex index.php
<Files *.txt>
Order allow,deny
Deny from all
</Files>
</Directory>
#Now restart apache
/etc/init.d/apache restart
[/bash]

Now we need to setup DHCPd-snmp (atleast the script) so my script can get the headers from it. This is easily done by:
[bash]
cd dhcp-snmp
sudo chmod +x dhcp2snmpconf.pl
./dhcp2snmpconf.pl /etc/dhcp3/dhcpd.conf > /home/checkDHCP/dhcpd-snmp.conf
[/bash]

You can now reach the webpage at http://your.ip/checkInternetDHCP.

You can also put this script running under cron, just:
[bash]
su www-data
crontab -e
#Lets run the script every second hour between 8-22
0 2,8-22 * * * /home/checkDHCP/checkDHCP.sh
[/bash]

This is how all looks like in the end (I’ve omitted the beginning of the IP ranges and the aliases for security reasons):

And this is how it looks like when you receive the e-mail:

FAQ:

1. You need to have a working sendmail, try it out manually if you have troubles getting mails sent. /usr/bin/mail is contained in the package mailutils I think. So apt-get install mailutils.
2. dhcpd-pools still can’t handle dynamic-bootp lines (even with 2.13), if you have those in your dhcp3.conf file you must remove them, I modified my checkDHCP.sh:
[bash]
replace
/usr/local/bin/dhcpd-pools -c /etc/dhcp3/dhcpd.conf -l /var/lib/dhcp3/dhcpd.leases -o $installDir/sampleoutput.txt
with
cp /etc/dhcp3/dhcpd.conf $installDir/dhcpd.conf_backup
cat $installDir/dhcpd.conf_backup | sed s/dynamic-bootp// > $installDir/test2
/usr/local/bin/dhcpd-pools -c $installDir/test2 -l /var/lib/dhcp3/dhcpd.leases -o $installDir/sampleoutput.txt
[/bash]

Categories
Linux script, PHP
Tags
dhcpd-pools dhcpd-snmp mail warning
Comments rss
Comments rss

« Cacti 0.8.7g + WeatherMap 0.97a Apache2 rewrite+ssl+roundcube »

Contents

  • 1 checkDHCP.sh
  • 2 changePercent.php
  • 3 ignoredIPs.php
  • 4 index.php
  • 5 manual.php
  • 6 removeIPfromIgnored.php
  • 7 runScript.php
  • 8 style.css
  • 9 FAQ:

Ads & Posts

I'm using ads to keep this site running. Please don't block them and if you don't mind consider clicking an ad or two to support this blog.

Feel free to use any code I've posted, consider it GPL or whatever. All I ask is that if you find it useful or see improvements that you write a comment about it and credit me if you use it somewhere else :)

Thanks
/Viktor
rss Comments rss