May 292011
 

If you intend to be able to reject connections from remote IP addresses if they’re from certain countries. This is how you do it. This method will reject ip address that has been mapped in GeoIP at smtp conversation stage. However, This tutorial has never been tested. nothing more than a prototype that i created in leisure time.

Software required:

  • postfix (tcp_table)
  • Perl
  • Perl Geo::IP module

main.cf:

127.0.0.1:2528_time_limit = 3600s
smtpd_client_restrictions =
	check_client_access tcp:[127.0.0.1]:2528

master.cf

127.0.0.1:2528 inet  n       n       n       -       0      spawn
	user=nobody argv=/etc/postfix/geo-reject.pl


geo-reject.pl

#!/usr/bin/perl
use strict;
use warnings;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Geo::IP;

my $gi = Geo::IP->new(GEOIP_STANDARD);

# maps country code to reject (this is just example)
# add more country code you would like to reject
my @geo_map = (
	'JP' ,
	'US' ,
	'CN' ,
	'HK'
);

#
# Initalize and open syslog.
#
openlog('postfix/geoIP-reject','pid','mail');

#
# Autoflush standard output.
#
select STDOUT; $|++;

while (<>) {
	chomp;
	if (/^get\s(.+)$/i) {
		my $client_ip = $1;
		my $country_code = $gi->country_code_by_name($client_ip);

		if (defined $country_code)
		{
			if ( grep /$country_code/, @geo_map )
			{
				print "200 REJECT you're from $country_code\n";
				syslog("info","Rejecting: %s", $country_code);
			} else {
				print "200 DUNNO\n";
			}
		} else {
			print "200 DUNNO\n";
		}
		next;
	}
	print "200 DUNNO\n";
}

Test from command line

# telnet xxx.xxx.xxx.xxx 25
Trying xxx.xxx.xxx.xxx...
Connected to mx.example.com (xxx.xxx.xxx.xxx).
Escape character is '^]'.
220-mx.example.com ESMTP Postfix
ehlo dude
554 5.7.1 <remote.example.com[xxx.xxx.xxx.xxx>: Client host rejected: you're from ID
503 5.7.0 Error: access denied for remote.example.com[xxx.xxx.xxx.xxx]

Logs

May 30 12:20:33 fire postfix/smtpd[7493]: NOQUEUE: reject: CONNECT from remote.example.com[xxx.xxx.xxx.xxx] 554 5.7.1 remote.example.com[xxx.xxx.xxx.xxx] Client host rejected: you're from ID; proto=SMTP

enjoy 🙂

  9 Responses to “Postfix GeoIP Based Rejections”

Comments (9)
  1. Dec 28 17:48:07 postfix/smtpd[41199]: warning: read TCP map reply from [127.0.0.1]:2528: unexpected EOF (Connection reset by peer)
    Dec 28 17:48:07 postfix/spawn[58310]: warning: command /etc/postfix/geo-reject.pl exit status 1

    Any solution ?

  2. Check geo-reject.pl. maybe there’s some whitespace causing those errors.

  3. It’s not working – in practice but works in the tests.

    When I test it in the post or localhost telnet on the server as per one of the comments, with my country as blocked I get REJECT back with get for my GB IP.

    But when I connect via Mail I get 200 DUNNO in the logs, and I can login/telnet fine from outside from banned countries? I originally had permission problems for the script also and had to set them more permissive (755, root:postix) so dunno if that’s an issue, if it was it wouldn’t be returning anything though. I disabled any permit networks in Postfix and all the other rules, RBL etc, still the same.

  4. it’s supposed to rejecting sender from countries defined in script. when you’re login/authenticated(SASL), actually yp already passed the restrictions. script permission has nothing to do with the issue. it’s worth to watch mail log while you do the test. so you can see the real ip address which is connected from.

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.