Thursday, October 1, 2009

Forwarding Traffic with IPTables

The netfilter/iptables tools for Linux can be used to route traffic destined for a particular host to another. An example where this might be useful is when migrating a service from one host to another and waiting for DNS changes to propagate, you want to ensure that all traffic destined for a particular host name will be serviced by one particular machine.

Say you have a machine called alpha, with IP addresses and and you wish to route traffic destined for to a different machine, called beta, that has the IP address, essentially using the first machine as a "middle-man" for requests destined for a particular host name. The effect will be that, no matter what machine the requests end up at initially, they will always be serviced by the second machine.

This is by no means the most elegant method for redirecting services; HTTP Redirects can generally be used with websites. However, sometimes this method can be useful.

To implement this using iptables, the commands below would need to be executed as root on alpha:

echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -A PREROUTING -t nat -d -j DNAT --to
iptables -A POSTROUTING -t nat -d -j SNAT --to

The first line tells the kernel to allow forwarding of IP packets; without this, the other commands will be useless. The first iptables rule mangles packets of data destined for before any routing decisions take place by changing the destination IP to, which causes the redirection of traffic. The second rule takes effect after the traffic has been routed, ensuring that return traffic travels back through alpha by changing the source IP of packets destined for beta to

If you wish to just forward traffic destined for one particular port, for example a mysql database on 3306, you would use the -p and --dport arguments:

echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -A PREROUTING -t nat -p TCP -d --dport 3306 -j DNAT --to
iptables -A POSTROUTING -t nat -d -j SNAT --to

By using multiple PREROUTING rules, you can specify multiple ports; one for each of the services you need to forward traffic for.


This article originally appeared here