In this tutorial, I’d like to share with you my 7 tips for blocking email spam with Postfix SMTP server. Over the last four years of running my own email server, I received lots of spam, aka unsolicited commercial email, most of which came from China and Russia. Spam exists because it’s so cheap to send large volume of emails on the Internet. Postfix allows you to block spam before they get into your mailbox, so you can save bandwidth and disk space. This post is the result of my experience in fighting spam.

Note: If you plan to run your own mail server, I recommend using iRedmail, which really simplifies the process of setting up a mail server. It also ships with anti-spam rules. If you prefer to set up a mail server from scratch, then check out my mail server tutorial series.

Characteristics of Spam

Below is what I found about email spam. These spam are easy to block.

  1. Their IP addresses don’t have PTR records.
  2. The spammer doesn’t provide valid hostname in HELO/EHLO clause.
  3. They spoof MAIL FROM address.
  4. They generally don’t re-send email after a failed email delivery.

Legitimate email servers should never have these characteristics. So here comes my 7 tips, which will block 90% of spam.

Fact: Around 93%~95% of emails in the world are rejected at the SMTP gateway, never landed in the inbox or spam folder.

Tip #1: Reject Email if SMTP Client Has no PTR record

PTR record maps an IP address to a domain name. It’s the counterpart to A record. On Linux, you can query the domain name associated with an IP address by executing the following command:

host 

For example, the following command returns the hostname of Google’s mail server.

host 209.85.217.172

Output:

172.217.85.209.in-addr.arpa domain name pointer mail-ua0-f172.google.com.

Due to the prevalence of spam, many mail servers require that SMTP clients have valid PTR records associated with their IP addresses. Every mail server admin should set PTR record for their SMTP servers. If the SMTP client has a PTR record, you can find a line in Postfix log like below.

connect from mail-ua0-f172.google.com[209.85.217.172]

If the SMTP client doesn’t have a PTR record, then the hostname will be identified as unknown.

connect from unknown[120.41.196.220]

To filter out emails with no PTR records, open Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following line in smtpd_sender_restrictions. This directive rejects an email if the client IP address has no PTR record.

reject_unknown_reverse_client_hostname

Example:

smtpd_sender_restrictions =
   permit_mynetworks
   permit_sasl_authenticated
   reject_unknown_reverse_client_hostname

Save and close the file. Then restart Postfix for the change to take effect.

sudo systemctl restart postfix

Tip #2: Enable HELO/EHLO Hostname Restrictions in Postfix

Some spammers don’t provide a valid HELO/EHLO hostname in the SMTP dialog. They can be non fully qualified domain name, or a domain name doesn’t exist or only for internal network. For example, a spammer using a Amazon EC2 instance to send spam is logged on my server as follows:

Aug 16 04:21:13 email postfix/smtpd[7070]: connect from ec2-54-237-201-103.compute-1.amazonaws.com[54.237.201.103]
Aug 16 04:21:13 email policyd-spf[7074]: prepend Received-SPF: None (mailfrom) identity=mailfrom; client-ip=54.237.201.103; helo=ip-172-30-0-149.ec2.internal; [email protected]; receiver=

As you can see, the HELO hostname is ip-172-30-0-149.ec2.internal , which is only valid in AWS internal network. It has no valid A record nor MX record.

To enable HELO/EHLO hostname restriction, edit Postfix main configuration file.

sudo nano /etc/postfix/main.cf

First, add the following line to require the client to provide a HELO/EHLO hostname.

smtpd_helo_required = yes

Then add the following 3 lines to enable smtpd_helo_restrictions.

smtpd_helo_restrictions = 
    permit_mynetworks
    permit_sasl_authenticated

Use the following line to reject clients who provide mailformed HELO/EHLO hostname.

reject_invalid_helo_hostname

Use the following line to reject non fully qualified HELO/EHLO hostname.

reject_non_fqdn_helo_hostname

To reject email when the HELO/EHLO hostname has neither DNS A record nor MX record, use

