7 Effective Tips for Blocking Email Spam with Postfix SMTP Server
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 a 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.
- Their IP addresses don’t have PTR records.
- The spammer doesn’t provide valid hostname in HELO/EHLO clause.
- They spoof MAIL FROM address.
- 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 <IP address>
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 (such as Gmail, gmx.com, gmx.net, facebook.com) 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 an internal network. For example, a spammer using an 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=<UNKNOWN>
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 malformed 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 two lines in smtpd_sender_restrictions
.
reject_unknown_reverse_client_hostname 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
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. Debian and Ubuntu users can install postgrey
from the default repository.
sudo apt install postgrey
CentOS/RHEL users can install it from EPEL repository.
sudo dnf install epel-release sudo dnf install postgrey
Once it’s installed, start it with systemctl.
sudo systemctl start postgrey
Enable auto-start at boot time.
sudo systemctl enable postgrey
On Debian and Ubuntu, it listens on TCP port 10023 on localhost (both IPv4 and IPv6).
sudo netstat -lnpt | grep postgrey
On CentOS/RHEL, Postgrey listens on a Unix socket (/var/spool/postfix/postgrey/socket
).
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
if you are using Debian or Ubuntu.
check_policy_service inet:127.0.0.1:10023
If you use CentOS/RHEL, you need to add the following line instead.
check_policy_service unix:/var/spool/postfix/postgrey/socket
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. This directive requires you to install and configure the postfix-policyd-spf-python package.
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 on Debian & Ubuntu
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
How to Minimize Bad User Experience
Greylisting can result in bad experience for the end user, as the user has to wait another several minute for the email to arrive. To minimize this bad experience, you can create a whitelist, and use a second MX record that points to the same host.
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 /etc/postgrey/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. Save and close the file, the restart Postgrey.
sudo systemctl restart postgrey
Create Another MX Hostname with the Same IP Address
You can specify more than one MX record for your domain name like below.
Record Type Name Mail Server Priority MX @ mail.yourdomain.com 0 MX @ mail2.yourdomain.com 5
The sender will try the first mail server (with priority 0). If mail.yourdomain.com rejects email by greylisting, then the sender would immediately try the second mail server (with priority 5).
If the two mail server hostnames have the same IP address, then when the sender tries the second mail server hostname, the email will be accepted immediately (if all other checks pass) and end users will not notice email delay caused by greylisting.
Note that this requires you to set a very small delay time like 1 second in /etc/default/postgrey
(Debian & Ubuntu) or /etc/sysconfig/postgrey
(CentOS/RHEL). The delay time tells the SMTP client how many seconds to wait before sending again. If the delay time is not small enough, then the second email delivery would still be rejected.
Debian/Ubuntu
POSTGREY_OPTS="--inet=127.0.0.1:10023 --delay=1"
CentOS/RHEL
OSTGREY_DELAY="--delay=1"
Restart Postgrey.
sudo systemctl restart postgrey
Also beware that not all mail servers would immediately try the second MX host.
Tip #6: Using Public Realtime 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 realtime blacklists (RBL), also known as DNSBLs (DNS based lists). By realtime it means that the list is always changing. An IP address or domain name could be on the list today and off the list tomorrow, so you could get different result depending on when you query the list.
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, check_policy_service unix:private/policyd-spf, check_policy_service inet:127.0.0.1:10023, 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,
Like below. It should be place above other RBL checks.
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, check_policy_service unix:private/policyd-spf, check_policy_service inet:127.0.0.1:10023, check_client_access hash:/etc/postfix/rbl_override, 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
Reload Postfix for the changes to take effect.
sudo systemctl reload postfix
Using Public Whitelist to Reduce False Positive
Maintaining a private whitelist is necessary sometimes, but you can also use public whitelists, the most famous of which is dnswl.org. Currently, there is only a whitelist for IP address. Domain name whitelist is in beta. To use it, put the following line in smtpd_recipient_restrictions
.
permit_dnswl_client list.dnswl.org=127.0.[0..255].[1..3],
Like below. It should be placed above the reject_rbl_client
check.
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, check_policy_service unix:private/policyd-spf, check_policy_service inet:127.0.0.1:10023, check_client_access hash:/etc/postfix/rbl_override, reject_rhsbl_helo dbl.spamhaus.org, reject_rhsbl_reverse_client dbl.spamhaus.org, reject_rhsbl_sender dbl.spamhaus.org, permit_dnswl_client list.dnswl.org=127.0.[0..255].[1..3], reject_rbl_client zen.spamhaus.org
Another well-known whitelist is swl.spamhaus.org, so you can also add it to your configuration.
permit_dnswl_client swl.spamhaus.org,
It’s impossible for an IP address to be listed in Spamhaus whitelist and blacklist at the same time, so if you only use Spamhaus blacklist in Postfix, then it’s not necessary to check against Spamhaus whitelist.
My Postfix Spam filters
Here’s a screenshot of my Postfix spam filters.
You might be wondering why there is no comma in the first two configuration snippets. Well, you can separate values in Postfix configuration file with space, carriage return or comma. If you add comma to one parameter (smptd_recipient_restrictions
as in the above screenshot), then make sure all remaining values are separated with comma.
Postfix Log Report
Pflogsumm
is a great tool to create a summary of Postfix logs. Install it on Ubuntu with:
sudo apt install pflogsumm
On CentOS/RHEL, pflogsumm is provided by the postfix-perl-scripts
package.
sudo dnf install postfix-perl-scripts
Use the following command to generate a report for today. (Note that on CentOS/RHEL, the mail log file is /var/log/maillog
.)
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
or
sudo dnf 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 one of the following guide to set up OpenDMARC.
- Set Up OpenDMARC with Postfix on Ubuntu to Block Email Spoofing
- Set Up OpenDMARC with Postfix on CentOS/RHEL to Block Email Spoofing
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 and we should save smtpd
processes for legitimiate SMTP clients, instead of wasting time dealing with spambots. 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 (.*)\[<HOST>\] 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-pc\r\n PREGREET 14 after 0.24 from [121.232.8.131]:55705: EHLO ylmf-pc\r\n PREGREET 14 after 0.24 from [114.232.9.57]:62783: EHLO ylmf-pc\r\n
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 \[<HOST>\]:.* 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 filter = postfix.iredmail 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
Running Local DNS Resolver to Speed Up DNS Lookups
As you can see, Postfix will need to lookup DNS records in order to analyze each SMTP dialog. To speed up DNS lookups, you can run a local DNS resolver by following on the tutorials below.
- Run Your Own BIND DNS Resolver on Debian
- Run Your Own BIND DNS Resolver on Ubuntu 18.04
- Run Your Own BIND DNS Resolver on Ubuntu 20.04
- Run Your Own BIND DNS Resolver on CentOS/RHEL
And most DNS blacklists have query limit. Running your own local DNS resolver to cache DNS records can help you stay under the query limit.
Next Step
I hope these 7 Postfix anti spam measures helped you block email spam. You may also want to deploy a content filter such as SpamAssassin to better detect spam.
- Block Email Spam with Postfix and SpamAssassin Content Filter on Debian/Ubuntu
- Set Up SpamAssassin on CentOS/RHEL to Block Email Spam
As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂
Nice! Thanks for ideas.
Really helpful. I currently pay for web hosting and a mail server but my 3 year contract is ending soon and have been researching methods on hosting this on an easy to deploy Vultr instance. Thanks for the spam filter information!!
For several days I trying to set up and secure mail server. It’s probably okay, but I still have questions.
1. GreyList.
In your “How to Easily Set Up a Full-Featured Mail Server on Ubuntu 18.04 with iRedMail” you wrote: “By default, iRedMail has enabled greylisting”. What is better: default iRedMail greylist or Postgrey? If I install Postgrey, should I disable default iRedMail greylist?
2. Fail2ban.
In my version of iRedMail in filter.d/postfix.iredmail.conf file I have something like similar line:
Is this the same rule or I still should add your [postfix-auth] to my jail.local?
And in my jail.local is only one jail [DEFAULT] – is this correct?
If you use iRedMail to set up your mail server, I recommend using the default iRedMail greylisting service and the default Fail2ban jails.
I would use Postgrey and create my custom Fail2ban jails if I set up mail server from scratch.
Excelente post compa gracias por el aporte.
Aunque actualemtne tengo el siguiente problema:
alguna idea de como bloquear esas IP a traves del csf de firewall de centos
Hi, this is nice, but my postfix server accepts mails from local network (192.168.1.xxx) as well as localhost,
so if I follow one of your first four tips, then it will stop sending mails from local network, am I right?
These tips are used to block inbound spam from other SMTP servers. Your own users on the local network and localhost can send emails as usual.
I assume by “accept” you mean outbound emails are submitted to Postfix from local network and localhost, which is different than accepting inbound emails from other SMTP servers.
fail2ban-client status
cat /var/log/auth.log | grep ‘Failed password’ – Debian
cat /var/log/secure | grep ‘Failed password’ – Centos
check_policy_service unix:private/policyd-spf – this blocks gmail and other external mailservers, even if maillog show, that gmail is whitelisted.
Sorry if I didn’t explain it well. You need to follow this tutorial to implement SPF checking.
In practice, SPF is more useful when you combine it with DKIM to enforce DMARC record checking to stop spammers impersonating other person’s domain name.
What if I am using CSF ?
Why the hell you don’t use smtp_client_restrictions?
I sent email from “http://www.anonymailer.net” and I got this response in maillog
postfix/smtpd[15785]: NOQUEUE: reject: RCPT from unknown[10.230.220.57]: 450 4.7.1 Client host rejected: cannot find your reverse hostname, [10.230.220.57]; from= to= proto=ESMTP helo=
Then, I sent email from my gmail account, I get the same (which is not expected)
postfix/smtpd[15785]: NOQUEUE: reject: RCPT from unknown[10.230.220.56]: 450 4.7.1 Client host rejected: cannot find your reverse hostname, [10.230.220.56]; from=
Here is my postfix config:
10.230.220.56 doesn’t seem to be Google’s IP address. Every IP address owned by Google has a reverse DNS record.
Hi, thanks for your post. Let me say my IMHO:
Guys, don’t use greylisting in your postfix config. Because of different implementation many mail servers can attempt second connection through very long time instead of your server advised. Your mail can be delayed for a long time, it’s not good idea for 21 century 🙂
That’s true if you receive emails from many different domains.
Hi, I just updated this article to include more tips for minimizing bad user experience when using greylisting on mail server. https://www.linuxbabe.com/mail-server/block-email-spam-postfix#minimize-bad-ux
These seem quite sensible. When I implemented the HELO checks, however, I started to get emails to my local Postmanster account with subject lines like
I assume these are notifying me of rejected messages. How can I suppress these notification emails?
Postfix by default does not report rejected messages. Getting this kind of email probably means there’s something wrong with your mail server. Usually you can see the reason at the bottom of the email.
for what version of postfix is this?
I find lots of options different from my own. I use bit old version –
mail_version = 2.10.1
but this is what I get with CentOS 7. Should I consider upgrade?
Postfix 3.x on Debian/Ubuntu.
There are several options that are different in Postfix 2.x. You can find the equivalent in Postfix documentation.
I made it a bit different.
I scheduled download of spammers list IP addresses from https://lists.blocklist.de/lists/mail.txt and new addresses I add to previously downloaded lists. So the list get bigger every day.
When in the list is more then 20 addresses in one range then I block the entire range eg. 176.221.42.0/24.
Example of postfix_blocklist_de file:
Postfix conf main.cf:
I made some whois checking that I do not block IPs registered to well known brands/partners and countries.
I also made whitelisting feature. Since I made this, we eliminated 99.99% of spam.
Of course I filtered from log all blocked addresses to check if there is some false blocking and in two months is no regular email blocked.
Sorry for the English, but certainly you have a clue what have I done 😉
These tips helped me perfectly to block spammers and SMTP AUTH requests from our Zentyal email server. Thanks a lot !
Hello,
My server is sending spam emails with my Postfix.
How can that be done? What happened here? Did he get the root password?
Thanks
You can secure your email server against hacking with a self-hosted VPN server.
How to Secure Email Server Against Hacking with VPN (Debian/Ubuntu)
Thanks for your advice, they helped me a lot!
Just a question: pflogsumm configured as you say it sends me a summary email but graylisting warning lines are also included, can they be omitted in some way?
Perhaps you can pipe the pflogsumm report to
sed
, which deletes the lines that contain the word “greylisting”. Of course you need to know how to use thesed
editor.Yes! I’ve used the command
to remove the lines containing the word “Greylisted” and the line directly after it.
thanks!
For the past three years, I am running an email server but receiving a lot of spam. With the help of the technical team, I have learned to block email spam with the Postfix SMTP server. Meanwhile, I have signed up with EasySendy and Mailgun for delivering email newsletters and leveraging sales process.
Hi,
How can postfix be configured to forward email for multiple domains while using TLS terminated behind a F5? Issues we are running into are ehlo banner hostname and TLS cert designation. DO I need a SAN certificate? Does actual hostname of the mailserver need to align with SAN entry? confused?
Mike
I think you fail to properly explain the repercussions that enabling reject_unknown_reverse_client_hostname and reject_unknown_client_hostname can have. First of all I think it is important to make it clear that setting these effectively makes sure that your mail server will not accept mails from people running their own mail servers on home internet connections where the PTR is either rarely set or can not be changed by the customer.
I also think that it is worth mentioning that if the mail server fails for resolve the PTR due to a DNS error, then it leads to delays in mail delivery because reject a mail with 450 means that the sending mail server will have to retry at a late time. Lastly I think the assumption “Their IP addresses don’t have PTR records.” is just wrong, and not only spammers have missing PTR records, and enabling these two setting should be discouraged as they inevitably will lead to false positives and lost or delayed mail. You really shouldn’t recommend these kinds of over approximations but instead push for interoperability.
First of all, you shouldn’t run a mail server with a home IP address, which often has bad IP reputation (dynamic IP) and doesn’t have PTR record. If you really want to run a mail server at home, you should set up SMTP relay. There are many SMTP relay services that offer free quotas, which is enough for people who run mail server at home.
How to Set up Postfix SMTP Relay on Ubuntu with Sendinblue
How to Set up Postfix SMTP Relay on Debian with Sendinblue
How to Set up Postfix SMTP Relay on CentOS/Rocky Linux with Sendinblue
SMTP relay services have PTR records for their servers. So if you don’t have PTR record, use SMTP relay service.
Facebook rejects any IP address that doesn’t have PTR record. Convince Facebook before trying to convince me not to use PTR restriction.
So is the case with GMX.
Gmail rejects emails sent from IP addresses that don’t have PTR record, for both IPv4 and IPv6.
SpamRats have a blacklist for IP addresses that don’t have PTR records.
The SMTP protocol (RFC 2821) recommends that sending SMTP server should retry failed email delivery at least 4-5 days. It’s the case for Postfix SMTP server. And you can configure your mail server to use multiple DNS servers to prevent DNS failure. That’s not hard to do. It’s common for mail servers to query DNS-based blacklist (DNSBL), also known as realtime blacklist (RBL), such as Spamhaus, to reject connections from spammers. You can’t even send emails when your DNS doesn’t work properly. If you worry about DNS failure, that indicates you are not qualified to run your own email server.
But there is another problem with the reject_unknown_reverse_client_hostname IP heck. IIUIC, this would reject any mail server which is on a local LAN behind a firewall but with valid PTR for the Public IP address NAT’s to the server – even if it has full DMARC and DKIM compliance.
Given the shortage of IPv4 public IP addresses, this is a real issue and until IPv6 becomes common, likely to be an increasing one.
The receiving SMTP server doesn’t know the local LAN IP address of the sending SMTP server. It thinks the connection is coming from the router/gateway. That’s how NAT Works.
So, reject_unknown_reverse_client_hostname has no problem with NAT at all.
I recently did a check using an online mail deliverability tool and spf reported the delivery from the lan to my ‘public’ server on the lan (which has a local IP address and not the public address) IIRC. However, I guess it could have been the mail client not the server that was being reported – which would make sense.
I had always assumed that NATing would work the way you suggested, but that report made me wonder.
You mean you have two mail servers in the LAN? Communications in the LAN uses local IP address. You can always add you LAN to Postfix mynetworks parameter, so any IP address in the LAN won’t be affected by reverse IP check.
No, a single mx server. The report even detailed internal passage to and from the virus scanner, or it may have been another component … I can’t recall.
It showed a lan address -> lan address -> 127.0.0.1 -> public ip routing.
Test involved sending an email and the header being examined.
I did once see a spam with the following email flow.
Such mail server has serious internal design flaw, but it’s not related to PTR check (reject_unknown_reverse_client_hostname). PTR check happens in the SMTP dialog phase and it doesn’t scan email headers.
It is a plain iredmail install so any internal flaws are inherent in that packaging.
I was particularly drawn to this series so I could better understand the complexities of a mailserver (as you suggested in your opening paragraphs of Part 1) and this discussion has further aided that education. I intended from the outset to build and maintain a new server from scratch – which I will do once I have the series completed. It is very helpful.
I am enjoying your series vet much. Linuxbabe is my goto for any guides – always dependable. Thank you for your very thorough work.
I now remember that it’s an email server hosted by GoDaddy (secureserver.net) with such email flow.
Actually iRedMail is not like that. The email flow sent from iRedMail servers is:
this was a great help, cut down spam by about 90%
If I add a 2nd and 3rd MX records, do I need to ADD a lets encrypt certificate for each additional domain MAIL2 and MAIL3?
And do I need to configure them in postfix as well?
Adding a second MX record is enough to skip greylisting. Adding a third MX record isn’t necessary.
Simply add mail2.yourdomain.com to your Apache or Nginx virtual host file like
Reload Nginx. Then obtain a multi-domain Let’s Encrypt certificate.
Once the certificate is obtained, simply restart Nginx, Postfix and Dovecot.
Nginx, Postfix and Dovecot will now use the multi-domain certificate.
I think I got banned from ICLOUD.COM because of this “host mx6.mail.icloud.com[17.178.97.79] refused to talk to me: 550 5.7.0 Blocked”
Can you help with?
Read the Postmaster information for icloud mail. Basically you need to send an email to the icloud postmaster team to ask for removal of your IP address from the blacklist.
Thank You so much.
Hello there,
I do have a problem, the “web server – www.MyDomain” is on another IP and over there fail2ban sends the daily email summary to my “mail server” and it goes to “greaylist” for obvious reason. How do I resolve this?
Thank you.
You can edit the /etc/postfix/main.cf file and find the
mynetworks
parameter.Add your web server’s IP address to
mynetworks
. Replace 12.34.56.78 with your real IP address. So your web server won’t be greylisted.Save and close the file. Then restart Postfix.
Hello and thank you for your awesome guide.
I’m following all the steps but I have a problem:
if I insert these lines in
I can’t receive mails:
Check your mail log file (/var/log/mail.log) to find out what’s wrong.
If I comment that lines everything works.
If I uncomment policyd-spf_time_limit = 3600 in /var/log/mail.err I read:
If I uncomment the smtpd_recipient_restrictions lines, I read:
Yesterday I moved /var/log/mail.log to /var/log/mail.log.bak to have a clean log but a new /var/log/mail.log weren’t created by the system…
Your DNS resolver is not working.
Your forgot to run this command:
Restart Postfix after running the above command.
Thank you, “open database /etc/postfix/rbl_override.db: No such file or directory” problem solved!
Ever since setting this up I’ve managed to get spam sent to one of my email addresses, sent FROM my server. The spammer didn’t just spoof my from address but it appears the email actually processed through my server when I examine the raw source of the email. DKIM is in there and looks to be correct. This is the raw source of one of the emails
I have edited my domain name to my-domain.com and edited the Reply-To email. The IP in the received line was actually my VPS IP address. The google.com links were all in the original email believe it or not.
I checked my logs for the id in the “Received” part in the headers as well as the message-id and found this:
Again, my-domain is me. The ip address in “connect from my-domain.com[my-vps-ip]” is actually my VPS IP.
Over the past few days I have received two of these emails, this being the most recent one. I have followed these tutorials to the letter and everything is set up you’ve said except for the greylisting.
This spam was generated on your WordPress site, perhaps through a contact form, or a comment area. Your WordPress site automatically sends the message to your email address.
The Xmailer header right? That’s what I thought initially too. I’ve disabled the “WP Mail SMTP” plugin for now as it seems I no longer need it. We’ll see what happens. Thanks for the reply btw, I appreciate it a great deal =)
Hi,
is there any way to use IMSVA from Trend Micro with postfix + dovecot? I searche dand searched but cannot find how to set it up with IMSVA.
Thank you!
Excellent work again! Everything seems to work as it should.
I had to make a minor change to my pflogsumm crontab entry in order to make it work for me (in order to get my morning report).
At the top of my root crontab is my admin email address.
Followed by the first line of crontab, which shows the order of cron commands
Here is the actual command string that I used to get it to send.
I chose 07:28 so that it would run in time to hit my mailbox right before I come down to my office.
The big change for me (Ubuntu 20.04 server) was to call
to run the pflogsumm program.
Finally, I was able to drop off Mutt, and the mailing instructions because I’ve got my email address at the top of the file.
Hope that helps someone.
Am using CentOS8 (release 8.1) and trying to implement the SMTP AUTH flood attack as you stated. The filter is detecting the attack but firewalld is not banning the IP addresses.
I try to this command:
And this is my main.cf file:
Whats wrong Xiao?
Very simple, you have duplicate parameters in main.cf file.
Dear Xiao,
Thanks for the great tutorial.
PS.: Please check the pflogsumm example, the parameter –problems-first needs to be changed to –problems_first.
Cheers,
Matthieu
From the man page of
pflogsumm
:Apologies for a potentially stupid question…will the postfix configurations above also work for a raspberry pi mail server running postfix?
It works with any Postfix version 3.x or above.
Thx so much! I just finished the configuration I think I need apart from the Greylisting. I can already see a difference in my log files.
Hello I set up everything and get this error :
RCPT from unknown[209.85.167.47]: 450 4.7.1 Client host rejected: cannot find your reverse hostname, [209.85.167.47]; from= to= proto=ESMTP helo=
Can you help me out?
Everything is working if i comment all the restriction.
It seems your DNS resolver isn’t working.
The problem is that everything is working unless I set up the restriction. Here is my complete postfix main.conf https://hatebin.com/lkefjajaio
If you got some time to look quickly arround it will help a lot ^^ Thanks
Before you add the restrictions, Postfix doesn’t need to query DNS. After the restrictions is enabled, Postfix must query DNS.
Please read the tutorial below to set up a local DNS resolver on the mail server.
Run Your Own BIND DNS Resolver on Ubuntu 18.04
Run Your Own BIND DNS Resolver on Ubuntu 20.04
Hello.
Just by accident I found this.
kirelos. com/7-effective-tips-for-blocking-email-spam-with-postfix-smtp-server/
I am currently using your tutorial to setup my server and it is very useful and well documented!
Many thanks for this!
Looks like it’s a scraper site.
Didn’t know the term scraper :).
It is fine tho. When I executed the log utility tool I got these warnings:
smtpd (total: 7)
1 hostname zg-0915a-42.stretchoid.com does not resolve to address…
1 hostname zg-0915b-248.stretchoid.com does not resolve to addres…
1 hostname zg-0915a-61.stretchoid.com does not resolve to address..
1 non-SMTP command from 92.118.161.9.netsystemsresearch.com[92.11…
1 TLS library problem: error:1408F10B:SSL routines:ssl3_get_recor…
These warnings indicates your Postfix is rejecting emails from servers that doesn’t conform to standards.
stretchoid.com is a domain listed in Spamhaus DBL blocklist.
Oh nice!
Many thanks for answer! 🙂
Thank you for great post. Number of spam mail has decreased a lot!
I have a situation where “reject_unknown_client_hostname” is rejecting one specific sender because his PTR doesn’t exist. This is ok. What I find annoying is that sender is retrying every minute for the last 3 days. It is filling log file. Should I do something or just wait?
Thank you!
In SMTP, if an email message is rejected, then the sending SMTP server shouldn’t try again but informs the sender about the delivery failure. If a SMTP server tries again and again after being rejected, it’s clearly a spammer.
Scroll down to the end of this article to see how to stop repeat senders who failed Postfix checks.
Hi, I write here cause I don’t know what else to do,
Recently few days ago we move our WordPress website from siteground to AWS Ec2 Server, we setup everything and our website is running fine on AWS server.
We also install postfix for email sending but when new users signup on our website or if anyone wants to reset the password then all verification mails are going to the spam folder, we already talk to aws premium support but not getting any help from them.
Please can anyone help us, how we resolve this issue, we use PHP mailer service inbuilt in WordPress for sending mails and we already verified our domain on AWS SES.
You can use the tips in this article: How to Stop Your Emails Being Marked as Spam
This is getting to be a bit old now, but great tips!
I do have one question though. reject_unknown_sender_domain blocks mail if the from address is an invalid domain, but is there any way to do the same for the reply-to field? I figure if that’s not a valid domain, I’m happy to drop that email right away. (I have a fair amount of spam coming in these days with valid from domains, but invalid reply-to domains)
Thank you for these wonderful tutorials!
Just FYI you don’t even need to make your own fail2ban “postfix-flood-attack filter”. There already is one for postfix using `filter = postfix[mode=ddos]` in a new block or under the existing `[postfix]` block set `mode=aggressive` if you want to enable all the posfix filters. The fail2ban ddos regex they have is similar to yours but it is not limited to ‘AUTH’:
You can add a new block to your jail.local like:
They also have a filter for SASL which is under `filter = postfix[mode=auth]` which I recommend (also included in aggressive mode). I had a bot hitting my server every minute for a week with a bogus SASL login until I noticed it and enabled this filter.
Regards!
Great tutorial.
Hello! I’m new to your tutorials. As a verrry long-term denizen of the Internet (domain #42 😉 ), may I commend you on your excellent work. Truly awesome.
A question/suggestion/request:
* Am I missing your handling of the relatively recent ARC (Authenticated Received Chain) protocol? I don’t see it mentioned.
* ARC is increasingly important: it takes care of the common case where people auto-forward emails to their phone etc… which of course means some spam will be forwarded. The result: Google will call my email server a spam source. 🙁
* I’ve not yet implemented it myself… but from what I’ve seen, OpenARC.org may be a good way to go.
Blessings,
Pete
Hello Xiao,
Thank you very much for this nice tutorial. Postfix is now the solution for my mailserver. (preivously I used MDaemon and Mailenable). I only have two questions remaining.
How do I let mail that is triggered by smtpd_recipient_restrictions or smtpd_helo_restrictions arrive in my “Junk” folder?
Which files and folders do I need to backup to create a full backup of the complete mailserver?
Thank you for you answer.
hi
we have some domain that are valid from us but dot have ptr record or other reason how we can create whitelist that dont reject their email.
Add those IP addresses in the
mynetworks
parameter in the/etc/postfix/main.cf
file.Then restart Postfix.
how i can block base64 encoded mails ?
spammers send bank phishing mail with base64 encoded body text, it is possible to decode the blocked words in the body_check_map, but it is very elaborate .
thanks
Thanks! Nice work finding and sharing these details! You’re the best!
Hi Guoan, Can I use fail2ban with iptables way when I have ufw enabled?
Yes, you can.
Thank you so much Xiao, and congratulations. Please a ask: Why do you don´t use: smtpd_client_restrictions ??? In my main.cf >>:
smtpd_client_restrictions =
permit_mynetworks,
reject_unknown_client_hostname,
reject_unauth_pipelining,
reject_unknown_reverse_client_hostname,
check_client_access hash:/etc/postfix/checks_allow,
check_client_access regexp:/etc/postfix/ip-access-exceptions
permit
Other question please:
I put permit on all “tags”, exemple:
smtpd_helo_restrictions =
xxxxxxx,
xxxxxx,
xxxxxxx,
permit
smtpd_sender_restrictions =
xxxxxxx,
xxxxxx,
xxxxxxx,
permit
smtpd_client_restrictions =
xxxxxxx,
xxxxxx,
xxxxxxx,
permit
smtpd_recipient_restrictions =
xxxxxxx,
xxxxxx,
xxxxxxx,
permit
Am I wrong?
Thanks again.
Great Tutorial!!!!
A+
Thank you LinuxBabe!!!!!
I’ve read 10s of these tutorials, and yours is by far the best.
Spot on advice! Well done. Especially liked the postfix flood attacks with fail2ban, just stopped someone using that. Got here from:
https://serverfault.com/questions/1030249/fail2ban-wont-ban-postfix-smtps-smtpd
You should write a book!!
Followed your instructions, i have had my own mail server running for two years already. Today, my router blocked all the internet traffic. The reason was that my mail server had sent bulk spam. It started 12:45. i figured it out because i got tens of “Undelivered Mail Returned to Sender”. Inside the headers, i found:
test.tennis24.ee is my domain and [email protected] is my email address. i think that someone is trying to impersonate me and i get all that trash. All the mails are in German having three different subjects:
“From” is set to “Ekaterina ” or “Kravchenko Ekaterina “. The content is always the same:
They ask to register at https://u.to/i_1IHA and looking for the profile 539571027 which i don’t want to do. The question is: how can i stop that seemingly DDOS attack to my mail server? i turned “postfix” off for a while and enjoyed the silence. However, if someone wants to send an email to me, i need to have it on. During writing this comment, ten further failure messages appeared and i have no idea how many were successful.
It seems your mail server has been hacked, and the hacker hijacks your mail server to send spam.
You can use the following method to block random people from accessing your mail server.
How to Secure Email Server Against Hacking with VPN (Debian/Ubuntu)
If your mail server continues to send spam after deploying the VPN protection, then it’s likely the hacker has installed malware on the mail server.
I had to disable tip #4, because I am seeing legitimate services using nonexistent domains in their FROM-headers to send e.g. various kinds of verification-emails and/or some other “no reply”-type ones. The most recent one was Oneplus, and yes, it was actually a legit email. I would rather have those mails delivered to the Junk-folder instead of outright rejected, but I don’t (yet?) know how to set that up.
If I may also make a suggestion: it could be interesting, if you made an article about one or another web-based monitoring-system, so it’s easier to check what is going on on one’s mail-server. I was going to take a look at Munin, since I’ve heard it’s pretty nice, but there are probably a number of other options out there as well.
If those legit email senders use non-existent From: email addresses, then they are doing it wrong.
I just published an article on how to set up Lightmeter for mail server monitoring.
Linux Mail Server Monitoring with Lightmeter (Debian, Ubuntu)
Microsoft Office 362(ish) does not have reverse DNS for its outgoing emails
Reverse DNS is controlled by hosting companies or ISPs, not by a mailbox provider.
Please note that at the beginning of this article, with some examples, the comma ( , ) is missing.
E.g.
smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
…..
should be
smtpd_sender_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
…..
from the article
“You might be wondering why there is no comma in the first two configuration snippets. Well, you can separate values in Postfix configuration file with space, carriage return or comma. If you add comma to one parameter (smptd_recipient_restrictions as in the above screenshot), then make sure all remaining values are separated with comma.”
just got started and immediately started getting hit by spammers. now i feel things are pretty well tied up. thank you so much!
Nice article. Don’t forget to add port 465 (smtps) to your jail configuration.
action = iptables-multiport[name=postfix, port=”http,https,smtp,smtps,submission,pop3,pop3s,imap,imaps,sieve”, protocol=tcp]
I usually never write comments, but those tutorials about postfix + dovecot are really, really helpful.
Thanks a lot
I noticed your article and have implemented all of your recommendations. However, I am still receiving a lot of attempted connections originating from *.dynamic.163data.com.cn . (About 50-100 attempts a day from unique ip addresses.)
Is there a way I can blacklist anything advertising itself coming from *.dynamic.163data.com.cn so as not to fill up my server logs? Does Postscreen do this job?
I want to thank you for the contributions, it was very helpful.
Hi, thanks for your great tutorials!
I get errors in fail2ban log, running on Debian and following your exact configuration:
iptables -w -I INPUT -p tcp -m multiport –dports ssh -j f2b-sshd
2023-04-27 18:35:26,194 fail2ban.utils [2354500]: ERROR 7f9c4263a0 — stderr: ‘iptables: Chain already exists.’
2023-04-27 18:35:26,194 fail2ban.utils [2354500]: ERROR 7f9c4263a0 — stderr: “iptables v1.8.7 (nf_tables): Couldn’t load match `multiport’:No such file or directory”
2023-04-27 18:35:26,194 fail2ban.utils [2354500]: ERROR 7f9c4263a0 — stderr: ”
2023-04-27 18:35:26,194 fail2ban.utils [2354500]: ERROR 7f9c4263a0 — stderr: “Try `iptables -h’ or ‘iptables –help’ for more information.”
2023-04-27 18:35:26,194 fail2ban.utils [2354500]: ERROR 7f9c4263a0 — returned 2
2023-04-27 18:35:26,194 fail2ban.actions [2354500]: ERROR Failed to execute ban jail ‘sshd’ action ‘iptables-multiport’ info ‘ActionInfo({‘ip’: ‘65.73.231.122’, ‘family’: ‘inet4’, ‘fid’: <function Actions.ActionInfo. at 0x7f9c9f5790>, ‘raw-ticket’: <function Actions.ActionInfo. at 0x7f9c9f5e50>})’: Error starting action Jail(‘sshd’)/iptables-multiport: ‘Script error’
2023-04-27 18:35:28,197 fail2ban.actions [2354500]: NOTICE [sshd] Unban 65.73.231.122
2023-04-27 18:35:30,298 fail2ban.filter [2354500]: INFO [sshd] Found 121.26.142.238 – 2023-04-27 18:35:29
2023-04-27 18:35:31,733 fail2ban.filter [2354500]: INFO [postfix-flood-attack] Found 46.148.40.13 – 2023-04-27 18:35:31
Very useful – thank you!!
Hi Xiao Guoan, your tutorial is the best of the best. I’m glad it’s there and I’m following your threads with disdain. if only I could make a slight addition “really need to disable in postfx EXPN, VRFY, and RCPT commands:”
Open the Postfix configuration file (typically located at
)using a text editor.
Add or modify the following lines to disable the
commands:
Save the configuration file and restart the Postfix service to apply the changes:
I’ve moved servers and now also using your tips to block the spammers, I used fail2ban already but now included greylist and blacklists. Thanks linuxbabe!