So if you are reading this then you have probably seen what appears to be every bot in China connecting to your Postfix server to attempt anything from relaying to auth attacking.

Well, have I got the solution for you!

Now before you implement this, I will warn you, this is very restrictive, it doesn’t really give any room for client error but believe me, your iptables will be full of blocked hosts in no time!

At a minimum I would suggest you have iptables configured for ignoring some CIDR’s (like your cell network, home outside IPv4, work address etc) so that you don’t block yourself from the server.

All of these don’t have to be implemented, if you don’t see the need, don’t add it.

Assumptions

I will assume you have a working environment, I’m specifically using Ubuntu 16.04.3 LTS – because of Postfix potentially logging differently depending on the version, I can only say that these regex filters work for this flavor. I use Postfix 3.1.0, to check the version you use:

postconf -d | grep mail_version

You will need:

  1. Ubuntu 16.04 LTS
  2. iptables installed
  3. postfix installed and configured to receive mail
  4. fail2ban installed and basic jail configuration setup

Jails

Like I said before, these are quite brutal, you can change the bantime and maxretry strings as you see fit.

[postfix-auth]
enabled = true
filter = postfix-auth
port = smtp
logpath = /var/log/mail.log
maxretry = 3
bantime = 604800

[postfix-rbl504]
enabled = yes
port     = smtp
logpath  = /var/log/mail.log
maxretry = 2
findtime  = 86400
bantime = 604800

[postfix-rbl450]
enabled = yes
port     = smtp
logpath  = /var/log/mail.log
maxretry = 2
findtime  = 86400
bantime = 604800

[postfix-rbl550]
enabled = yes
port     = smtp
logpath  = /var/log/mail.log
maxretry = 2
findtime  = 86400
bantime = 604800

[postfix-rbl454]
enabled = yes
port     = smtp
logpath  = /var/log/mail.log
maxretry = 2
findtime  = 86400
bantime = 604800

[postfix-rbl554]
enabled = yes
port     = smtp
logpath  = /var/log/mail.log
maxretry = 2
findtime  = 86400
bantime = 604800

Filters

Filters will need to be placed in “/etc/fail2ban/filter.d” folder. The file name will need to be what the jail is called eg: postfix-rbl554 = /etc/fail2ban/filter.d/postfix-rbl554.conf

I know some of these regex queries might look like duplicates but I want to make sure that all conditions are met regardless of string.

Postfix-auth

[Definition]
failregex = lost connection after AUTH from (.*)\[<HOST>\]
	  = lost connection after EHLO from (.*)\[<HOST>\]
	  = lost connection after EHLO from(.*)\[<HOST>\]
	  = lost connection after ELHO from unknown (.*)\[<HOST>\]
          = lost connection after ELHO from unknown(.*)\[<HOST>\]
ignoreregex =

postfix-rbl504

failregex = reject: RCPT from \S+\[<HOST>\]: 504 5\.5\.2 <\S+>: Helo command rejected: need fully-qualified hostname; .*$ 
            NOQUEUE: reject: RCPT from \S+\[<HOST>\]: 504 5\.5\.2 <\S+>: Helo command rejected: need fully-qualified hostname; .*$
	    NOQUEUE: reject: RCPT from \S+\[<HOST>\]: 504 5\.5\.2
ignoreregex =

postfix-rbl450

[Definition]
failregex = reject: RCPT from (.*)\[<HOST>\]: 450 4.7.1
	    NOQUEUE reject: RCPT from (.*)\[<HOST>\]: 450 4.7.1
	    reject: RCPT from (.*)\[<HOST>\]: 450 4.7.8
            NOQUEUE reject: RCPT from (.*)\[<HOST>\]: 450 4.7.8
ignoreregex =

postfix-rbl550

[Definition]
failregex = reject: RCPT from (.*)\[<HOST>\]: 550 5.1.1
	    NOQUEUE: reject: RCPT from (.*)\[<HOST>\]: 550 5.1.1
            reject: RCPT from (.*)\[<HOST>\]: 550 5.7.1
            NOQUEUE: reject: RCPT from (.*)\[<HOST>\]: 550 5.7.1
ignoreregex =

postfix-rbl454

[INCLUDES]
before = common.conf
[Definition]
_daemon = postfix/smtpd
failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 454 4\.7\.1 Service unavailable; Client host \[\S+\] blocked using .* from=<\S*> to=<\S+> proto=ESMTP helo=<\S*>$
	    NOQUEUE: reject: RCPT from \S+\[<HOST>\]: 454 4\.7\.1
	    reject: RCPT from \S+\[<HOST>\]: 454 4\.7\.1
ignoreregex =

postfix-rbl554

[INCLUDES]
before = common.conf
[Definition]
_daemon = postfix/smtpd
failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 554 5\.7\.1 Service unavailable; Client host \[\S+\] blocked using .* from=<\S*> to=<\S+> proto=ESMTP helo=<\S*>$
	  = NOQUEUE: reject: RCPT from \S+\[<HOST>\]: 554 5\.7\.1
ignoreregex =

Conclusion

Obviously, this is not a silver bullet, you should try this along with Postfix RBL blocking and something like Spamassasin for optimal results.

If you really want to clean up your logs and stop wasting resources processing bot attacks then this will really come in handy but just beware you might block a source you aren’t meant to

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.