#!/usr/bin/perl -w use strict; use Data::Dumper; my (%tcpserver, %rbl, %tcpsmtp, %smtp, %block); my $dir = '/var/log/qmail/qmail-smtpd'; opendir D, $dir or die $!; my @dirs = sort grep /^@|current/, readdir D; my %ok = map {$_,1} qw/ 128.138.207.242 63.225.177.94 131.193.178.160 /; my $hardlimit = 1000; my $softlimit = 500; for my $file (@dirs) { open F, "$dir/$file" or die $!; while () { if (/tcpserver: .* from ([0-9.]+)/) { $tcpserver{$1}++; } elsif (/rblsmtpd: ([0-9.]+)/) { $rbl{$1}++; } elsif (/qmail-smtpd: .* from ([0-9.]+)/) { $smtp{$1}++; } } } my $tcp = '/etc/tcp.smtp.2'; open T, $tcp or die $!; while () { my $bad = $1 if /^(.*):allow,RBLSMTPD=\"Connection rejected:/; next unless $bad; if ($bad =~ /(\d+\.\d+\.\d+\.)(\d+)-(\d+)/ ) { my $root = $1; for my $i ($2..$3) { my $ip = $root . $i; $tcpsmtp{$ip}++; } } elsif ($bad =~ /\.$/) { $block{$bad}++; } else { $tcpsmtp{$bad}++; } } close T or warn $!; my $msg; my $deny = qq~allow,RBLSMTPD="Connection rejected: see http:// visca.com/rej~; TOP: for my $ip (sort {$tcpserver{$b} <=> $tcpserver{$a}} keys %tcpserver) { for my $range (keys %block) { if ($ip =~ /^$range/) { next TOP; } } next if $rbl{$ip}; next if $tcpsmtp{$ip}; next if $smtp{$ip}; next if $ok{$ip}; if ($tcpserver{$ip} > $hardlimit) { $msg .= "$ip => $tcpserver{$ip}\n"; open T, ">>$tcp" or die $!; print T "$ip:$deny/?$ip\n"; print `tcprules /etc/tcp.smtp.cdb /etc/tmp < /etc/tcp.smtp.2`; my $dns = `dnsname $ip`; chomp $dns; $dns ? ($msg .= "Domain name: $dns\n") : ($msg .= " => No name\n"); $msg .= "\n"; next TOP; } elsif ($tcpserver{$ip} > $softlimit) { $msg .= "$ip => $tcpserver{$ip}"; my $dns = `dnsname $ip`; chomp $dns; $dns ? ($msg .= " => $dns\n") : ($msg .= " => No name\n"); } else {next} } exit unless $msg; my $date = join '-', (split /\s/, scalar localtime())[4,1,2,3]; open M, "|/var/qmail/bin/qmail-inject" or die $!; print M qq~To: lou (!) visca-server.com Subject: Hourly SMTPD alert! $date $msg ~;