Below I want to show how to configure the built-in options for Postfix to prevent unsolicited commercial emails (UCE) or spam will be sent to your inbox and instead will get rejected.


Introduction

First we will see what Postfix out of the box supports to block and reject UCE and spam.

Postfix can block such messages at different stages or in other words in a specific order Postfix will check and reject them.

Postfix uses for the different stages SMTP access restrictions lists you can configure to block and reject connection attempts and email messages.


Postfix SMTP access restrictions lists will be evaluated in a proper order regarding the SMTP Mail flow.

TCP 3-way handshake –> HELO/EHLO –> MAIL FROM: –> RCPT TO: –> DATA –> QUIT

  • smtpd_client_restrictions (TCP3-way handshake)
  • smtpd_helo_restrictions (HELO/EHLO)
  • smtpd_sender_restrictions (MAIL FROM:)
  • smtpd_recipient_restrictions (RCPT TO)


At each of theses stages (SMTP access restrictions lists), Postfix can either PERMIT or REJECT the SMTP Connection or email message.

By default Postfix will set the following parameter to yes.
smtpd_delay_reject = Yes

If not set explicitly to No, Postfix will nevertheless first evaluate all SMTP access restrictions lists before in case of an matching REJECT it will close the connection or reject the email message. More about below.




Configuration

First Stage -> smtpd_client_restrictions (TCP3-way handshake)

So the first stage to reject and block messages Postfix will use are the smtpd_client_restrictions list. They will control what systems will be able to send email messages to Postfix based on their IP address and hostname. You can also whitelist or blacklist here IPs and hostnames by using the following parameters below.

check_client_access cidr:/etc/postfix/client_access

The client_access file itself will include lines like the following for allowing or blocking email messages coming from specific IPs or hostnames.
172.16.0.0/16 OK
10.10.10.10 OK
8.8.4.4 OK
smtp-mail.outlook.com OK
microsoft.com OK

8.8.8.8 REJECT
10.20.20.30 REJECT
domain.com REJECT
mail.domain.com REJECT

cidr_table format
https://www.postfix.org/cidr_table.5.html

Postfix lookup table types
https://www.postfix.org/DATABASE_README.html#types



There is a further parameter regarding postpone the evaluation of SMTP access restrictions lists as already mentioned above.

smtpd_delay_reject

smtpd_delay_reject = yes allows the smtp conversation to continue until the point of actually receiving the message before it is rejected, and is useful because it allows full sender and recipient information to be logged.
Source: https://wiki.centos.org/HowTos/postfix_restrictions

Wait until the RCPT TO command before evaluating $smtpd_client_restrictions, $smtpd_helo_restrictions and $smtpd_sender_restrictions, or wait until the ETRN command before evaluating $smtpd_client_restrictions and $smtpd_helo_restrictions.
This feature is turned on by default because some clients apparently mis-behave when the Postfix SMTP server rejects commands before RCPT TO.
https://www.postfix.org/postconf.5.html#smtpd_delay_reject

Early Postfix versions evaluated SMTP access restrictions lists as early as possible. The client restriction list was evaluated before Postfix sent the “220 $myhostname…” greeting banner to the SMTP client, the helo restriction list was evaluated before Postfix replied to the HELO (EHLO) command, the sender restriction list was evaluated before Postfix replied to the MAIL FROM command, and so on. This approach turned out to be difficult to use.
Source: http://postfix.cs.utah.edu/SMTPD_ACCESS_README.html#timing



So by setting smtpd_delay_reject to yes, Postfix either way won’t close or reject the smtp connection before receiving the RCPT TO command, even if one of the first restrictions configured to reject at violating them.


The above client_access txt file for whitelisting and blacklisting IPs and hostnames, you will use to create an indexed file in dbm or db format for fast searching by the email system. You can create the dbm or db file by using the following command.

$ postmap /etc/postfix/client_access

You will always execute that command after changing the client_access file to rebuild the indexed dbm or db file.
Source: http://www.postfix.org/access.5.html



Second Stage -> smtpd_helo_restrictions (HELO/EHLO)

The second stage is the HELO or EHLO command from a SMTP Server who wants to connect to our Postfix to send the email message. With these commands it is identifying itself and tries to establish a connection with our Postfix SMTP server.

At this stage there is also no information about the actual email message it wants to send to Postfix.

Here you can use the following SMTP access restrictions list from Postfix to block and reject connections from SMTP servers they don’t advertise the HELO or EHLO command.

First to enable the restriction list you need to set the following to Yes.

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

Requiring that the client sends the HELO or EHLO command before sending the MAIL FROM or ETRN command. This may cause problems with home-grown applications that send mail. For this reason, the requirement is disabled by default (“smtpd_helo_required = no”).
Source: https://www.postfix.org/SMTPD_ACCESS_README.html




Third Stage -> smtpd_sender_restrictions (MAIL FROM:)

The third stage are the smtpd_sender_restrictions list. They will define what sender addresses will be able to send mails through your Postfix server based on their envelope-from addresses (“Mail From” address:).

Note!
This is not the RCPT TO address from the email header.


More about the differences between the Mail From and From address you can read in my following post under the Sender Policy Framework (SPF) section.




smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unknown_reverse_client_hostname
reject_unknown_client_hostname
reject_unknown_sender_domain

# reject_unknown_reverse_client_hostname –> Will reject emails where the IP from the SMTP Client (Sending server) couldn’t be resolved into a FQDN because of a missing DNS PTR record. A PTR record maps an IP address to a hostname resp. FQDN.


