Skip to main content

How to balance outgoing emails via multiple IP addresses with postfix

Postfix how to balance outgoing emails via multiple IP addresses

The solution is depending on postfix`s TCP_TABLES and a perl script. In my example I`m using 7 different IP address to route outgoing mails, make sure you`ve already the IP addresses you are going to use have been configured on your box.

First get a recent postfix rpm from here http://ftp.wl0.org/official/2.9/RPMS-rhel5-x86_64/. This one is built for rhel5/centos5 however should be working without much hassle on rhel6/centos5.

Install the package:
# rpm -Uvh postfix-2.9.1-1.rhel5.x86_64.rpm

Make sure its built with tcp tables support:
# postconf -m
btree
cidr
environ
fail
hash
internal
ldap
memcache
nis
proxy
regexp
static
tcp
texthash
unix

Install the perl module  List::util::WeightedRoundRobin:
cpan install /List::util::WeightedRoundRobin/

Create the following perl script and make it executable:
vi /etc/postfix/postfix.pl

#!/usr/bin/perl -w
# author: Hari Hendaryanto <hari.h -at- csmcom.com>
use strict;
use warnings;
use Sys::Syslog qw(:DEFAULT setlogsock);
use List::Util::WeightedRoundRobin;
use Storable;

my $hashfile="/tmp/file.hash";
store {}, $hashfile unless -r $hashfile;

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


# Queued using Weighted Round-Robin Scheduling
#
my $list = [
{
name => 'smtp1:',
weight => 1,
},
{
name => 'smtp2:',
weight => 1,
},
{
name => 'smtp3:',
weight => 1,
},
{
name => 'smtp4:',
weight => 1,
},
{
name => 'smtp5:',
weight => 1,
},
{

name => 'smtp6:',
weight => 1,
},
{
name => 'smtp7:',
weight => 1,
},
];

my $WeightedList = List::Util::WeightedRoundRobin->new();
my $weighted_list = $WeightedList->create_weighted_list( $list );

# $maxinqueue max number of queue in smtp list
my $maxinqueue = scalar(@{$weighted_list});

#
# Initalize and open syslog.

#
openlog('postfix/randomizer','pid','mail');
#
# Autoflush standard output.
#
select STDOUT; $|++;

while (<>) {
chomp;
my $count;
my $hash=retrieve($hashfile);

if (!defined $hash->{"index"})
{
$count = 0;
} else {
$count = $hash->{"index"};
}

if ($count >= $maxinqueue)
{
$hash->{"index"} = 0;
$count = 0;
}

$hash->{"index"}++;
store $hash, $hashfile;
my $random_smtp = ${$weighted_list}[$count];
if (/^get\s(.+)$/i) {
print "200 $random_smtp\n";
syslog("info","Using: %s Transport Service", $random_smtp);
next;
}
print "200 smtp:\n";
}

Execute the script to make sure it`s working and no errors are encountered:
/etc/postfix/random.pl
Configure postfix to use the random generated smtp transport.

Edit /etc/postfix/master.cf, by appending following lines:
## Round-robin outgoing smtp
127.0.0.1:23000 inet n n n - 0 spawn
user=nobody argv=/etc/postfix/random.pl
# random smtp
smtp1 unix - - n - - smtp
-o syslog_name=postfix-smtp1
  -o smtp_helo_name=FQDN
  -o smtp_bind_address=IP

smtp2 unix - - n - - smtp
-o syslog_name=postfix-smtp2
-o smtp_helo_name= FQDN
  -o smtp_bind_address=IP

smtp3 unix - - n - - smtp
-o syslog_name=postfix-smtp3
  -o smtp_helo_name=FQDN
  -o smtp_bind_address=IP

smtp4 unix - - n - - smtp
-o syslog_name=postfix-smtp4
  -o smtp_helo_name=FQDN
  -o smtp_bind_address=IP

smtp5 unix - - n - - smtp
-o syslog_name=postfix-smtp5
  -o smtp_helo_name=FQDN
  -o smtp_bind_address=IP

smtp6 unix - - n - - smtp
-o syslog_name=postfix-smtp6
-o smtp_helo_name= FQDN
  -o smtp_bind_address=IP

smtp7 unix - - n - - smtp
-o syslog_name=postfix-smtp7
-o smtp_helo_name= FQDN
  -o smtp_bind_address=IP

Replace FQDN with desired hostname and IP with the list of the IP addresses you`d like to use.

Append the following lines to your /etc/postfix/main.cf:

transport_maps = tcp:127.0.0.1:23000
127.0.0.1:23000_time_limit = 3600s

Restart/reload postfix and verify everything is working correctly:
# postmap -q "dummy" tcp:127.0.0.1:23000
smtp4:
# postmap -q "dummy" tcp:127.0.0.1:23000
smtp5:
# postmap -q "dummy" tcp:127.0.0.1:23000
smtp6:


In your logs you should see the different smtp transport beeing used when mails are sent.
 

And also you get an entry when the perl script is used to provide transport.


THanks :)




      

Comments

Popular posts from this blog

How To Block Removable drive in linux

For Block Removable disk like pen drive you have to run only one following command - Open terminal -      #sudo chmod 700 /media For unblock -     # sudo chmod 755 /media   

how to take mails backup in outlook 2007

How to take backup of mails in outlook 2007. there is a very simple way to taking backup of mails 1.Opne outlook 2007 > tools >account > data files >open folder then close all other windows and copy outlook.pst file in a safe location To restore backup 1.Opne outlook 2007 > tools >account > data files > add > and give the location of outlook.pst file.