Linux NAT routing on Raspberry Pi with Buildroot
This post documents the kernel modules and other packages required to build an embedded Linux NAT router using Buildroot, for Raspberry Pi.
Modify Linux kernel configuration
make linux-menuconfig in buildroot folder to initiate kernel configuration utility. Select modules shown in the figures below.
Ensure that the following is enabled under Networking Options
- Network packet filtering framework (Netfilter)
Ensure that the following are enabled under Core Netfilter Configuration
- Netfilter connection tracking support
- Netfilter Xtables support (required for ip_tables)
- “conntrack” connection tracking match support
- “state” match support
Ensure following is enabled under Network packet filtering framework (Netfilter)
- Advanced netfilter configuration
Ensure the following modules are selected under IP: Netfilter Configuration
- IPv4 connection tracking support (required for NAT)
- IP tables support (required for filtering/masq/NAT)
- Packet filtering
- IPv4 NAT
- MASQUERADE target support
- NETMAP target support
- REDIRECT target support
Enable other targets if you want to do sophisticated filtering.
Modify Buildroot Configuration
Include iptables utility package shown in the figure below, using the configuration utility invoked by executing
make menuconfig. Include tcpdump if you want to sniff network data.
Now, just execute make to build the system, and copy the kernel image and root file system to SD card.
Perform NAT routing
I use the following commands to bring up the network interfaces and setup NAT forwarding. Any packets received on interface eth0 are forwarded to usb0. Only packets for connections already established are forwarded back to eth0. usb0 is a USB CDC ethernet interface of the kind seen in modems.
ifconfig usb0 up ifconfig eth0 up dhcpcd echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -o usb0 -j MASQUERADE iptables -A FORWARD -i usb0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i eth0 -o usb0 -j ACCEPT
If you get any of the following error messages with iptables, you are probably missing one of the kernel modules mentioned above
iptables v1.4.21: can't initialize iptables table `nat': Table does not exist (do you need to insmod?) Perhaps iptables or your kernel needs to be upgraded.
iptables v1.4.21: can't initialize iptables table `filter': Table does not exist (do you need to insmod?) Perhaps iptables or your kernel needs to be upgraded.
iptables: No chain/target/match by that name.
If the NAT router is not the default gateway on downstream hosts and routers, you’ll have to setup static routes to relay packets upstream. This can be done using a command such as the following on Mac OS X
sudo route -n add -net 10.0.0.0/8 192.168.2.1
Or, on Linux
route add -net 10.0.0.0/8 gw 192.168.2.1
Finally, a couple of useful commands to troubleshoot IP routing and forwarding.
List all rules in iptables
iptables -L -v
Flush all rules in iptables
A basic packet sniffer
tcpdump -A -i usb0
List all routes