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:";
}
Make it executable
# chmod 755 random.pl
master.cf parts
Run the scripts via postfix spawn daemon service.
127.0.0.1:2527 inet n n n - 0 spawn
user=nobody argv=/etc/postfix/random.pl
add 5 smtp client services called rotate1, rotate2, rotate3, rotate4, rotate5, that bind to its own ip
address and has uniq syslog/helo name.
# random smtp
rotate1 unix - - n - - smtp
-o syslog_name=postfix-rotate1
-o smtp_helo_name=smtp1.example.com
-o smtp_bind_address=1.2.3.1
rotate2 unix - - n - - smtp
-o syslog_name=postfix-rotate2
-o smtp_helo_name=smtp2.example.com
-o smtp_bind_address=1.2.3.2
rotate3 unix - - n - - smtp
-o syslog_name=postfix-rotate3
-o smtp_helo_name=smtp3.example.com
-o smtp_bind_address=1.2.3.3
rotate4 unix - - n - - smtp
-o syslog_name=postfix-rotate4
-o smtp_helo_name=smtp4.example.com
-o smtp_bind_address=1.2.3.4
rotate5 unix - - n - - smtp
-o syslog_name=postfix-rotate5
-o smtp_helo_name=smtp5.example.com
-o smtp_bind_address=1.2.3.5
Before we actually implement our randomize transport, let’s make sure that the setting actually work.
Reload postfix
# postfix reload
Run this query fiew times, and you’ll see the perl script will return “random answer” transport
# postmap -q "whatever" tcp:127.0.0.1:2527 rotate1:
# postmap -q "whatever" tcp:127.0.0.1:2527 rotate5:
And so on..
Note on “whatever”, since the script acted in “catch-all” mode as i’ve mentioned earlier, what ever postfix transport_maps client asked. it will be answered with random values such as rotate1, rotate2, rotate3, rotate4, rotate5 in randomized fashion.
main.cf parts
Add these lines
transport_maps = tcp:[127.0.0.1]:2527 127.0.0.1:2527_time_limit = 3600s
Reload postfix
that’s it. example log would be like these and that’s indicate that randomizer is working.
Month date 12:26:53 host postfix-rotate1/smtp[4252]: A1CA68480A4: to=<xxx@example.com>, relay=mx.example.com.com[xx.xx.xxx.xx]:25], delay=3.6, delays=0.69/0.01/0.81/2, dsn=2.0.0, status=sent (250 ok dirdel) --snip-- Month date 12:27:06 host postfix-rotate5/smtp[4253]: 41C2E8480A4: to=<xxx@example.net>, relay=mx.example.net[xx.xxx.xxx.xxx]:25], delay=6, delays=0.14/0.01/0.85/5, dsn=2.0.0, status=sent (250 ok dirdel) --snip-- Month date 12:27:22 host postfix-rotate3/smtp[4277]: 4BA9F8480A4: to=<xxx@example.org>, relay=mx.example.org[xx.xxx.xx.xxx]:25], delay=7.9, delays=0.85/0.02/0.61/6.4, dsn=2.0.0, status=sent (250 ok dirdel)
disclaimer:
I’m not taking any responsible if the reader “misuse” this tutorial.the tutorial is provide as-is for experimental purposes.
Just a feedback. The script is running ok but…but…after two days of sending I get the following error :”smtp postfix/qmgr[20602]: fatal: fcntl F_DUPFD 128: Too many open files”.
Regards
Andrei
that’s postfix errors, look likes you ran out of file descriptor, you should tuned up you box, increase maximum file that can be opened (man ulimit).
i ran this setup years without any problem
What value do you suggest it will be enough? Thank you for you kind support.
well, that depends on your hardware..
Hey,
I’m using your code but when sending an e-mail to myself, I’m getting the following error message in the log file:
to=, relay=none, delay=1.9, delays=0.21/0/1.7/0, dsn=5.4.6, status=bounced (mail for *** loops back to myself
where *** is my domain.
Any idea where it comes from?
postmap -q “whatever” tcp:127.0.0.1:2527
postmap: warning: read TCP map reply from 127.0.0.1:2527: malformed reply: Can’t open -o: No such file or directory at /etc/postfix/random.pl line 23.
postmap: fatal: tcp:127.0.0.1:2527: query error: Operation now in progress
What i’m doing wrong?
Thanks!
post your whole script here
PS:
line 23 on my script is:
while () {
when i check
postmap -q “whatever” tcp:127.0.0.1:2527
then back message : “postmap: fatal: unsupported dictionary type: tcp”
how do i fix it?
what version of postfix did you use? you have to upgrade to recent postfix in order for tcp table to work