|
Programming Guru
Join Date: May 2004
Location: Brandon, Manitoba, Canada
Posts: 2,023
Rep Power: 7 
|
IP blocker
Hey,
for the past few months, i have noticed a increase of invalid login attempts on my webserver (that has ssh running on it). Bascially these are attempts at brute forcing a username and password set....which as many of you know (or at least the ones that hang around on irc or talk to me on MSN) pisses me off. They have never gotten into ssh, but why leave that chance open?
I got talking with IR (Infinite Recursion) about this problem...i soon found out that he also had a problem with these things. Then i found out that he had a script to add these ip's to his host.deny file (sorry windows users, this is a linux/unix only thing). Long story short, i decided to code my own script.
Here it is:
#!/usr/bin/env perl
use Net::SMTP::TLS;
use Switch;
use POSIX;
use Pg;
#use strict;
#Search Patterns:
my @patterns = ("Did not receive identification string","Invalid user","POSSIBLE BREAKIN ATTEMPT");
#db stuff:
#$con_val[0] == the database name.
#$con_val[1] == the host.
#$con_val[2] == the port.
#$con_val[3] == the username for the database.
#$con_val[4] == the password for the database.
my @conn_val = ("sentinel", "localhost", "5432", "sentinel", "fuck_china");
my $ip;
my $date;
my @months;
$months["Jan"] = 0;
$months["Feb"] = 1;
$months["Mar"] = 2;
$months["Apr"] = 3;
$months["May"] = 4;
$months["Jun"] = 5;
$months["Jul"] = 6;
$months["Aug"] = 7;
$months["Sep"] = 8;
$months["Oct"] = 9;
$months["Nov"] = 10;
$months["Dec"] = 11;
my $time = localtime time;
$time =~ m/\b[0-9][0-9][0-9][0-9]\b/;
my $year = $&;
$year -= 2000;
$year += 100;
#connect up to the db.
$conn = Pg::connectdb("host=" . $conn_val[1] . " port=" . $conn_val[2] . " dbname=" . $conn_val[0] . " user=" . $conn_val[3] . " password=" . $conn_val[4]);
#check connection.
if ($conn->status != PGRES_CONNECTION_OK)
{
die "Failed to connect: ".-$conn->errorMessage."\n";
}
open (TAIL, "tail -f auth.log 2>&1 |") or die "can't open pipe:$!";
while (<TAIL>)
{
switch ($_)
{
case m/$patterns[2]/ { next }
case m/$patterns[0]/
{
#log ip, then block and sms details to admin.
#grab ip addy
$_ =~ m/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
$ip = $&;
#grab date
$_ =~ m/\b[A-z]{3} [0-9]{2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}\b/;
$date = $&;
#now, chunk date out into, $month, day, hours, minutes, seconds.
my ($month, $day, $time) = split(/ /, $date);
my ($hour, $min, $sec) = split(/:/, $time);
my $full_date = mktime($sec, $min, $hour, $day, $months[$month], $year);
my $sql = "INSERT INTO log (ip, date) VALUES ('$ip', $full_date)";
my $result = $conn->exec($sql);
open (DENY, ">>", "host.deny") or die "Can't open host.deny!";
print DENY $ip . "\n";
close DENY;
}
case m/$patterns[1]/
{
#get the fucker's ip address.
$_ =~ m/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
$ip = $&;
open (CHECK, "tail -n6 auth.log 2>&1 |") or die "can't open pipe:$!";
my $count = 0;
while (<CHECK>)
{
$_ =~ m/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
$log_ip = $&;
if ($log_ip == $ip)
{
$count += 1;
}
}
close CHECK;
if ($count >= 3)
{
#we have an attempt.
#log and ban.
$_ =~ m/\b[A-z]{3} [0-9]{2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}\b/;
$date = $&;
my ($month, $day, $time) = split(/ /, $date);
my ($hour, $min, $sec) = split(/:/, $time);
my $full_date = mktime($sec, $min, $hour, $day, $months[$month], $year);
my $sql = "INSERT INTO log (ip, date) VALUES ('$ip', $full_date)";
$conn->exec($sql);
#append to host.deny
open (DENY, ">>", "host.deny") or die "Can't open host.deny!";
print DENY $ip . "\n";
close DENY;
}
}
}
} #end of while loop.
The code scans your auth.log file, for attempts, adds em to hosts.deny and logs them to a db for furture use. I am now working on making a php script to output a graph based on ip and country code. I have a feeling most attempts will come from china, or atleast a ip that's spoofed to look like china.
I plan on expanding this script's features in the future, so any suggestions would be great. One of the ideas for future features that IR and i were talking about is: adding the ip to a .htaccess file to block the ip from accessing web resources. More programs/log files will be supported in the future.
It should be noted, you'll have to change some of the stuff in the script for it to work on your box (ie: location of auth.log and hosts.deny). Also, i designed this script so that you can (and should) start it from a script at startup.
__________________
Profanity is the one language that all programmers understand.
Check out my Blog <---updated Nov 30 2007!
|