Anti-spam Freakness v0.1 (Sep 2017)

this presentation for the SNE Master Students at Innopolis University

Before we start

Everything clear about SMTP chains? What about smarthosts? (+ auth vs network?)

DNS and SMTP are so critical they are often outsourced

MDA/MUA vs spambox vs smtp session

There are several ways to handle SPAM.

Those methods can be cumulated but one gets great results with filtering during the SMTP session already.

Message’s source

Looking at a message’s source:

Layout of a standart SMTP session

Connect with telnet,

telnet 2525

Who you are (helo YOURSELF),


Who’s email account are you impersonating (this is for the Return-Path)?

mail from:<>

Who are you wiling to send a message to?

rcpt to:root
rcpt to:<>

What are you willing to send (including the message headers)?

From: Me Me Me <>
To: Target <>
Subject: you have been spammed

spam content

Introduction about Acceptance Testing

==> Do not forget to make the customer sign it (even if some parts failed)!

(quick reminder of the major SMTP daemons available out there)


One could consider distributing the postfix instances on different bare-metal or VMs or Docker containers against a shared storage. One could consider firewalling, load-balancing, CARP and DNS round-robin but this is out of topic. We are not reviewing infrastructure architecture for heavy production but only anti-spam specific tuning.

One could also consider the linkage between the SMTP services and the Calendar Webmail Chat etc. To undoom your customer or the company you will be working from from MS hosted mail facilities, the Open Source community does not have ideal answers yet. Microsoft is strong on the server market with their Exchange and Outlook products. Actually it is the only thing they got left. But I believe that we are going to take over this remaining peace too in the future (what else do they got anyway?).

By the way on the Desktop OS market, we (the Open Source community) are also becoming stronger with Unity, Cinnamon, MATE and Ubuntu Budgie.

Yes, given the labs you are working on, you are part of the community now.

Preparation – Initial server setup

myorigin = $mydomain
#(default to FQDN minus the first component)
mydomain =
myhostname =
mydestination = $mydomain
mynetworks = [::ffff:]/104 [::1]/128

smtpd_banner = $myhostname ESMTP
biff = no
append_dot_mydomain = no
delay_warning_time = 4h
readme_directory = no
compatibility_level = 2
alias_maps = hash:/etc/aliases

Forcing alias_maps because the default is alias_maps = hash:/etc/aliases, nis:mail.aliases.

Enabling delay_warning_time for user’s convenience.

Changing port 25 to 2525 to workaround the blocked outgoing SMTP sessions from Innopolis networks as well as from Google Cloud (so we can also do some tests from those locations),

vi /etc/postfix/

#smtp      inet  n       -       y       -       -       smtpd
2525      inet  n       -       y       -       -       smtpd

Create a dummy mail user called user,

groupadd mailuser
useradd -g mailuser -m -s /sbin/nologin user

Preparation – Initial client(s) setup

Check that you can reach out the target SMTPD from different locations/clients,


and that ports smtp and submission are not filtered,

nmap -p 25,587

Check that your own presence on the public network has a PTR and resolves,

curl -s | egrep '^your ip|resolves'

Setup Expect and Autoexpect to automate telnet test sessions for this PoC acceptance testing,

apt install expect expect-dev

Re-do the sample SMTP session with Expect,


Acceptance Testing with default relay restrictions (negative control)




Hint on # RELAY restrictions

Most important importantly (here used config = default),

#smtpd_relay_restrictions (default: permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination)
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

Acceptance Testing # NETWORK restrictions (smtpd_client_restrictions)

Beware of the Postfix version. The syntax is continuously changing esp. between versions 2.x and 3.x. Do NOT copy/paste configuration snippets from the web. Read The Freacking Manual man 5 postconf and Postfix Documentation. How to find relevant manual pages by the way?

The tested configurations are enabled then disabled so the next one can actually be tested (it also helps to get back to the scientific negative control status anyway).


tail -F /var/log/mail*

and for production progressively seperate the output, at least look at both logs separately,

tail -F /var/log/mail.log
tail -F /var/log/mail.err

Note: On Redhat systems there is /var/log/maillog.

enabling in,



from an NXDOMAIN client

450 4.7.1 Client host rejected: cannot find your reverse hostname, []
450     Requested mail action not taken: mailbox unavailable

replacing with,



