Security and Technology Ramblings…

Perl

For a while now, I have been looking for a simple perl script that would watch a set of hosts/IP addresses and report back an up/down status, min, current and max ping times.

Never found one, so I threw something together below. Feel free to use it the need fits.

Oh, and keep in mind, I’m relatively new to perl. So, I would welcome some feedback or constructive criticism on my coding. Let me know how I should have done it differently.

Screen Output:

Code:



#!/opt/local/bin/perl
################################################
#Script:   pingchart                           #
#Author:   John Penrod                         #
#Contact:  penrodcc -at- gmail.com             #
#Version:  1.17                                 #
#Date:     20110604                            #
################################################
use Net::Ping;
use Term::Screen;
use Term::ReadKey;
ReadMode 4;
my $time = 1; #Sleep between pings
my $initiallength = 0;

open (FILE, "<", "hostfile") or die "Host File Missing!";
  while (<FILE>) {
  chomp;
  push (@host_array, $_);
  }
close (FILE);

foreach my $host (@host_array) {
  $host =~ chomp($host);
  $length = length ($host);
  if ( $length > $initiallength ) {
    $initiallength = $length;
    }
  }

  $length = $initiallength;

my %hash;
my $row = 0;
my $status = "U"; #Default HOST status.
my $currentpingount = 1;
my $dropped = 0;

foreach my $host (@host_array) {
  #           host   min      max  current total avg  
  $hash{$row} = [ $host, 1000000, 0, 0, 0, 0];
  $row++;
  }

$p = Net::Ping->new(icmp,2);
$p->hires();
$scr = new Term::Screen ; unless ($scr) { die " Can not setup screen \n"; }
$scr->clrscr();

while (not( defined ($key = ReadKey(-1)))) {
  $scr->at(0,0) ->puts("Ping Tester - Press Q to quit.");
  $scr->at(2,0) ->puts("Host");     $scr->at(3,0) ->puts("----");
  $scr->at(2,$length+5) ->puts("Status");  $scr->at(3,$length+5) ->puts("------");
  $scr->at(2,$length+25) ->puts("Drop"); $scr->at(3,$length+25) ->puts("----");
  $scr->at(2,$length+33) ->puts("Minimum"); $scr->at(3,$length+33) ->puts("-------");
  $scr->at(2,$length+43) ->puts("Current"); $scr->at(3,$length+43) ->puts("-------");
  $scr->at(2,$length+53) ->puts("Maximum"); $scr->at(3,$length+53) ->puts("-------");
  #$scr->at(2,$length+70) ->puts("Average"); $scr->at(3,$length+70) ->puts("-------");
  our $line = 4;
  for my $h (keys %hash) {
        ($host,$min,$max,$currentping,$totalpings,$average) = @{$hash{$h}};
    ($ret, $duration, $ip) = $p->ping($host, 5.5);  
          $duration2 = 1000 * $duration;
          $duration3 = sprintf("%.2f", "$duration2");
                if ( $duration3 > 5000 ) {
                        $status = "D";
      $totalpings++;
                  $scr->at($line,0)  ->puts("$host");
                  $percent = ($currentping/$totalpings)*100;
                  $percent2 = sprintf("%.2f%%", "$percent");
                  $scr->at($line,$length+5) ->puts("$status $currentping\/$totalpings \($percent2\)");
      $dropped   = $totalpings-$currentping;
                        $scr->at($line,$length+25) ->puts("$dropped");
                        $scr->at($line,$length+33) ->puts("  -  ");
                        $scr->at($line,$length+43) ->puts("  -  ");
                        $scr->at($line,$length+53) ->puts("  -     ");
      @{$hash{$h}} = ("$host", "$min", "$max", "$currentping", "$totalpings", "$average");
                        }
                else    {
      $status = "U";
                        $currentping++;
                        $totalpings++;
      if ( $duration3 <= $min ) {
        $min = $duration3;
        }
      if ( $duration3 >= $max ) {
        $max = $duration3;
        }
      $dropped   = $totalpings-$currentping;
      if ( $dropped > 0) {
                          $max = "Infinite";
                          }
                  $scr->at($line,0)  ->puts("$host");
                  $percent = ($currentping/$totalpings)*100;
                  $percent2 = sprintf("%.2f%%", "$percent");
                  $scr->at($line,$length+5) ->puts("$status $currentping\/$totalpings \($percent2\)");
      $dropped   = $totalpings-$currentping;
                        $scr->at($line,$length+25) ->puts("$dropped");
                        $scr->at($line,$length+33) ->puts("$min");
                        $scr->at($line,$length+43) ->puts("$duration3");
                        $scr->at($line,$length+53) ->puts("$max");
                        @{$hash{$h}} = ("$host", "$min", "$max", "$currentping", "$totalpings", "$average");

    }
    $line++;
     }    
  sleep $time;
}
$line++;
$scr->at($line,0) ->puts("");
ReadMode 0; 
$p->close();