reject_unknown_helo_hostname

Like this:

smtpd_helo_required = yes
smtpd_helo_restrictions =
    permit_mynetworks
    permit_sasl_authenticated
    reject_invalid_helo_hostname
    reject_non_fqdn_helo_hostname
    reject_unknown_helo_hostname

Save and close the file. Then reload Postfix.

sudo systemctl reload postfix

Note that although most legitimate mail servers have valid A record for the HELO/EHLO hostname, occasionally a legitimate mail server doesn’t meet this requirement. You need to whitelist them with check_helo_access.

smtpd_helo_required = yes
smtpd_helo_restrictions =
    permit_mynetworks
    permit_sasl_authenticated
    check_helo_access hash:/etc/postfix/helo_access
    reject_invalid_helo_hostname
    reject_non_fqdn_helo_hostname
    reject_unknown_helo_hostname

Then you need to create the /etc/postfix/helo_access file.

sudo nano /etc/postfix/helo_access

Whitelist legitimate mail server’s HELO/EHLO hostname like below.

optimus-webapi-prod-2.localdomain      OK
va-massmail-02.rakutenmarketing.com    OK

It’s likely that you don’t know which hostnames to whitelist, then simply copy the above two lines, which is the only lines in my helo_access file. You can always add more hostnames later. Save and close the file. Then run the following command to create the /etc/postfix/helo_access.db file.

sudo postmap /etc/postfix/helo_access

And reload Postfix.

sudo systemctl reload postfix

Tip #3: Reject Email if SMTP Client Hostname doesn’t have valid A Record

A legitimate email server should also have a valid A record for its hostname. The IP address returned from A record should match the IP address of email server. To filter out emails from hosts that don’t have valid A record, edit Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following line in smtpd_sender_restrictions.

reject_unknown_client_hostname

Example:

smtpd_sender_restrictions =
   permit_mynetworks
   permit_sasl_authenticated
   reject_unknown_reverse_client_hostname
   reject_unknown_client_hostname

Save and close the file. Then restart Postfix for the change to take effect.

sudo systemctl restart postfix

Note that reject_unknown_client_hostname does not require HELO from SMTP client. It will fetch the hostname from PTR record, then check the A record.

Tip #4: Reject Email If MAIL FROM Domain Has Neither MX Record Nor A Record

The MAIL FROM address is also known as envelope from address. Some spammers use a non-existent domain in the MAIL FROM address. If a domain name has no MX record, Postfix will find the A record of the main domain and send email to that host. If the sender domain has neither MX record nor A record, Postfix can’t send email to that domain. So why not reject emails that you can’t reply to?

To filter out this kind of spam, edit Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following line in smtpd_sender_restrictions. It will reject email if the domain name of the address supplied with the MAIL FROM command has neither MX record nor A record.

reject_unknown_sender_domain

Example:

smtpd_sender_restrictions =
   permit_mynetworks
   permit_sasl_authenticated
   reject_unknown_sender_domain
   reject_unknown_reverse_client_hostname
   reject_unknown_client_hostname

Save and close the file. Then restart Postfix for the change to take effect.

sudo systemctl restart postfix

Note that I placed this restriction above other reject restrictions. From my experience, if it is below other reject restrictions, it won’t work. (Maybe this only happens on my email server.)

Tip #5: Enable Greylisting in Postfix

As required by the SMTP protocol, any legitimate SMTP client must be able to re-send email if delivery fails. (By default, Postfix is configured to resend failed emails many times before it informs the sender that the message could not be delivered.) Many spammers usually just send once and would not retry.

Postgrey is a greylisting policy server for Postfix. You can install postgrey on Ubuntu from the default repository.

sudo apt install postgrey

It will be automatically started, as shown with:

sudo systemctl status postgrey

And it listens on TCP port 10023 on localhost (both IPv4 and IPv6).

sudo netstat -lnpt | grep postgrey

