The Linux Page

Using your firewall with Postfix

After a little while (very little) our mail server gets quite clogged. It does not cause much problem to our server, however, legal mail server will have a hard time to connect because all of those illegal mail server connect thousands of times to try sending us spam.

To give you an example, I blocked less than 10 IPs today and I got over 5,000 hits blocked within about 12 hours. That's to give you a picture of the badness of those scam robots.

I thus looked for a solution to automatically block those IPs. I found two things, one is a shell script. I do not recommend it since it is rather slow (also, please, remove the -i from the grep option it makes it 10 times slower!)

(Source: https://forum.howtoforge.com/threads/31681/)

#!/bin/bash
IPT=/sbin/iptables
LIMIT=5 # change this to the maximum number of rejected attempt your server will authorize

cd /usr/local/sbin/smtp_flood/ # change this to the path where youinstall the script

# first get hour of log
tail -n 400 /var/log/maillog | grep -i "`date +"%b %e %H:"`" > minutelog
# now extract the rejected attempts, sort and count uniq ip
cat minutelog | grep "reject:" | cut -d" " -f11 | cut -d"[" -f2 | cut
-d"]" -f 1 | sort | uniq -c | sort -n | sed 's/^[ \t]*//' > tmp1
# for each line in result
while read line
do
MYCOUNT=`echo $line | cut -d" " -f1`
MYIP=`echo $line | cut -d" " -f2`

if  [ $MYCOUNT -lt $LIMIT ] ;
then
echo $MYIP je ok: $MYCOUNT poskusov
else

ALREADY=`cat blocked.smtp | grep $MYIP | wc -l`

if  [ $ALREADY -eq "0" ] ;
then
echo blokiramo spemerja $MYIP z $MYCOUNT poskusi
$IPT -I INPUT -i eth0 --proto tcp -s $MYIP --destination-port 25 -j DROP
echo $MYIP >> blocked.smtp
else
echo $MYIP ze blokiran
fi
fi
done < tmp1
# remove temp files
rm -f minutelog
rm -f tmp1

The other solution is to look into fail2ban. That process is used to ban IP addresses for a while if something or other fails. The following is an example setup for that server:

file: /etc/fail2ban/jail.conf

[postfix-tcpwrapper]

enabled = true
filter = postfix
action = hostsdeny
sendmail[name=Postfix, dest=you@yourdomain.net]
logpath = /var/log/maillog
maxretry = 3
bantime = 900
findtime = 900

I did not yet install those, but plan to do that very soon as quite often I have to restart my mail server just so I can send emails!

fail2ban documentation can be found on the tool official website: ftp://ftp.porcupine.org/

Installed and working great!

Wow! I'm very impressed! 8-) So glad I have found that fail2ban system!

Some quick result after not even 1 day of running this system:

1. The load of the server when from 1 1/2 page of connections on port 25 to 4 or 5, which is more than bearable and much more sensible for a small business like ours

2. The number of IPs already blocked is staggering, nearly 2 pages... and that includes non-spammer people whose mail systems are not properly setup (Oops!)

3. Within about 12 hours we got over 63k hit on our server, of which only 55K went through, so fail2ban already blocked 8K connections

Also, for the setup I did two things which have nothing to do with what I have in my article:

1. I turned ON the [postfix] entry and changed the bantime to 1 day (instead of 10 min.) with a max. retry of 3 (which is the default), that's in /etc/fail2ban/jail.conf

[postfix]

enabled = true
port = smtp,ssmtp
filter = postfix
logpath = /var/log/mail.log
bantime = 86400
maxretry = 3

2. I changed the regex with the following in /etc/fail2ban/filter.d/postfix.conf

failregex = reject: RCPT from (.*)\[<HOST>\]: 554 5.7.1
            reject: RCPT from unknown\[<HOST>\]: 450 4.7.1
            reject: RCPT from (.*)\[<HOST>\]: 550 5.1.1

which appears in the Postfix documentation from fail2ban manual, but it is not that easy to find those!

The 450 4.7.1 will block all the accesses from totally unknown domains (that is, from any person sending an email from a computer that does not have a PTR properly defined.) This is what I get the most. From all the blocked IPs, that certainly presents 90% of them.

The 554 are people trying to illegally use our server as a relay.

The 550 is the default offered with fail2ban and represents people trying to email people who do not exist (i.e. blah@example.com when there is no blah account.) I'm thinking that these should probably not be blocked for a whole day in case someone misspelled an email address... since a good mail system will try on the next day and again for 4 days blocking the user for all that time! Still, we always get tons of those 550 errors.