Iptables: rules to forward incoming packets from a static IP on one interface to a dynamic IP on another interface

iptableslinux-networking

I want to use a PI running the latest Raspbian as network bridge – don't know if that's exactly the right term but the goal is easy to explain:

  • one of the PI's USB ports is connected to a modem – it gets a IP by DHCP for interface usb0, the internet works (out of the box, really nice)
  • the PI's Ethernet/RJ45 port is connected to the WAN port of a router
  • I want the PI to give the devices attached to the router internet access + block all incoming requests (nothing to expose here)

The PI runs no DHCP; its eth0 is configured to use static IP 192.168.0.1 with address mask 255.255.255.0 and the router is configured to use IP 192.168.0.2, the same address mask and 192.168.0.1 as gateway.

In tests I see that beside the fact that the PI itself is online:

  • pings from the PI to the router are successful (once the option is enabled on the router…)
  • pings from LAN devices to the PI are successful

so networking wise everything seems fine but there's no internet access from the LAN devices, presumably because the packet forwarding rules are missing/wrong. What are the rules that forward all packets arriving on eth0 from IP 192.168.0.2 to the dynamic IP on usb0 + the counter-part for "answer packets" on their way back? Latter in combination with a rule that blocks all incoming requests?

Thanks!

Update

Thanks to @BillThor's answer and this tutorial I was able to get on track. It's important not to mix up the routing and the firewall aspects. The routing requires no special forwarding rules, if IP masquerade is enabled, that's "included". The commands to enable IP masquerade are:

$> sudo sysctl -w net.ipv4.ip_forward=1 to enable IP forwarding in the kernel and

$> sudo iptables -t nat -A POSTROUTING -o <wan_network_interface> -j MASQUERADE

with <wan_network_interface> the network interface that provides the internet connection, usb0 in my case. This will work as long as the default firewall policy for FORWARD is ACCEPT (and no other rule disallows it explicitly), f.ex. if iptables -S returns

OUTPUT DROP
FORWARD ACCEPT
INPUT DROP

If the default policy for FORWARD is changed to DROP the following rules enable the internet connection sharing:

$> sudo iptables -A FORWARD -i <shareconn_nw_intf> -o <online_nw_intf> -j ACCEPT
$> sudo iptables -A FORWARD -i <online_nw_interface> -o <shareconn_nw_interface> -j ACCEPT

I still doubt what happens if a packet arrives on the <online_nw_interface> on a port that was not opened by the IP masquerading? Will it be considered INPUT or will the last FORWARD rule above be applied?
I mean these FORWARD rules seem to configure the firewall to accept forwarding decisions which were taken elsewhere (masquerade) but they don't actually instruct iptables to forward anything – right?? I find that quite counter-intuitive… but if I remove the masquerade rule while keeping the forwarding rules, there's no internet connection.

Best Answer

You may want to enable masquerading which will make all outgoing traffic look like it is coming from the Pi. A starting point would be these rules.

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -A FORWARD -i eth0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

You will want to set appropriate policies on the chains. Possibly with additional rules to DROP unexpected packets on the WAN interface and REJECT packets on the eth0 interface.

If you have IPv6 available, this does not require network address translation but has as separate ip6tables implementation. There is a separate shorewall6 package to configure this.
It may be easier to configure using a tool like shorewall which should be available for the pi. The Shorewall site has lots of documentation which can be used to build your own rules or just the shorewall tool.