Things required:
• perl Cache::Memcached module
• libmemcached
• postfix with tcp_table support
• /home/httpd/cgi-bin/meta/getmemcacheentry
Configuration Files:-
/etc/postfix/master.cf
/etc/postfix/main.cf
Script:-
/etc/postfix/memc.pl
Below are the steps that are required to make this work:
A simple perl script that allows you to handle the protocols of tcp_table named memc.pl.
an entry like this in master.cf
127.0.0.1:2552 inet n n n – 0 spawn
user=nobody argv=/etc/postfix/memc.pl
Make memc.pl executable and don’t forget to reload postfix
# chmod 755 memc.pl
# /etc/init.d/postfix reload
And, for example we want to use it in smtpd_recipient_restrictions as check_recipient_access in main.cf
smtpd_recipient_restrictions =
…
check_recipient_access tcp:[127.0.0.1]:2552,
…
TESTS:-
Don’t forget to reload postfix. let’s try using postmap to query entries that we have input into memcached.
$ /var/postfix/sbin/postmap -q fuhomipu_12@rediffmail.com tcp:127.0.0.1:2552
DUNNO DO WHATEVER IT WANTS TO DO
# telnet localhost 2552
Trying 127.0.0.1…
Connected to localhost.localdomain (127.0.0.1).
Escape character is ‘^]’.
get zbddz9a7fh850a2@rediffmail.com
200 DISCARD DELETING MAILS FROM THIS SENDER
Connection closed by foreign host.
# /var/postfix/sbin/postmap -q zbddz9a7fh850a2@rediffmail.com tcp:127.0.0.1:2552
DISCARD DELETING MAILS FROM THIS SENDER
# 3 Expected Responses:-
1. DISCARD (Deleted the mail without sending the bounceback)
2. HOLD (Move the email to HOLD QUEUE)
3. DUNNO (Allow mails and check if another rule exists)
SOME LEARNING:-
NAME
tcp_table – Postfix client/server table lookup protocol
PROTOCOL DESCRIPTION
The TCP map class implements a very simple protocol: the
client sends a request, and the server sends one reply.
Requests and replies are sent as one line of ASCII text,
terminated by the ASCII newline character. Request and
reply parameters (see below) are separated by whitespace.
Send and receive operations must complete in 100 seconds.
REQUEST FORMAT
Each request specifies a command, a lookup key, and possi-
bly a lookup result.
get SPACE key NEWLINE
Look up data under the specified key.
put SPACE key SPACE value NEWLINE
This request is currently not implemented.
REPLY FORMAT
Each reply specifies a status code and text. Replies must
be no longer than 4096 characters including the newline
terminator.
500 SPACE text NEWLINE
In case of a lookup request, the requested data
does not exist. In case of an update request, the
request was rejected. The text describes the
nature of the problem.
400 SPACE text NEWLINE
This indicates an error condition. The text
describes the nature of the problem. The client
should retry the request later.
200 SPACE text NEWLINE
The request was successful. In the case of a lookup
request, the text contains an encoded version of
the requested data.
memc.pl
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use Cache::Memcached;
use Data::Dumper;
my $memd = new Cache::Memcached {
’servers’ => [ '127.0.0.1:11211' ],
};
my $email;
sub usage
{
print “Unknown option: @_\n” if ( @_ );
print “Usage: memc.pl abc\@domain.com \n”;
exit;
}
sub trim($)
{
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
sub qrymemc {
return unless /^get\s+(.+)/i;
my $email = lc($1);
chomp($email);
trim($email);
my $cmd = “getmemcacheentry xx.xx.xx.xx,xx.xx.xx.xx 11211 emailid:”.$email;
my $ret = `$cmd`;
return $ret;
#
# my $val = $memd->get(”fbl:”.$email);
# if (defined $val) {
# return ($email,$val);
# }
# return;
}
my $val;
while (<>) {
chomp;
if (/^get\s+(.+)/i) {
$email = lc($1);
}
if(defined($email) && $email ne ”) {
#print “You have entered $email\n”;
chomp($email);
trim($email);
#print(”\nDBG:email:”.$email.”\n”);
#$val = $memd->get(’fbl:’.$email);
#print(”DBG:val:”.$val.”\n”);
my $val = qrymemc($email);
#print(”DBG:val:”.$val.”\n”);
#print(”You have entered $email \n”);
#if (@res) {
# chomp(@res);
# $val = $res[1];
# next;
#}
if(!defined($val)) {
print(”200 DUNNO SENDER KEY NOT FOUND\n”);
exit;
}
chomp($val);
trim($val);
if (lc($val) eq “perm”) {
print(”200 DISCARD DELETING MAILS FROM THIS SENDER\n”);
exit;
}
elsif (lc($val) eq “temp”) {
print(”200 HOLD HOLDING the mail from this SENDER\n”);
exit;
}
else {
print(”200 DUNNO DO WHATEVER IT WANTS TO DO$val\n”);
exit;
}
}
else {
usage();
}
}
That’s It !!!!!