Iptables NAT routing

Intro

Over the years I have been turning my desktop into a NAT router.. why for virtual machines of course!

If your using 1 virtual machine the virtual machine software does it for ya, but when you want to simulate your own virtual network, separate from the LAN your desktop is on this is how to do it.
I used to do this a lot back when I was working at the ANU, to enable a test network.. and now suddenly I need it again to work on multi master MySQL replication at work.

It easy to do, only a few commands really, but it something I like to have filed away, I have it on a private wiki, but thought why not post it here.

Routing in Linux

To turn on routing in your kernel at runtime, without needing to reboot, as root run:
echo 1 > /proc/sys/net/ipv4/ip_forward

To make this permanent, edit ‘/etc/sysctl.conf’  and turn on IP packet forwarding:
net.ipv4.ip_forward = 1

Now that we have packet forwarding (trouting) enabled, we need to use iptables to allow us to connect our private LAN to the internet via NAT.
To do this we need to write an iptables rule on the nat table to MASQUARADE every packet coming from the virtual or internal network interface and out to the world through our public interface.
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Where eth0 is the public interface.

The above rule, after routing changes the source IP address to that of the public interface, so traffic can get back to this machine. once a packet is returned iptables knows to change it back to the hidden LAN machine’s IP address.

In many distributions, iptables default configuration is to ACCEPT all traffic going through the FORWARD chain. But I’ve noticed Fedora doesn’t. it actually rejects forwarded packets. To check this out run the command:
iptables -L

My Fedora 12 Desktop FORWARD chain by default  looked like:
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Which REJECT’s anything being forwarded.

There are many ways to solve this:
Insert a rule to accept all:
iptables -I FORWARD 1 -j ACCEPT

Flush the chain:
iptables  -F FORWARD

If the policy is DROP, then change it to ACCEPT:
iptables -P FORWARD ACCEPT

Finally if you need to port forward to a machine behind your new NAT router then use a rule like:
iptables -t nat -I PREROUTING -p tcp -i eth0 --dport 6346 -j DNAT --to 192.168.0.2:6346

And if your interested in rate-limiting then read: http://www.debian-administration.org/articles/187