Iptables: redirect port to external IP

From lxadm | Linux administration tips, tutorials, HOWTOs and articles
Jump to: navigation, search

Sometimes, you need to migrate the servers - the new server will have a new IP. Because DNS changes are not immediate, and even with low TTL - you might lose some traffic - some DNS servers ignore TTL, so the traffic will hit your old IP long after DNS changes were made.

Fortunately, it's easy to redirect all traffic to a given port to a different, external IP: this way, no traffic will be lost.


Assuming it's web traffic, traffic flow will look like below (all traffic will pass through the old server):

client browser <--> old server:80 <--> new server:80


Please note that the new webserver will see the IP of the old IP in its logs, not the IP of the original client browser.


Below are iptables rules needed to achieve this:

OLD_IP=1.2.3.4
NEW_IP=2.3.4.5

# enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# redirect the traffic on port 80
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination $NEW_IP:80
iptables -t nat -A POSTROUTING -p tcp -d $NEW_IP --dport 80 -j SNAT --to-source $OLD_IP

# redirect the traffic on port 443 (SSL)
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination $OLD_IP:443
iptables -t nat -A POSTROUTING -p tcp -d $NEW_IP --dport 443 -j SNAT --to-source $OLD_IP

# finally, rewrite the IPs (MASQUERADE)
iptables -t nat -A POSTROUTING -j MASQUERADE

In case your old server does not have a public IP, or has a "fake" public IP (i.e. all Amazon AWS servers don't have a public IP internally) - please use server's private IP as $OLD_IP (with Amazon AWS, typically 10.x.x.x).