unknown_client_reject_code   = 554


from an NXDOMAIN client

554 5.7.25 Client host rejected: cannot find your hostname, []
554     Transaction failed

Note: the client IP has changed in the meamwhile. This has nothing to do with the Schmilblick.


example on production system


# this is too restrictive
#   reject_rhsbl_sender,

# apews is blocking (
#   reject_rbl_client,

# not found
#   reject_rbl_client,


example on prod server

Sep 14 10:05:37 postfixprod postfix/smtpd[18751]: NOQUEUE: reject: RCPT from[]:50029: 554 5.7.1 Service unavailable; Client host [] blocked using; Blocked - see; from=<> to=<> proto=ESMTP helo=<>

Sep 10 01:47:37 postfixprod postfix/smtpd[9923]: NOQUEUE: reject: RCPT from[]:31497: 554 5.7.1 Service unavailable; Client host [] blocked using; Blocked - see; from=<> to=<> proto=ESMTP helo=<>

Sep 13 14:21:18 postfixprod postfix/smtpd[17080]: NOQUEUE: reject: RCPT from[]:37099: 554 5.7.1 Service unavailable; Client host [] blocked using; Client host blocked using Barracuda Reputation, see; from=<> to=<> proto=ESMTP helo=<>

Aug 11 05:49:19 postfixprod postfix/smtpd[19570]: NOQUEUE: reject: RCPT from[]:58944: 554 5.7.1 Service unavailable; Client host [] blocked using;; from=<> to=<> proto=ESMTP helo=<>

Note: IAP’s IP address ranges are blocked! What does this mean for SMTP servers at home?



telnet bulk,

from any client

(echo helo crap; echo mail from:whatever; echo rcpt | telnet 2525

returns (instead of Relay Access Denied),

Client host rejected: Improper use of SMTP command pipelining

enabling SPF policy,

on aws

less /etc/nsd/

on hosted NS with WEB GUI

and testing,

from a system that can do outgoing tcp/25,

telnet 25

(could not reproduce -- TXT record broken?)

usually returns,

on production system

Sep 14 15:28:38 postfixprod postfix/smtpd[19305]: NOQUEUE: reject: RCPT from unknown[]:44712: 550 5.7.1 <unknown[]:44712>: Client host rejected: Message rejected due to: SPF fail - not authorized. Please see;;ip=;; from=<> to=<> proto=ESMTP helo=<>

enabling client_access,

on production system

vi /etc/postfix/client_access
postmap /etc/postfix/client_access
ls -lhF /etc/postfix/client_access


from a system that can do outgoing tcp/25,

telnet 25


554 5.7.1 <[]:47566>: Client host rejected: is identified as a spam domain

Acceptance Testing # HELO/EHLO restrictions


smtpd_helo_restrictions = permit_mynetworks,

#reject_unknown_helo_hostname --> unknown_hostname_reject_code
unknown_hostname_reject_code = 554

gives among others,

554 5.7.1 <>: Helo command rejected: Host not found

Acceptance Testing # MAIL FROM restrictions

#postmap /etc/postfix/sender_access
smtpd_sender_restrictions = permit_mynetworks,
    check_sender_access hash:/etc/postfix/sender_access,

#        warn_if_reject,
#too restrictive, this prevents unreal addresses to send
#you messages.  try to book a hotel or a flight with that
#and you will feel the pain,
#       reject_unverified_sender
#unverified_sender_reject_code = 550
#unverified_sender_reject_reason = Address verification failed
#address_verify_map = proxy:btree:$data_directory/verify_cache
#address_verify_cache_cleanup_interval = 72h
# Postfix 2.6 and later.
# unverified_sender_defer_code = 250
#proxy_write_maps = $smtp_sasl_auth_cache_name $lmtp_sasl_auth_cache_name $address_verify_map $postscreen_cache_map

Acceptance Testing # RCPT TO restrictions

smtpd_recipient_restrictions = permit_mynetworks,

#reject_unknown_sender_domain --> unknown_address_reject_code
#reject_unknown_recipient_domain --> unknown_address_reject_code
unknown_address_reject_code  = 554

# DATA restrictions
# Block clients that speak too early.
smtpd_data_restrictions = reject_unauth_pipelining


Further readings

Nethence | Pub | Lab | Pbraun | SNE Russia | xhtml