CREATIVE CHAOS   ▋ blog

Use Fail2ban and Postfix Postscreen to Fight Cutwail Botnet

PUBLISHED ON 25/10/2018 — EDITED ON 11/12/2023 — SYSOPS

Intro

My /var/log/mail.log:

Oct 25 12:26:54 sablun postfix/postscreen[20895]: PREGREET 14 after 0.23 from [187.60.214.100]:53007: EHLO ylmf-pc\r\n
Oct 25 12:26:55 sablun postfix/postscreen[20895]: PREGREET 14 after 0.23 from [187.60.214.100]:53128: EHLO ylmf-pc\r\n
Oct 25 12:26:56 sablun postfix/postscreen[20895]: PREGREET 14 after 0.23 from [187.60.214.100]:53254: EHLO ylmf-pc\r\n
Oct 25 12:26:56 sablun postfix/postscreen[20895]: PREGREET 14 after 0.23 from [187.60.214.100]:53362: EHLO ylmf-pc\r\n
Oct 25 12:26:57 sablun postfix/postscreen[20895]: PREGREET 14 after 0.22 from [187.60.214.100]:53484: EHLO ylmf-pc\r\n
Oct 25 12:26:58 sablun postfix/postscreen[20895]: PREGREET 14 after 0.22 from [187.60.214.100]:53587: EHLO ylmf-pc\r\n

Postfix

Create a definition file for HELO requests, for now, we will only reject the “ylmf-pc”:

$ vim /etc/postfix/helo_access

Contents of the file:

ylmf-pc REJECT

Create the Postfix lookup table for the helo access:

$ postmap /etc/postfix/helo_access

Edit the following part, add the last line containing check_helo_access:

$ vim /etc/postfix/main.cf
### Foreign mail servers must present a valid "HELO"
smtpd_helo_required = yes
smtpd_helo_restrictions =   permit_mynetworks
                            reject_invalid_helo_hostname
                            reject_non_fqdn_helo_hostname
                            reject_unknown_helo_hostname
                            check_helo_access hash:/etc/postfix/helo_access

Restart the postfix service:

$ service postfix restart

Fail2ban

Create a filter rule for postscreen:

$ vim /etc/fail2ban/filter.d/postscreen.local

Contents of the file:

[INCLUDES]
before = common.conf

[Definition]
_daemon = postfix/postscreen
failregex = ^%(__prefix_line)sPREGREET \d+ after \d+\.\d+ from \[<HOST>\]:\d+: EHLO ylmf-pc\\r\\n
ignoreregex =

Create a jail.local file, that will be persistent (updates of fail2ban will leave it alone), that defines 1 retry possible before ban for the spammers and enables the rule for postscreen:

$ vim /etc/fail2ban/jail.local

Contents of the file:

[postscreen]
port = smtp,465,submission
logpath = %(postfix_log)s
enabled = true
maxretry = 1

Restart the fail2ban service:

$ service fail2ban restart

Testing

After a while, you can see data accumulation (pkts and bytes values) in the iptables rule using:

$ iptables -nvL
...

Chain f2b-postscreen (1 references)
 pkts bytes target     prot opt in     out     source        destination
 8432  539K RETURN     all  --  *      *       0.0.0.0/0     0.0.0.0/0

...

If the configuration was successful, your log files will also be much cleaner now.

Sources

  1. Post on blogg.no