Based on Debian 10 "Buster" environment.

SMTPd Restrictions

If your server is open to the internet, you will soon find so many connections coming in before announcing your server is open. Actually more than 90% (95%? probably) of the connection is considered malicious, infected, anyway, useless.

To block these kinds of connections to prevent wasting the server resources, Postfix has built-in restriction configurations.

smtpd_*_restrictions

There are several restrictions groups - Postfix SMTP relay and access control
Here I go a bit more strict than the explanation above.

The configuration below means in short, 

  1. Permit: My networks
  2. Permit: Authenticated users
  3. Reject: Invalid domain names with helo command
  4. Reject: Invalid sender address
  5. Reject: Invalid RCPT TO mail address
  6. Permit anything else
# Restrictions
message_size_limit = 20480000
disable_vrfy_command = yes

unknown_hostname_reject_code = 554
unknown_address_reject_code = 554
unverified_sender_reject_code = 554
unverified_recipient_reject_code = 554

smtpd_helo_required = yes

mua_client_restrictions =
    permit_mynetworks
    permit_sasl_authenticated

mua_helo_restrictions =
    reject_invalid_helo_hostname
    reject_non_fqdn_helo_hostname

mua_sender_restrictions =
    reject_non_fqdn_sender
    reject_unknown_sender_domain

mua_recipient_restrictions =
    reject_non_fqdn_recipient
    reject_unknown_recipient_domain

smtpd_client_restrictions = $mua_client_restrictions
smtpd_helo_restrictions = $mua_helo_restrictions
smtpd_sender_restrictions = $mua_sender_restrictions
smtpd_recipient_restrictions = $mua_recipient_restrictions
  • message_size_limit: 20MB should be enough (default 10MB)
  • disable_vrfy_command: Prevent this command to be used for user scanning.
  • *_reject_code: 450 (try later) is the default. Don't want them to come back later...
  • smtpd_helo_required: Yes to make most use of helo_restrictions.

Reload to apply new restrictions.

# systemctl reload postfix

Watching the mail log, it seems most connections are kicked by the helo_restrictions with non-FQDN hostname. Even the restrictions above are not enough, there are more powerful restrictions such as reject_unknown_helo_hostname or reject_unverified_sender. The reason why I don't use them is the side effects that may kick out the valid servers.

After narrowing most spams in the entrance, the Bayesian filter should be enough to handle them.