My linux qmail/vpopmail/squirrelmail server was based upon netqmail-1.05.
I had a virtual domain that was being hit hard by dictionary attacks. I use RBLSMTP to repel known spammers and include specific IPs in my /etc/tcp.smtp reference for other abusers. So mechanically I just needed the prime offenders' IP addresses and I could update my tcp.smtp.cdb with the necessary details. This is, of course, where the problem arises. This is a pain in the butt without automation. So let's build 'bantcp'.
I had implemented the CHKUSER 2.x qmail patch a while ago and knew I had the necessary detail in my logs.
CHKUSER outputs log entries into /var/log/qmail/smtp/current with lines that look like this:
@40000000439496ae16e1d76c CHKUSER rejected rcpt: from <iqfqswavmgp@spoofeddomain.com::> remote <example.com:unknown:300.400.500.600> rcpt <Melvalqq@example.com> : not existing recipient
(yes, the IP address is altered...)DISCLAIMER: I really suck at elegant bash solutions, so this can probably be done far better than what I've built... but hey, treat this as proof-of-concept for now.
OK, so here's my first kludge at solving this.
1) On the mail server (already running MySQL for vpopmail) create tables in a database I called 'bantcp' with user 'sqluser' and password 'password':
CREATE TABLE banips (
id int(12) NOT NULL auto_increment,
date datetime NOT NULL default '0000-00-00 00:00:00',
ip char(16) NOT NULL default '',
PRIMARY KEY (id)
) TYPE=MyISAM;
CREATE TABLE ips (
ip char(16) NOT NULL default '',
count int(11) NOT NULL default '0'
) TYPE=MyISAM;
2) Create a bash script 'bantcp.sh' (chmod 700 when done):
#!/bin/bash
DOMAIN="example.com"
SQLUSER="sqluser"
SQLPASSWORD="password"
cat /var/log/qmail/smtpd/current | grep 'CHKUSER rejected' | tai64nlocal | grep '$DOMAIN' > $DOMAIN_only.log
perl prep_parse.pl < $DOMAIN_only.log > banip.sql
mysql -u$SQLUSER --password="$SQLPASSWORD" bantcp -e "delete from banips"
mysql -u$SQLUSER --password="$SQLPASSWORD" bantcp -e "delete from ips"
mysql -u$SQLUSER --password="$SQLPASSWORD" bantcp < banip.sql
mysql -u$SQLUSER --password="$SQLPASSWORD" bantcp -e "insert into ips(ip,count) SELECT ip,count(ip) as count FROM banips WHERE date BETWEEN (CURDATE() - INTERVAL 12 HOUR) AND CURDATE() group by ip having count > 5 order by count asc;"
mysql -u$SQLUSER --password="$SQLPASSWORD" bantcp -e "select ip from ips;" > temp.txt
perl bantcp.pl < temp.txt
3) Create the first perl script 'prep_parse.pl'
#!/usr/bin/perl4) Create the last perl script 'bantcp.pl'
#!/usr/bin/perlThe 'bantcp' process is built to output the necessary strings for tcp.smtp to STDOUT. This means when you run the scripts you'll see something like this:
:allow,RBLSMTPD="-Connections from this IP have been banned."
671.6107.5103.4241:allow,RBLSMTPD="-Connections from this IP have been banned."
4201.427.468.444:allow,RBLSMTPD="-Connections from this IP have been banned."
(I plan on figuring out why the first line has output without an IP address. You should ignore that.)
What IS VALUABLE on this output are the lines that begin with an IP address. Using the query embedded in step 2, you now have a list of IPs who have sent email to invalid recipients at the queried domain within the last 12 hours and have tried at least 5 times.
Simply, just copy and paste these lines into the top of your 'tcp.smtp' file and regenerate your tcp.smtp.cdb file
The location of your 'tcp.smtp' file depends upon whether you've built it into /etc/ or /home/vpopmail/ or ......
If you've use the Life with Qmail approach, you should have a qmail application shortcut called 'qmailctl'. To regenerate/refresh the tcp.smtp.cdb file, you should run 'qmailctl cdb'.
| Please see the License terms. | | Return to www.daver.net |