By default, the greylist time is 300 seconds, which means an unknown SMTP client needs to wait 5 minutes before re-sending the email. If that’s very long to you, you can change it to 60 seconds or 120 seconds. This can be configured in /etc/default/postgrey file.

sudo nano /etc/default/postgrey

Find the following line.

POSTGREY_OPTS="--inet=10023"

Change it to

POSTGREY_OPTS="--inet=127.0.0.1:10023 --delay=60"

Save and close the file. Then restart postgrey for the change to take effect.

sudo systemctl restart postgrey

Next, we need to edit Postfix main configuration file to make it use the greylisting policy server.

sudo nano /etc/postfix/main.cf

Add the following line in smtpd_recipient_restrictions.

check_policy_service inet:127.0.0.1:10023

In case you don’t know, the directive check_policy_service unix:private/policyd-spf in the above screenshot will make Postfix check SPF record on the sender’s domain and you are advised to implement SPF and DKIM on your own domain to improve your email sender score.

Save and close the file. Then restart Postfix.

sudo systemctl restart postfix

From now on, Postgrey will reject an email if the sender triplet (sender IP address, sender email address, recipient email address) is new. The following log message in /var/log/mail.log shows a new sender triplet. The action “greylist” means this email message was rejected.

postgrey[1016]: action=greylist, reason=new, client_name=unknown, client_address=117.90.24.148/32, [email protected], [email protected]

From my experience, Chinese email spammers like to use a fake, weird-looking and randomly generated sender address for every email, so adding these fake email addresses to blacklist won’t stop them. On the other hand, they never try re-sending a rejected email with the same sender address, which means greylisting can be very effective at stopping this kind of spam.

Fixing Error

If you see the following error in mail log (/var/log/mail.log)

warning: connect to 127.0.0.1:10023: Connection refused
warning: problem talking to server 127.0.0.1:10023: Connection refused

The problem is that postgrey is not running. You need to specify 127.0.0.1 as the listening address in  /etc/default/postgrey file. So change the following line

POSTGREY_OPTS="--inet=10023"

to

POSTGREY_OPTS="--inet=127.0.0.1:10023"

Then restart postgrey

sudo systemctl restart postgrey

Check if it’s listening:

sudo netstat -lnpt | grep 10023

Whitelisting

Greylisting can result in bad experience for the end user, as the user has to wait another several minutes for the email to arrive. To minimize this bad experience, you can create whitelist.

Postgrey ships with two whitelist files (/etc/postgrey/whitelist_clients and /etc/postgrey/whitelist_recipients). The former contains a list of hostnames and the latter contains a list of recipient addresses.

By default, Google’s mail servers are whitelisted. No matter the sender is using a @gmail.com address or other address, as long as the sender is using Google’s mail server, Postgrey won’t reject the email. The following line in my /var/log/mail.log file shows this.

postgrey[1032]: action=pass, reason=client whitelist, client_name=mail-yb0-f190.google.com

Note: You can also see postgrey logs with this command sudo journalctl -u postgrey.

You can add other hostnames in whitelist_clients file, like

facebook.com
bounce.twitter.com
blogger.com
email.medium.com

You can get these hostnames with a tool called pflogsumm, which I will discuss later in this article.

Tip #6: Using Public Anti-Spam Blacklists

There are spam emails that are sent from servers that has a valid hostname, valid PTR record and can pass through grey listing. In this case, you can use blacklisting to reject spam. There are many public anti-spam blacklists, also known as DNSBLs (DNS based lists). You can use multiple blacklists to block spam.  Go to https://www.debouncer.com and mxtoolbox.com , enter the spammer’s domain and IP address to see which blacklists are blocking them, then you can use those blacklists. For example, I found that spammers are blacklisted by one of the following blacklists:

  • dbl.spamhaus.org
  • zen.spamhaus.org
  • multi.uribl.com
  • ivmURI
  • InvaluementURI

So I can add the following configurations in /etc/postfix/main.cf file. Some public blacklisting service requires monthly fee. For now, I’m using the free service of spamhaus.org.

