Iptables – Forward Traffic in & out, NAT iptables

forwardingiptablesnat;

I have a box setup as DHCP Server with NAT ipv4 forwarding enabled. Currently the box uses eth0 to connect to a local network and has access to the internet, it has another 3 interfaces, eth1, eth2 and eth3 which connect to other boxes.
The 3 other boxes can all talk to one another and the primary box.

I'd like to allow the other 3 boxes to access the internet via the primary box over it's eth0 interface so I believe I need to setup iptable rules. There's no special port rules or anything specific, I'd just like traffic from eth1, eth2 and eth3 to go through eth0 when accessing the public internet.

for thoroughness here is my /etc/network/interface file

auto lo

iface lo inet loopback
iface eth0 inet dhcp

iface eth1 inet static
  address 192.168.1.1
  netmask 255.255.255.0

iface eth2 inet static
  address 192.168.2.1
  netmask 255.255.255.0

iface eth3 inet static
  address 192.168.3.1
  netmask 255.255.255.0

From the information here on SO and around the web this is what my iptables-save currently look like

*nat
:PREROUTING ACCEPT [1799:327587]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [23:2190]
-A POSTROUTING -j MASQUERADE 
COMMIT
*filter
:INPUT ACCEPT [3474:500657]
:FORWARD ACCEPT [24:1613]
:OUTPUT ACCEPT [857:128814]
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 
-A FORWARD -s 192.168.1.101 -i eth1 -o eth0 -m conntrack --ctstate NEW -j ACCEPT 
-A FORWARD -s 192.168.2.102 -i eth2 -o eth0 -m conntrack --ctstate NEW -j ACCEPT 
-A FORWARD -s 192.168.3.103 -i eth3 -o eth0 -m conntrack --ctstate NEW -j ACCEPT 
COMMIT

The rules are persistant on reboot via pre-up

Since I do not have a good understanding of iptable rules the current questions on serverfault are hard to follow / understand what I'm actually doing.

Best Answer

There are some problems with how you wrote your rules.

-A POSTROUTING -j MASQUERADE 

This rule applies too broadly. You only need such rule for connections from the LAN leaving your network. One way to do that would be to specify which outgoing interface it applies to:

-A POSTROUTING -o eth0 -j MASQUERADE 

Additionally your filter table does not make much sense:

*filter
:INPUT ACCEPT [3474:500657]
:FORWARD ACCEPT [24:1613]
:OUTPUT ACCEPT [857:128814]
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 
-A FORWARD -s 192.168.1.101 -i eth1 -o eth0 -m conntrack --ctstate NEW -j ACCEPT 
-A FORWARD -s 192.168.2.102 -i eth2 -o eth0 -m conntrack --ctstate NEW -j ACCEPT 
-A FORWARD -s 192.168.3.103 -i eth3 -o eth0 -m conntrack --ctstate NEW -j ACCEPT 
COMMIT

Each of your rules ACCEPT packets according to certain criteria. However it is all redundant since in the end you are going to ACCEPT them with the default policy for the chain. So the outcome is that you ACCEPT everything, which would also be the case if you removed all the rules.