Uncategorized

Post fix with Multiple IP’s

Postfix how to balance outgoing emails via multiple IP addresses

Postfix how to balance outgoing emails via multiple IP addresses

Note: text in italic are description
Text in BOLD is part of script (text contents for script)

The solution is depending on postfix`s TCP_TABLES and a perl script. In my example I`m using 4 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/random.pl     (l=L in small)

#!/usr/bin/perl -w
# author: Hasan<hasan -at- harvestglobal.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,
},
];

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:(stored in path/etc/postfix)
/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=IPsmtp2 unix – – n – – smtp
-o syslog_name=postfix-smtp2
-o smtp_helo_name= FQDN
  -o smtp_bind_address=IPsmtp3 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

NOTE:
Replace FQDN with desired hostname and IP with the list of the IP addresses you`d like to use. (out of 4 ip addresses you have)

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:
Sep 2 12:50:05 myserver postfix-smtp2/smtp[2016]: 3CA964C0004: to=<example@domain.org>, relay=domain.org[XXXXXXXXX]:25, delay=2, delays=0.03/0.01/0.18/1.8, dsn=2.0.0, status=sent (250 OK id=1T86oe-0005tU-E9)
Sep 2 12:50:05 myserver postfix-smtp5/smtp[2014]: 4EE244C0012: to=<example@domain.org>, relay=domain.org[XXXXXXXXX]:25, delay=2, delays=0.01/0/0.21/1.8, dsn=2.0.0, status=sent (250 OK id=1T86oe-0005tx-Gn)
Sep 2 12:50:05 myserver postfix-smtp3/smtp[2045]: 69305680035: to=<example@domain.org>, relay=domain.org[XXXXXXXXX]:25, delay=2, delays=0.05/0/0.11/1.9, dsn=2.0.0, status=sent (250 OK id=1T86oe-0005uJ-Ih)
Sep 2 12:50:05 myserver postfix-smtp3/smtp[2034]: 444B94C0006: to=<example@domain.org>, relay=domain.org[XXXXXXXXX]:25, delay=2.2, delays=0.04/0/0.21/1.9, dsn=2.0.0, status=sent (250 OK id=1T86oe-0005tW-G9)
Sep 2 12:50:05 myserver postfix-smtp1/smtp[2039]: 585A6583CFE: to=<example@domain.org>, relay=domain.org[XXXXXXXXX]:25, delay=2.2, delays=0.01/0/0.15/2, dsn=2.0.0, status=sent (250 OK id=1T86oe-0005u0-GO)And also you get an entry when the perl script is used to provide transport:
Sep 2 13:24:59 myserver postfix/randomizer[2076]: Using: smtp6: Transport Service

This guide is based on:
http://www.kutukupret.com/2011/05/22/postfix-rotating-outgoing-ip-using-tcp_table-and-perl/
http://www.kutukupret.com/2010/12/06/postfix-randomizing-outgoing-ip-using-tcp_table-and-perl/
All credists to Hari Hendaryanto <hari.h -at- csmcom.com>

Leave a Reply

Your email address will not be published. Required fields are marked *