Block SMTP Relays with Fail2Ban

If your Postfix mail server is constantly bombarded with spammers trying to relay through your system, you might be getting tired of huge log files and incessant spam connects.

To help reduce this we’re going to create our own filter for relay rejects because the regular Postfix filter has a maxretry of 3, and we don’t want to affect that filter so this one will be a maxretry of 1.

Note: Doing this may inadvertently block legitimate SMTP servers, such as Gmail or Yahoo. If you use this, I suggest you set your ban time to a few minutes or less otherwise you may have delayed email. Another solution would be to implement postscreen within Postfix to reduce connections by spammers.

Edit /etc/fail2ban/jail.local

Add a section for [postfix-reject]

enabled  = true
port     = smtp,smtps,submission
filter   = postfix-reject
logpath  = /var/log/mail.log
maxretry = 1

I have my syslog configured to log mail events to mail.log, not syslog, so if you need to change the log path, please do so.

Now copy the Postfix filter and we’ll edit the copy.

cp /etc/fail2ban/filter.d/postfix.conf /etc/fail2ban/filter.d/postfix-reject.conf

nano /etc/fail2ban/filter.d/postfix-reject.conf

Change the failregex line to the following:
(word wrap is affecting the appearance of this code, copy and paste directly and it should look fine)

failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 554 5\.7\.1 .*$
            ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 450 4\.7\.1 .*$
            ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 454 4\.7\.1 .*$
            ^%(__prefix_line)sNOQUEUE: reject: RCPT from (.*)\[<HOST>\]: 554 4\.7\.1 .*$
            ^%(__prefix_line)sNOQUEUE: reject: RCPT from (.*)\[<HOST>\]: 450 4\.7\.1 .*$
            ^%(__prefix_line)sNOQUEUE: reject: RCPT from (.*)\[<HOST>\]: 454 4\.7\.1 .*

Save the config file and run from the shell prompt:

sudo service fail2ban restart


sudo watch -d -n 5 fail2ban-client status postfix-reject

Within minutes you’ll start seeing results, and after a few hours it should look something like this:

Every 5.0s: fail2ban-client status postfix-reject                          

Status for the jail: postfix-reject
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     963
|  `- File list:        /var/log/mail.log
`- Actions
   |- Currently banned: 29
   |- Total banned:     848
   `- Banned IP list:   (...)

That’s it!  If this helped you, please comment below.

If this little writeup helped you, please consider making a donation to help cover operating expenses.