Moving servers without changing of IPs. No hassle migrations by proxy.

Ever had to move a bunch of servers (in our case about 30) to another location in a hurry? Every wondered if it would be easy to give your clients the same ip address before and after the migration, at least for a little while until they have their DNS’s updated?

Well, it is easy in fact. How? By using a neat little program called tcpproxy. This is actually all you need. You simply wip up a config file;


port 22
# old ip
# new ip

and run ./tcpproxy

Two servers are moved in need of port 22? Simple, just do:

port 22
# old ip
# new ip
# old ip
# new ip


After entering a bunch of servers like this (up to thirty in our case, with every servers having bunches of open ports), you get a bit tired of this format. So let’s get our trusty Perl working this for us.

Personally I like configuration formats which are clear, simple and fast. So I wipped up the following format:


for example:


and another one:



As you might notice (I hope); the ip address is not complete; in our case, we move from one network to another in which the first 3 numbers in the ip address are the same. For instance:

Before IP: 192.168.0.*
After IP: 192.168.1.*

The script I made to read in the configuration file should have some configuration settings:

# settings
$oldr = “192.168.0”; # old ip address range
$newr = “192.168.1”; # new ip address range
$eth = “eth0”; # ethernet card to make aliases for

An observant reader might notice that I added the ethernet card; this is because we want to use one machine for the forwarding, not as many machines as there were before 🙂 Also we would want the settings for this forwarding machine to be auto-generated. For the above case, we need to have:

ifconfig eth0:0 up
ifconfig eth0:1 up

To make tcpproxy to be able to listen to incoming requests on those addresses.

In case there already are alias interfaces on $eth, we need to figure out what they are, so we can decide where to start counting new aliases:

# calc interface start
$count = `ifconfig|grep $eth|tail -n 1|awk ‘{print $1}’|grep :|sed -e s/$eth://`;
if ($count eq “”) {
$count = 0;
} else {
$first = $count;

Next step is to generate all the settings for the /etc/tcpproxy.conf file and to generate a set and unset interface file for you to run to get the computer in the proper mode to listen to all incoming requests:

open(F, $f);
open(SET, “> ./set$”);
open(UNSET, “> ./unset$”);
print SET “#!/bin/shn”;
print UNSET “#!/bin/shn”;
while() {
next if /^$/;
($umln,$ipo,$ipn,$pts) = split(/:/);
print SET “# $umlnnifconfig $eth:$count $oldr.$ipo upn”;
print UNSET “# $umlnnifconfig $eth:$count downn” if $count == $first;
foreach(split(/,/,$pts)) {
$port{$_}.=”# $umlnn”;
$port{$_}.=” interface $oldr.$ipon”;
$port{$_}.=” server $newr.$ipnn”;
close F;
close SET;
close UNSET;

We cannot write the tcpproxy.conf as we go along, because it is only allowed to have one

port X

per set of interfaces and servers. In the above code we collected all ports with their interfaces settings, contained in $port.

We only have to put these into a nice string which is, in fact, the /etc/tcpproxy.conf file; we leave the saving of it to the reader. For fun it is nicely sorted by port 🙂

foreach(sort {$a <=> $b} keys %port) {
$tot .= “port $_n”;
$tot .= $port{$_};
$tot .= “n”;

Have fun!

Be the first to leave a comment. Don’t be shy.

Join the Discussion

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>