smtpd_recipient_restrictions =
   permit_mynetworks,
   permit_sasl_authenticated,
   reject_rhsbl_helo dbl.spamhaus.org,
   reject_rhsbl_reverse_client dbl.spamhaus.org,
   reject_rhsbl_sender dbl.spamhaus.org,
   reject_rbl_client zen.spamhaus.org

Where:

  • rhs stands for right hand side, i.e, the domain name.
  • reject_rhsbl_helo makes Postfix reject email when the client HELO or EHLO hostname is blacklisted.
  • reject_rhsbl_reverse_client: reject the email when the unverified reverse client hostname is blacklisted. Postfix will fetch the client hostname from PTR record. If the hostname is blacklisted, reject the email.
  • reject_rhsbl_sender makes Postfix reject email when the MAIL FROM domain is blacklisted.
  • reject_rbl_client: This is an IP-based blacklist. When the client IP address is backlisted, reject the email.

Some spammers use Google’s mail server, so reject_rhsbl_helo is ineffective, but most of them use their own domain names in the MAIL FROM header, so reject_rhsbl_sender will be effective.

Create A Whitelist

Sometimes there are legitimate email servers blacklisted. You can create a whitelist so they won’t be blocked. Create the following file.

sudo nano /etc/postfix/rbl_override

In this file, whitelist domain names like below.

dripemail2.com  OK           //This domain belongs to drip.com

mlsend.com      OK           //This domain belongs to mailerlite email marketing service

Save and close the file. Then run the following command to create the rbl_override.db file.

sudo postmap /etc/postfix/rbl_override

Edit Postfix main configuration file.

sudo nano /etc/postfix/main.cf

In smtpd_recipient_restrictions, add the following line.

check_client_access hash:/etc/postfix/rbl_override,

Reload Postfix for the changes to take effect.

sudo systemctl reload postfix

My Postfix Spam filters

Here’s a screenshot of my Postfix spam filters.

You might be wondering why there is no coma in the first two configuration snippets. Well, you can separate values in Postfix configuration file with space, carriage return or coma. If you add coma to one parameter (smptd_recipient_restrictions as in the above screenshot), then make sure all remaining values are separated with coma.

Postfix Log Report

Pflogsumm is a great tool to create a summary of Postfix logs. Install it on Ubuntu with:

sudo apt install pflogsumm

Use the following command to generate a report for today.

sudo pflogsumm -d today /var/log/mail.log

Generate a report for yesterday.

sudo pflogsumm -d yesterday /var/log/mail.log

If you like to generate a report for this week.

sudo pflogsumm /var/log/mail.log

To emit “problem” reports (bounces, defers, warnings, rejects) before “normal” stats, use --problems-first flag.

sudo pflogsumm -d today /var/log/mail.log --problems-first

To append the email from address to each listing in the reject report, use --rej-add-from flag.

sudo pflogsumm -d today /var/log/mail.log --rej-add-from

To show the full reason in reject summaries, use --verbose-msg-detail flag.

sudo pflogsumm -d today /var/log/mail.log --rej-add-from --verbose-msg-detail

You can add a cron job to make pflogsumm to send a report to your email address every day.

sudo crontab -e

Add the following line, which will generate a report every day at 4:00 AM.

0 4 * * * /usr/sbin/pflogsumm -d yesterday /var/log/mail.log --problems-first --rej-add-from --verbose-msg-detail -q

To receive the report via email, add the following line above all cron jobs.

MAILTO="your-email-address"

You should pay attention to the message reject detail section, where you can see for what reason those emails are rejected and if there’s any false positives. Greylisting rejections are safe to ignore.

If the MAILTO variable has already been set but you want Postfix log summary sent to a different email address, you can put the following line in your Cron job.

0 4 * * * /usr/sbin/pflogsumm -d yesterday /var/log/mail.log --problems-first --rej-add-from --verbose-msg-detail -q | mutt -s "Postfix log summary"  your-email-address

