Every now and then, a question like this pops up on some email server management forum:

  I'd like to be able to reject connections from remote IP addresses if they're from certain countries.

The usual reason is either that

the sender only receives spam from those countries and is convinced that this will always be the case, or that, since the sender doesn’t need or want to exchange email with anybody in those countries, why bother at all with filtering messages from there?

Personally, I feel that both reasons are very weak, to say the least, and could turn against (the users of ) the system administrator that implements them. I’ve explained why in another post. However, this is a relatively frequent question and if an email system administrator really wants to do it, at the very least, he or she ought to do it right. Besides, even if I don’t do it myself, I do want to understand how all this works, both for the fun of it and because the same tricks may be used to flag or delay, instead of plainly rejecting, email that “comes from certain countries”. For all these reasons, I’ve reformatted here some tips appeared in a recent thread on the postfix list. Please remember that (see above and bottom) as far as this page is concerned, I’m just an editor! I have just rearranged in a more readable form an email discussion! If there are errors or other ways to add this function to a web server, just let me know in the comments and I’ll update this page as soon as possible, because I do want it to be as accurate and complete as possible.

As far as I understand, there several ways to do geographically based email rejection in PostFix, but with other servers it should be possible to do similar things.

IP-based black lists

If you want this mere as an anti spam measure, I advise to use IP-based black lists. They are more powerful and are adapted for spam hosts around the globe as they appear. However, the original poster reported that “I’m already using three RBL’s (b.barracudacentral.org, zen.spamhaus.org and dnsbl.sorbs.net) yet I’m still seeing a fair amount of spam coming in from Russian and Romanian IP ranges that isn’t blocked.

Per-country access map, policy plugin, milter, or deep content filter

How to do this with PostFix (thanks Wietse!) is explained in these pages (if you know how to do the same with other servers, please let me know)

Check URI/domain based DNSBLs

You may also want to try this script: it scans mail headers for domains and checks them against 3 URI/domain based DNSBLs. hese are user configurable, so you can add more URI/domain DNSBLs if you wish. Do NOT use IP based DNSBLs with this, only URI/domain DNSBLs.

“I’d use both of the above tools regardless of the Russian/Romanian spam problem. And if you absolutely will never receive mail from these countries, or very infrequently, using ipdeny.com as Wietse mentioned is a sure fire way to block the entire country. I use it myself against Russia, Romania, China, Korea, Malaysia, and a few others. If you do this it’s a good idea to implement the dnswl.org whitelist.”

Alternatively, you can also use DNSBL maps like http://countries.nerd.dk/, keeping in mind, as their author himself says, that “countries.nerd.dk is NOT a list of spammers, it is an IP-to-country DNS mapping service”.

Postfix PCRE bot spam killer

give this a go. It is reported as simple to implement. It targets dynamic IP hosts and some others that simply shouldn’t be sending SMTP mail directly. It stops quite a bit that Zen (CBL+PBL), SORBS DUL, and other DNSBLs miss. It’s a simple PCRE table consisting of 1600+ regular expressions that matche rDNS strings of undesirable hosts. Myself and a few others on this list use it with good results. “It’s not magic, but just another good tool to have in your AS arsenal”.

DNSWL

Postfix > 2.8 can query DNSWL directly. For earlier versions you’ll need to get permission to rsync the data file. You’ll need to run it through a script to add “permit_auth_destination” to each IP line transforming it into a CIDR table.

SQL access maps

you can convert the GeoIP map into an sql access map (see also the GeoIP how to). With that you can adjust your sql queries to implement whatever you want to do. You can convert the GeoIP map to a DNSBL and use rbldnsd

Other solutions

Use Milter-Greylist based geoip detection, this Python GeoIP policy server, these Header checks or the list in this (not so recent) article on Asian spam.

Again, any pointer / suggestion on how to improve this page is welcome.