Protect your FreeBSD box!
I made this simple PHP script because I was tired of getting 400KB security run output emails from my FreeBSD box. It's written in PHP because I'm not good in shell scripting.
Every minute it checks for line like this
Feb 5 01:40:02 kyle sshd[939]: Failed password for root from 80.86.75.67 port 11807 ssh2
in the auth.log and grabs the IP address. If there is more than 3 failed logins from 1 IP address in one minute it is added to the firewall. I'm using the ipfw firewall.
// Both your server and this script must share the same timezone
date_default_timezone_set('Europe/Bratislava');
// Get the last minute.
// We need this because when we run this script from the cron
// it starts at zero seconds and the log file will have not any entries.
$lastminute = mktime(date('G'), date('i') - 1);
// Get the lines with failed logins for last minute
$cmd = '/usr/bin/more /var/log/auth.log | /usr/bin/grep "Failed password" | /usr/bin/grep "';
$cmd .= date('j H:i:', $lastminute).'"';
$output = shell_exec($cmd);
// Make the $output an array
$output = explode("\n", $output);
// Array of IPs that you do not want to block
$ignore = array('127.0.0.1');
// This array will hold IPs with failed logins
$ips = array();
// Get and count IPs
foreach ($output as $line) {
$line = trim($line);
preg_match_all('/[0-9]{1,3}(\.[0-9]{1,3}){3}/', $line, $matches);
foreach ($matches[0] as $ip) {
if (!isset($ips[$ip])) {
$ips[$ip] = 1;
} else {
$ips[$ip]++;
}
}
}
// Block IPs
foreach ($ips as $ip => $count) {
if ($count > 3 && !in_array($ip, $ignore)) {
$data = "/sbin/ipfw -q add 20000 deny log all from {$ip} to me";
file_put_contents('/etc/ipfw-dynamic.rules',$data, FILE_APPEND);
shell_exec($data);
}
}
Put this script to cron and set it to start every minute.

