Postfix Changing Outgoing IP By Time Interval Using TCP_TABLE And Perl

Someone asked me if i can make a perl scripts that can change the ip address based on time interval, say he want ip address 1.2.3.4 used within one hour, if done next ip address will be used within next one hour..and so on. when it came to highest number of ip address in array, they will be reset back to the start. first i suggest him to look at the articles i wrote. But then i decide to write Perl script which was made for the purposes mention above.

here we are..

Postfix section:

master.cf
127.0.0.1:2527 inet  n       n       n       -       0      spawn
          user=nobody argv=/etc/postfix/ip_by_time.pl

ip1  unix -       -       n       -       -       smtp
          -o syslog_name=postfix-ip1
          -o smtp_helo_name=smtp1.example.com
          -o smtp_bind_address=1.2.3.1

ip2  unix -       -       n       -       -       smtp
          -o syslog_name=postfix-ip2
          -o smtp_helo_name=smtp2.example.com
          -o smtp_bind_address=1.2.3.2

ip3  unix -       -       n       -       -       smtp
          -o syslog_name=postfix-ip3
          -o smtp_helo_name=smtp3.example.com
          -o smtp_bind_address=1.2.3.3

ip4  unix -       -       n       -       -       smtp
          -o syslog_name=postfix-ip4
          -o smtp_helo_name=smtp4.example.com
          -o smtp_bind_address=1.2.3.4
....
....

main.cf

transport_maps = tcp:[127.0.0.1]:2527
127.0.0.1:2527_time_limit = 3600s

postfix, integrating memcache as a lookup table using tcp_table

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";
}

Postfix Rotating Outgoing IP Using TCP_TABLE And Perl

In The last article “Postfix Randomizing Outgoing IP Using TCP_TABLE And Perl“, i was writing about my experiment randomizing outbound ip. someone asked if the script can be mimicked as in the iptables statistic module. indeed, when using the previous script, the results obtained will really random. although that is what the script was created.

I found this wiki explaining about Weighted Round-Robin Scheduling.

Supposing that there is a server set S = {S0, S1, …, Sn-1};
W(Si) indicates the weight of Si;
i indicates the server selected last time, and i is initialized with -1;
cw is the current weight in scheduling, and cw is initialized with zero;
max(S) is the maximum weight of all the servers in S;
gcd(S) is the greatest common divisor of all server weights in S;

while (true) {
    i = (i + 1) mod n;
    if (i == 0) {
        cw = cw - gcd(S);
        if (cw <= 0) {
            cw = max(S);
            if (cw == 0)
            return NULL;
        }
    }
    if (W(Si) >= cw)
        return Si;
}

anyway, I do not have much time to implement that algorithm into the script, so I use an existing perl module List:: util:: WeightedRoundRobin

Postfix Randomizing Outgoing IP Using TCP_TABLE And Perl

This time i’ll show you how to randomize your smtp outbound’s IP addresses. This can be done via transport map. But, since ordinary Postfix lookup tables store information as (key, value) pairs. it will provide static value only. we need someting that can manipulate the value (right hand side) of a lookup table. In order to answer random transport value.

first come to mind was tcp_tables, tcp_tables lookup table gives some flexibility for us to execute our tiny perl script that will randomizing transport. that’s the basic idea.

Ok, here’s the first part, create perl script call random.pl, anyway this script only provide answer in “catch-all” manner. so it will randomized, all outgoing mail.

# cd /etc/postfix
# vi random.pl
#!/usr/bin/perl -w
# author: Hari Hendaryanto <hari.h -at- csmcom.com>

use strict;
use warnings;
use Sys::Syslog qw(:DEFAULT setlogsock);

#
# our transports array, we will define this in master.cf as transport services
#

our @array = (
'rotate1:',
'rotate2:',
'rotate3:',
'rotate4:',
'rotate5:'
);

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

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

while (<>) {
        chomp;
        # randomizing transports array
        my $random_smtp = int(rand(scalar(@array)));
        if (/^get\s(.+)$/i) {
                print "200 $array[$random_smtp]\n";
                syslog("info","Using: %s Transport Service", $random_smtp);
                next;
        }

	print "200 smtp:";
}

Postfix header_checks using tcp_table and checkdbl.pl script

Postfix implements the header_checks as built-in content inspection classes while receiving mail. Usually the best performance is obtained with pcre (Perl Compatible Regular Expression) tables or slower regexp (POSIX regular expressions). Googling on the net, i’ve found tiny perl script that can queries to dbl.spamhaus.org, multi.surbl.org, black.uribl.com. ( Sahil Tandon wrote it, based on  João Gouveia perl script, i think..)

first download the script

# cd /etc/postfix
# wget http://people.freebsd.org/~sahil/scripts/checkdbl.pl.txt

Rename and make it executable

# mv checkdbl.pl.txt checkdbl.pl
# chmod 755 checkdbl.pl

Edit master.cf add this two lines

127.0.0.1:2526 inet  n       n       n       -       0      spawn
user=nobody argv=/etc/postfix/checkdbl.pl

Make preliminary test, to ensure checkdb.pl sih really spawned and answering our queries

# postfix reload
# telnet 127.0.0.1 2526