The output of pflogsumm command is redirected to mutt, a command line mail user agent, which will use the output as the email body and send it to the email address you specify at the end. Of course, you need to install mutt on your Linux server.

sudo apt install mutt

Tip #7: Set Up OpenDMARC to Reject Emails That Fail DMARC Check

DMARC (Domain-based Message Authentication, Reporting and Conformance) is an Internet standard that allows domain owners to prevent their domain names from being used by email spoofers. Please read the following guide.

Don’t be an Open Relay

Mail servers that forward mail on behalf of anyone towards any destination is called open relay. In the beginning, this is a good thing. As time went by, open relays are abused by spammers and now open relays are often blacklisted. The following line in /etc/postfix/main.cf file prevents your email server from being an open relay.

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination

This line tells Postfix to forward email only from clients in trusted networks, from clients that have authenticated with SASL, or to domains that are configured as authorized relay destinations. It should be already in the main configuration file after you install Postfix.

How to Stop SMTP AUTH Flood from Spammers

After some time, the spammer knew that he cannot get through my spam filter. This bad actor started flooding my email server with SMTP AUTH connections. In my /var/log/mail.log file, I can find the following messages.

Dec 14 09:58:37 email postfix/smtpd[22095]: connect from unknown[117.86.35.119]
Dec 14 09:58:37 email postfix/smtpd[22119]: lost connection after AUTH from unknown[114.232.141.99]
Dec 14 09:58:37 email postfix/smtpd[22119]: disconnect from unknown[114.232.141.99] ehlo=1 auth=0/1 commands=1/2
Dec 14 09:58:37 email postfix/smtpd[22119]: connect from unknown[180.120.191.91]
Dec 14 09:58:38 email postfix/smtpd[22095]: lost connection after AUTH from unknown[117.86.35.119]
Dec 14 09:58:38 email postfix/smtpd[22095]: disconnect from unknown[117.86.35.119] ehlo=1 auth=0/1 commands=1/2
Dec 14 09:58:38 email postfix/smtpd[22119]: lost connection after AUTH from unknown[180.120.191.91]
Dec 14 09:58:38 email postfix/smtpd[22119]: disconnect from unknown[180.120.191.91] ehlo=1 auth=0/1 commands=1/2
Dec 14 09:58:38 email postfix/smtpd[22095]: connect from unknown[49.67.68.34]
Dec 14 09:58:39 email postfix/smtpd[22106]: lost connection after AUTH from unknown[180.120.192.199]
Dec 14 09:58:39 email postfix/smtpd[22106]: disconnect from unknown[180.120.192.199] ehlo=1 auth=0/1 commands=1/2
Dec 14 09:58:39 email postfix/smtpd[22095]: lost connection after AUTH from unknown[49.67.68.34]
Dec 14 09:58:39 email postfix/smtpd[22095]: disconnect from unknown[49.67.68.34] ehlo=1 auth=0/1 commands=1/2
Dec 14 09:58:39 email postfix/smtpd[22119]: connect from unknown[121.226.62.16]
Dec 14 09:58:39 email postfix/smtpd[22119]: lost connection after AUTH from unknown[121.226.62.16]
Dec 14 09:58:39 email postfix/smtpd[22119]: disconnect from unknown[121.226.62.16] ehlo=1 auth=0/1 commands=1/2
Dec 14 09:58:39 email postfix/smtpd[22106]: connect from unknown[58.221.55.21]
Dec 14 09:58:40 email postfix/smtpd[22106]: lost connection after AUTH from unknown[58.221.55.21]
Dec 14 09:58:40 email postfix/smtpd[22106]: disconnect from unknown[58.221.55.21] ehlo=1 auth=0/1 commands=1/2
Dec 14 09:58:47 email postfix/smtpd[22095]: connect from unknown[121.232.65.223]
Dec 14 09:58:47 email postfix/smtpd[22095]: lost connection after AUTH from unknown[121.232.65.223]
Dec 14 09:58:47 email postfix/smtpd[22095]: disconnect from unknown[121.232.65.223] ehlo=1 auth=0/1 commands=1/2