Here’s a great way to automate the process of blacklisting specific countries within the Shorewall firewall system.

Source data is pulled via the website IPDeny.


#!/bin/bash
HOME=/etc/shorewall/country
DATA=/etc/shorewall/country/data
LOG=/var/log/messages
WGET=/usr/bin/wget
MAIL=/usr/bin/mail
SHOREWALL="/sbin/shorewall"
SNAGROOT="http://www.ipdeny.com/ipblocks/data/countries"
COUNTRY="cn af kr"
#LOCALBLACK is an array to add IP addresses you want to manually blacklist.
LOCALBLACK="1.1.1.1 2.2.2.2"
NOW=$(date +"%c")
SUBJECT="Shorewall Country Refresh Status"
EMAIL="your@email.com"
touch $LOG
cat /etc/shorewall/country/blacklist > /etc/shorewall/blacklist
for k  in $COUNTRY
do
  tDB=$DATA/$k.zone
  echo "$NOW: Fetching $k.zone now."
  echo "$NOW: [SHOREWALL BLACKLIST REFRESH] Fetching $k.zone now." >> $LOG
  $WGET -O $tDB $SNAGROOT/$k.zone > /dev/null 2>&1
  echo "$NOW: Dumping $k.zone to shorewall blacklist file."
  echo "$NOW: [SHOREWALL BLACKLIST REFRESH] Dumping $k.zone to shorewall blacklist file." >> $LOG
  echo "#ZONE START FOR $k.zone" >> /etc/shorewall/blacklist
  cat $DATA/$k.zone >> /etc/shorewall/blacklist
  echo "#ZONE STOP FOR $k.zone" >> /etc/shorewall/blacklist
 done
echo "#LocalBlack Start" >> /etc/shorewall/blacklist
for k in $LOCALBLACK
do
echo "$NOW: Dumping local blacklist array to shorewall blacklist file."
echo "$NOW: [SHOREWALL BLACKLIST REFRESH] Dumping local blacklist array to shorewall blacklist file." >> $LOG
echo $k >> /etc/shorewall/blacklist
done
echo "#LocalBlack Stop" >> /etc/shorewall/blacklist
OUTPUT=$($SHOREWALL check |grep -i verified )
if [ "$OUTPUT" = "Shorewall configuration verified" ] ; then
  echo "$NOW: Shorewall config looks good!"
  echo "$NOW: [SHOREWALL BLACKLIST REFRESH] Shorewall config looks good!" >> $LOG
  echo "$NOW: [SHOREWALL BLACKLIST REFRESH] Restarting shorewall now." >> $LOG
  /etc/init.d/shorewall restart
  SUBJECT="Sucess: Shorewall Country Refresh Status"
  echo "$NOW:  Shorewall Country Refresh Status Sucessful!" >/tmp/emailoutput
  $MAIL -s "$SUBJECT" "$EMAIL" < /tmp/emailoutput
else
  echo "$NOW: Shorewall config is bad!" 
  echo "$NOW: [SHOREWALL BLACKLIST REFRESH] Shorewall config is bad!" >> $LOG
        SUBJECT="Failed: Shorewall Country Refresh Status"
        echo "$NOW:  Shorewall Country Refresh Status Failed!" >/tmp/emailoutput
        $MAIL -s "$SUBJECT" "$EMAIL" < /tmp/emailoutput
fi

Disclaimer: This bash script is just something I threw together. Do not blame me if it destroys your system, causes cancer or punches one of your small pets.

Find this useful? Cool. Otherwise, it’s just here to remind me.
It this example, I’m looking for all tasks that have the word “chrome” in it and then stopping them.

kill $(ps aux |grep -i chrome |grep -v grep| awk {‘print $2’})

Sorry, just using the blog as my brain again…

Method to search for files based on a certain size…


find . -type f -size +50M -exec ls -lu {} \;

Method to delete files older than 30 days in a directory…


find . -mtime +30 -type f -exec \rm {} \;

Method to cp or move files after finding them…


find <source directory> -name '*.jpg' -exec cp '{}' <destination directory> \;&