Jul 202011
 

I have not had time to do the test “postfix memcached patch” because there are no idle servers that can be used for the experiment. instead, I’ve made a tutorial how to integrate memcached as a “postfix lookup table” with the help of tcp_table and a simple perl script.

Indeed, tcp_table “table lookup protocol” is one of the most powerful tools as well as the regexp and pcre, in my opinion. although client-server connection is not protected and and the server is not authenticated.

yes, I did a lot of experiments using tcp_table and perl scripts. it made me realize that I can do almost everything I need and make postfix as my favorite MTA.

Things required:

OK, first we create a simple perl script that allows you to handle the protocols of tcp_table. let’s call it memc.pl

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

# Configure the memcached server
my $memd = new Cache::Memcached {
            'servers' => [ '127.0.0.1:11211' ],
};

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

sub qrymemc {
        return unless /^get\s+(.+)/i;
        my $kmemc = lc($1);
        chomp($kmemc);
        trim($kmemc);
        my $vmemc = $memd->get($kmemc);
        if (defined $vmemc) {
                return ($kmemc,$vmemc);
        }
        return;
}

sub trim{
        $_[0]=~s/^\s+//;
        $_[0]=~s/\s+$//;
        return;
}

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

while (<>) {
        chomp;
        if (/^get\s+(.+)/i) {
                my $data = lc($1);
                my @res = qrymemc($data);
                syslog("info","data: %s", $data);
                if (@res) {
                        chomp(@res);
                        print "200 $res[1]\n";
                        syslog("info","Found: key = %s, value = %s", $res[0], $res[1]);
                        next;
                }
        }
        print "200 DUNNO\n";
}


Create 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
# postfix reload

To perform the entry/deletion “key, value” to the memcache I wrote a perl script called postmemc.pl

#!/usr/bin/perl
use strict;
use warnings;
use Cache::Memcached;
use Getopt::Long;

my $memd = new Cache::Memcached {
    'servers' => [ "localhost:11211" ],
  };

my ($k, $v, $help, $delk);

usage() if ( @ARGV < 1 or
           ! GetOptions ('help|?' => \$help, "k=s" => \$k, "v=s" => \$v, "del=s" => \$delk)
           or defined $help );

sub usage
{
        print "Unknown option: @_\n" if ( @_ );
        print "Usage: postmemc.pl --k=key --v='value'\n";
        print "       postmemc.pl --k key --v 'value'\n";
        print "       postmemc.pl --del=key\n";
        print "       postmemc.pl --del key\n";
        exit;
}

if (defined($k) && defined($v) && !defined($delk)) {
        my $val = $memd->get($k);

        if ($val)
        {
                print "Key: $k with Value: '$val' exist\n";
        } else {
                $memd->set($k, $v);
        }
} elsif (!defined($k) && !defined($v) && defined($delk)) {
        my $val = $memd->get($delk);

        if ($val)
        {
                $memd->delete($delk);
        } else {
                print "Key: $delk not' exist\n";
        }
} else {
        usage();
}

$memd->disconnect_all();

Now, let’s try to enter some data using postmemc.pl

$ ./postmemc.pl --k='spam@example.com' --v='REJECT not allowed'

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,
   ...

Don’t forget to reload postfix. let’s try using postmap to query entries that we have input into memcached.

$ postmap -q spam@example.com tcp:[127.0.0.1]:2552
REJECT not allowed

yeah, another tcp_table’s greatness has been created.  :mrgreen:

  7 Responses to “postfix, integrating memcache as a lookup table using tcp_table”

Comments (7)
  1. sure why not?table(and the code) can be modified, either contained email address or ip address 🙂

  2. I have tested successfully on all incoming mails using tcp_table.

    But, I fail to perform it on the outgoing mail of local machine. In fact, the mail was sent out directly without leave any warning message on mail log.

    Is there any way to achieve these kind of checking on all mail relay to this server (including same machine)?

 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.