Postfix is designed to run even under stressful conditions. It uses a limited amount of memory, so such attacks are much less effective. However, I don’t want them to appear in my mail log. To stop this kind of flood attack, you can use fail2ban, which is a set of server and client programs to limit brute force authentication attempts. Install fail2ban from default Ubuntu repository.

sudo apt install fail2ban

After it’s installed, it will be automatically started, as can be seen with:

sudo systemctl status fail2ban

The fail2ban-server program included in fail2ban monitors log files and issues ban/unban command. By default, it would ban a client’s IP address for 10 minutes if the client failed authentication 5 times. The ban is done by adding iptables firewall rules. You can check iptables rules by running the following command.

sudo iptables -L

To enable fail2ban on Postifx SMTP AUTH attack, add the following lines in /etc/fail2ban/jail.local file. If the file doesn’t exist, then create this file.

[postfix-flood-attack]
enabled  = true
bantime  = 10m
filter   = postfix-flood-attack
action   = iptables-multiport[name=postfix, port="http,https,smtp,submission,pop3,pop3s,imap,imaps,sieve", protocol=tcp]
logpath  = /var/log/mail.log

You can change the bantime to something like 30m or 12h to ban the bad actor for longer time. If you would like to whitelist your own IP address, add the following line to tell fail2ban to ignore your IP address. Replace 12.34.56.78 with your own IP address. Multiple IP addresses are separated by spaces.

ignoreip = 127.0.0.1/8 ::1 12.34.56.78

By default, the allowed max number of failure it 5 times. After 5 failures, the client will be banned. To specify a customized number of failures, add the following line. Change the number to your liking.

maxretry = 4

Save and close the file. Then create the filter rule file.

sudo nano /etc/fail2ban/filter.d/postfix-flood-attack.conf

In this file, we specify that if the “lost connection after AUTH from” is found, then ban that IP address.

[Definition]
failregex = lost connection after AUTH from (.*)[]
ignoreregex =

Save and close the file. Restart fail2ban the changes to take effect.

sudo systemctl restart fail2ban

In the fail2ban log file (/var/log/fail2ban.log), I can find the message like below, which indicates the IP address 114.223.221.55 has been banned because it failed authentication 5 times.

2018-12-14 09:52:15,598 fail2ban.filter [21897]: INFO [postfix-flood-attack] Found 114.223.211.55 - 2018-12-14 09:52:15
2018-12-14 09:52:16,485 fail2ban.filter [21897]: INFO [postfix-flood-attack] Found 114.223.211.55 - 2018-12-14 09:52:16
2018-12-14 09:52:20,864 fail2ban.filter [21897]: INFO [postfix-flood-attack] Found 114.223.211.55 - 2018-12-14 09:52:20
2018-12-14 09:52:21,601 fail2ban.filter [21897]: INFO [postfix-flood-attack] Found 114.223.211.55 - 2018-12-14 09:52:21
2018-12-14 09:52:22,102 fail2ban.filter [21897]: INFO [postfix-flood-attack] Found 114.223.211.55 - 2018-12-14 09:52:22
2018-12-14 09:52:22,544 fail2ban.actions [21897]: NOTICE [postfix-flood-attack] Ban 114.223.211.55

I can also check my iptables.

sudo iptables -L

Output:

Chain f2b-postfix (1 references)
target     prot opt source               destination         
REJECT     all  --  195.140.231.114.broad.nt.js.dynamic.163data.com.cn  anywhere             reject-with icmp-port-unreachable
RETURN     all  --  anywhere             anywhere

This indicates fail2ban has set up a iptables rule that reject connection from 195.140.231.114.broad.nt.js.dynamic.163data.com.cn, which is a hostname is used by the spammer.

If you would like to manually block an IP address, run the following command. Replace 12.34.56.78 with the IP address you want to block.

sudo iptables -I INPUT -s 12.34.56.78 -j DROP