You can also whitelist or blacklist here sender email addresses by using the sender_access txt file like before under client access for IPs and hostnames. This time we use the hash table format instead of the cidr table fomat as previously for the client access file.

Use the command postconf -m to find out what lookup table types your Postfix system supports.

check_sender_access hash:/etc/postfix/sender_access

The sender_access file itself will include lines like the following for allowing or blocking email messages coming from specific email sender addresses or domains.
user@example.com REJECT
example.com REJECT
example2.com OK

Postfix lookup table types
https://www.postfix.org/DATABASE_README.html#types




Last Stage -> smtpd_recipient_restrictions (RCPT TO)

Now for the last stage the smtpd_recipient_restrictions list will be evaluated by Postfix. This restriction will check email messages based on the RCPT TO address.

smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_pipelining
reject_non_fqdn_recipient
reject_unknown_recipient_domain
reject_unauth_destination
reject_rbl_client bl.spamcop.net
reject_rbl_client cbl.abuseat.org
reject_rbl_client ix.dnsbl.manitu.net
reject_rbl_client sbl.spamhaus.org
reject_rbl_client dnsbl-1.uceprotect.net
reject_rbl_client dnsbl-2.uceprotect.net
reject_rbl_client dnsbl-3.uceprotect.net
reject_rbl_client zen.spamhaus.org
reject_rbl_client b.barracudacentral.org
reject_rbl_client bb.barracudacentral.org
permit


Regarding using the smtpd_recipient_restrictions list and what to list in it, please also read the follwing article.

Dangerous use of smtpd_recipient_restrictions
http://postfix.cs.utah.edu/SMTPD_ACCESS_README.html#danger


The last permit parameter above under the smtpd_recipient_restrictions list isn’t really needed to put in there.

The end of each list is equivalent to a PERMIT result.
By placing a PERMIT restriction before a REJECT restriction you can make exceptions for specific clients or users. This is called allowlisting.
Source: https://www.postfix.org/SMTPD_ACCESS_README.html


Further checks for Header and Body of the email messages can also be done by using the following parameter. The following checks uses the regexp table type.

Use the command postconf -m to find out what lookup table types your Postfix system supports.

header_checks = regexp:/etc/postfix/header_checks
Source: https://www.postfix.org/header_checks.5.html

mime_header_checks = regexp:/etc/postfix/mime_header_checks
Source: https://www.postfix.org/postconf.5.html#mime_header_checks

body_checks = regexp:/etc/postfix/body_checks
Source: https://manpages.debian.org/testing/postfix/body_checks.5.en.html#body_checks


So far we just uses the built-in options from Postfix to prevent unsolicited messages or spam. You can also use as shown below, the open-source mail filter SpamAssassin therefore or in addition Greylisting which is a method to reject spammers.





Install and Configure SpamAsssassin on Ubuntu

Apache SpamAssassin is a computer program used for e-mail spam filtering. It uses a variety of spam-detection techniques, including DNS and fuzzy checksum techniques, Bayesian filtering, external programs, blacklists and online databases. It is released under the Apache License 2.0 and is a part of the Apache Foundation since 2004.

Source: https://en.wikipedia.org/wiki/Apache_SpamAssassin


To install and enable SpamAssassin use the following commands.

$ sudo apt install spamassassin spamc

Enable auto-start at boot
$ sudo systemctl enable spamassassin

$ sudo systemctl start spamassassin





Install and Configure Greylisting for Postfix on Ubuntu

Greylisting is a method of defending e-mail users against spam. A mail transfer agent (MTA) using greylisting will temporarily reject any email from a sender it does not recognize. If the mail is legitimate, the originating server will try again after a delay, and if sufficient time has elapsed, the email will be accepted.

A server employing greylisting temporarily rejects email from unknown or suspicious sources by sending 4xx reply codes (“please call back later”), as defined in the Simple Mail Transfer Protocol (SMTP). Fully capable SMTP implementations are expected to maintain queues for retrying message transmissions in such cases, and so while legitimate mail may be delayed, it should still get through.

Greylisting is effective against mass email tools used by spammers that do not queue and reattempt mail delivery as is normal for a regular mail transport agent.

Source: https://en.wikipedia.org/wiki/Greylisting_(email)


To install and enable Greylisting for Postfix on Ubuntu use the following commands.

$ sudo apt install postgrey

Enable auto-start at boot
$ sudo systemctl enable postgrey

$ sudo systemctl start postgrey


Next we need to edit the main config file /etc/postfix/main.cf in order postfix will use the greylisting service which is listening by default on 127.0.0.1:10023.

Add the following line under smtpd_recipient_restriction

check_policy_service inet:127.0.0.1:10023

Restart postfix

$ sudo systemctl restart postfix





Links

Postfix Documentation
https://www.postfix.org/documentation.html

Blocking SPAM (UCE) using Postfix

https://www.akadia.com/services/postfix_uce.html

7 Effective Tips for Blocking Email Spam with Postfix SMTP Server
https://www.linuxbabe.com/mail-server/block-email-spam-postfix

Block Email Spam with Postfix and SpamAssassin Content Filter
https://www.linuxbabe.com/mail-server/block-email-spam-check-header-body-with-postfix-spamassassin

Greylisting
https://en.wikipedia.org/wiki/Greylisting_(email)