Postfix – How to Reject Emails Failing Reverse Hostname Resolution

postfixspam

My Postfix server is receiving spam from an ever changing set of domain names but with a consistent pattern in the log file starting with line warning: hostname X does not resolve to address Y. No legit (ham) email has this pattern so I would like to block emails associated with this message.

Is there a way to block these emails entirely in the Postfix configuration, such as in the main.cf file?

Here is a section of the log file showing the pattern present when the spam arrives:

May 10 21:47:46 localhost postfix/smtpd[313324]: warning: hostname trojan.kringeas.co.uk does not resolve to address 104.129.30.93: Name or service not known
May 10 21:47:46 localhost postfix/smtpd[313324]: connect from unknown[104.129.30.93]
May 10 21:47:46 localhost postfix/smtpd[313324]: 2AF1D101825: client=unknown[104.129.30.93]
May 10 21:47:46 localhost postfix/cleanup[313331]: 2AF1D101825: message-id=<dO7GXAfoNocg1hEkeyqMfulg7RZ0aamifKqrB8JpUH8.ofI9TFu7lSCnlxwicxT5GA@meansfolk.sa.com>
May 10 21:47:46 localhost postfix/qmgr[294981]: 2AF1D101825: from=<[email protected]>, size=4241, nrcpt=1 (queue active)
May 10 21:47:46 localhost postfix/pipe[313333]: 2AF1D101825: to=<[email protected]>, orig_to=<[email protected]>, relay=dovecot, delay=0.11, delays=0.08/0.01/0/0.02, dsn=2     .0.0, status=sent (delivered via dovecot service)
May 10 21:47:46 localhost postfix/qmgr[294981]: 2AF1D101825: removed
May 10 21:47:46 localhost postfix/smtpd[313324]: disconnect from unknown[104.129.30.93] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5

Here is my main.cf file:
Note that it includes: smtpd_client_restrictions = reject_unknown_reverse_client_hostname which I tried after reading this post.

queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix/sbin
data_directory = /var/lib/postfix
mail_owner = postfix
inet_protocols = all
mydestination = localhost, localhost.localdomain
unknown_local_recipient_reject_code = 550
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
debug_peer_level = 2
debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd $daemon_directory/$process_name $process_id & sleep 5

sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.10.1/samples
readme_directory = /usr/share/doc/postfix-2.10.1/README_FILES


myhostname = xxxx.net
mynetworks = 127.0.0.0/8
message_size_limit = 30720000
virtual_alias_domains =
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf, hash:/etc/postfix/virtual
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf
virtual_mailbox_base = /home/vmail
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
smtpd_client_restrictions = reject_unknown_reverse_client_hostname
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_authenticated_header = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_use_tls = yes
smtpd_tls_cert_file = /etc/pki/dovecot/certs/dovecot.pem
smtpd_tls_key_file = /etc/pki/dovecot/private/dovecot.pem
virtual_create_maildirsize = yes
virtual_maildir_extended = yes
proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
inet_interfaces = all
smtp_tls_security_level = may
disable_vrfy_command = yes
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept

Best Answer

Just replace

smtpd_client_restrictions = reject_unknown_reverse_client_hostname

with

smtpd_client_restrictions = reject_unknown_client_hostname .

From the Postfix manual:

reject_unknown_client_hostname (with Postfix < 2.3: reject_unknown_client)
    Reject the request when 
      1) the client IP address->name mapping fails, or 
      2) the name->address mapping fails, or
      3) the name->address mapping does not match the client IP address.
    This is a stronger restriction than the reject_unknown_reverse_client_hostname 
    feature, which triggers only under condition 1) above.
    The unknown_client_reject_code parameter specifies the response code for
    rejected requests (default: 450). The reply is always 450 in case the
    address->name or name->address lookup failed due to a temporary problem. 

However, this your belief is wrong:

No legit (ham) email has this pattern so I would like to block emails associated with this message.

My customers complaint from time to time, and it happens that sometimes reverse hostname does not comply with the HELO address, or it resolves to other address or doesn't resolve at all, and that's perfectly solicited mail. Basically, current RFCs only mandate the existence of the PTR record of the HELO hostname, while don't say anything about its value or existence of the A record under that name or its value. Technically legitimate server can omit everything else and still comply to RFCs, while you are blocking it with this configuration. To remedy this, I put all those checks into smtpd_recipient_restrictions, and added check_sender_access hash://... immediately before it, so I can selectively exclude some mail from this check by sender domain name or full sender email address:

smtpd_client_restrictions = [default]
smtpd_recipient_restrictions = 
...
    check_sender_access hash:/etc/postfix/spam_exceptions,
    reject_unknown_client_hostname,
...

You can't use check_sender_access in the smtpd_client_restrictions because you only obtain sender envelope address to check against during MAIL From: phase.

This spam_exceptions file has the simple structure:

affected.domain OK
...

I just add domains into this file when I resolve complaints. And I have a quite big collection already!