If you use UFW (iptables frontend), then run

sudo ufw insert 1 deny from 12.34.56.78 to any

How To Stop Repeat Senders Who Failed Postfix Check

Some spammers use automated tools to send spam. They ignore the Postfix reject message and continue sending spam. For example, sometimes I can see the following message in Postfix summary report.

 504 5.5.2 : Helo command rejected: need fully-qualified hostname; from=<[email protected]> to=<[email protected]> proto=ESMTP helo= (total: 1)
           1   185.191.228.36
 504 5.5.2 : Helo command rejected: need fully-qualified hostname; from=<[email protected]> to=<[email protected]> proto=ESMTP helo= (total: 1)
           1   185.191.228.36
 504 5.5.2 : Helo command rejected: need fully-qualified hostname; from=<[email protected]> to=<[email protected]> proto=ESMTP helo= (total: 1)
           1   185.191.228.36
 504 5.5.2 : Helo command rejected: need fully-qualified hostname; from=<[email protected]> to=<[email protected]> proto=ESMTP helo= (total: 1)
           1   185.191.228.36
 504 5.5.2 : Helo command rejected: need fully-qualified hostname; from=<[email protected]> to=<[email protected]> proto=ESMTP helo= (total: 1)
           1   185.191.228.36
 504 5.5.2 : Helo command rejected: need fully-qualified hostname; from=<[email protected]> to=<[email protected]> proto=ESMTP helo= (total: 1)

This spammer continues sending spam, ignoring the Postfix reject message: Helo command rejected: need fully-qualified hostname. To stop this kind of behavior, we can also use Fail2ban by adding the following lines in /etc/fail2ban/jail.local file.

[postfix]
enabled = true
maxretry = 3
bantime = 1h
filter = postfix
logpath = /var/log/mail.log

The [postfix] jail will use the builtin filter shipped with Fail2ban (/etc/fail2ban/filter.d/postfix.conf). Save and close the file. Then restart Fail2ban.

sudo systemctl restart fail2ban

Now the spammer will have to wait 1 hour before pounding your mail server again.

Bonus Tip For iRedMail Users

iRedMail automatically configures Postscreen with Postfix. By default, there is a pregreet test in Postscreen to detect spam. As you may already know, in SMTP protocol, the receiving SMTP server should always declare its hostname before the sending SMTP server does so. Some spammers violate this rule and declare their hostnames before the receiving SMTP server does.

Sometimes I can see the following lines in /var/log/mail.log file, which indicates that this sender declare its hostname first. This spammer just want to pound my mail server with endless connections, but has no intent to send any email. And the EHLO hostname ylmf-pc is a clear indication that these connections are originated from compromised home computers. (ylmf is an acronym for the defunct Chinese Linux distro: 雨林木风.)

PREGREET 14 after 0.22 from [121.226.63.86]:64689: EHLO ylmf-pcrn
PREGREET 14 after 0.24 from [121.232.8.131]:55705: EHLO ylmf-pcrn
PREGREET 14 after 0.24 from [114.232.9.57]:62783: EHLO ylmf-pcrn

iRedMail ships with a fail2ban rule to filter this kind of malicious activities. You can see the following line in /etc/fail2ban/filter.d/postfix.iredmail.conf file.

PREGREET .* from []:.* EHLO ylmf-pc

But I think the default bantime (1 hour) for this filter to too low. Open the /etc/fail2ban/jail.local file and add a custom bantime parameter like below.

[postfix-iredmail]
enabled   =  true
max-retry =  1
bantime   =  24h
logpath   =  /var/log/mail.log

I set the bantime value to 24 hours because the sender is clearly using compromised home computers. Save and close the file. Restart fail2ban the changes to take effect.

sudo systemctl restart fail2ban

Next Step

I hope these 7 Postfix anti spam measures helped you block email spam. You may also want to read how to block spam by checking email header/body in Postfix and SpamAssassin. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂

Rate this tutorial

[Total: 28 Average: 4.9]