Using Postfix to block mail based on From/sender and To/recipient

Back in late November (now 56 days ago), I started getting huge levels of very directed spam. When I tweeted about it, I was getting perhaps 100-250 a day. I thought it would soon stop and they would target someone else.

They would get into my spam folder yes, but it still takes time to go through that folder.

Eventually it did stop.

For a few days, then it came back at about 200-400 messages a day.

I asked on #postfix on FreeNode IRC about this.

I was directed to Postfix Per-Client/User/etc. Access Control

It took me a bit of thinking and reading, but eventually I came up with the following entries for /usr/local/etc/postfix/main.cf. My approach mimics that described in the Protecting internal email distribution lists section of the Postfix URL above.

smtpd_recipient_restrictions = 
        permit_mynetworks
        check_recipient_access hash:/usr/local/etc/postfix/protected_destinations

smtpd_restriction_classes = good_senders_only
good_senders_only = check_sender_access hash:/usr/local/etc/postfix/restricted_senders, permit

Lines 1-3 define the “Optional restrictions that the Postfix SMTP server applies in the context of a client RCPT TO command” (see smtpd_recipient_restrictions).

The check_recipient_access directive will apply to the recipient of this email (i.e. TO), and specifies the protected_destinations hash and will “Search the specified access(5) database for the resolved RCPT TO address, domain, parent domains, or localpart@, and execute the corresponding action“. That hash (see below) defines foo@bar.org as a member of the good_senders_only class.

This is where smtpd_restriction_classes comes in, as it defines actions for that class.

The beauty of the good_senders_only class definition is the check_sender_access using the restricted_senders hash. In that hash, it will search “for the MAIL FROM address, domain, parent domains, or localpart@, and execute the corresponding action“. In my case, it will reject the email.

In short, for a specific class of recipient (foo@bar.org), check the sender and take action based on that.

The above configuration refers to two files:

$ cat /usr/local/etc/postfix/protected_destinations
# not everyone can send to these destinations
# we restrict some of them

foo@bar.org     good_senders_only

The above lists the particular receiving address which I wanted to filter.

This file defines the senders which I want to reject:

$ cat /usr/local/etc/postfix/restricted_senders
# We do not want mail from these folks, generally

qq.com         REJECT  521
163.com        REJECT  521

Once I created those files, I ran this command to create the associate hash files:

cd /usr/local/etc/postfix
postmap protected_destinations restricted_senders

This will reject mail from those domains, sent to the address in question, with a status of 521.

Why 521. It sounds good:

Note: The “521” response should be used only with botnets
and other malware where interoperability is of no con-
cern. The “send 521 and disconnect” behavior is NOT
defined in the SMTP standard

Testing

Here is the simple testing I did with the above in place.

$ telnet mx.example.org 25
Trying 203.0.113.82...
Connected to mx.example.org.
Escape character is '^]'.
220 mx.example.org ESMTP Postfix
helo me.testing.example.com
250 mx.example.org
mail from: 318787866@qq.com
250 2.1.0 Ok
rcpt to: foo@bar.org
554 5.7.1 <318787866@qq.com>: Sender address rejected: 521

Good. Success.

Over the next day or so I monitored the log with sudo tail -F /var/log/maillog | grep NOQUEUE looking for everything which got rejected. Eventually I started running this check every day:

$ sudo grep NOQUEUE /var/log/maillog | egrep -v '163.com|qq.com'
$

This nil result tells me that all NOQUEUE involved either 163.com or qq.com. Good.

Die spammers die.

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

Leave a Comment

Scroll to Top