PiRouter

At times you may need to connect networks together but you don’t necessarily have a spare router up your sleeve to make it happen. Well, while your waiting for the IT budget to come through, why not have a Raspberry Pi router in your back pocket for a temporary fix. It won’t be a barn burner, but hey, at least you can make some progress.

In the absolute simplest of networks, a single workgroup switch can be used as the physical layer to connect multiple networks together, and the host subnet masks will keep their traffic isolated. Obviously its not very secure, since anyone can change their network settings to make their computer see both networks. Using a switch capable of Virtual LAN’s, or VLAN’s, provides isolation of multiple networks. However, at some point these groups will want to share stuff or communicate and you will need a router to allow networks to communicate with each other.

There are a number of examples for turning a Raspberry Pi into a Wireless Access Point (WAP), including my own efforts documented in this blog. We will discuss how to connect three wired Ethernet networks together with a Raspberry Pi, called PiRouter for now. In addition we will use a WiFi adapter in the PiRouter to establish a WiFi access point. So in total we will have four physical media segments to connect.

Network Design

Our expectations for the PiRouter is it will handle the packet forwarding for IPv4 network addresses, to be able to see traffic on the network for troubleshooting, and provide Network Address Translation (NAT) for traffic headed to the internet. We are not going to dive deeply into firewall rules, just enough to limit Internet traffic to those connections initially established by someone on the inside of our networks.

The dirty little secret of this build is that there are no routing processes running on the Pi. This network design is commonly referred to as a stub network, but since we are running NAT on the connection to the outside world, we are not really routing traffic as much as we are “forwarding” traffic between the networks the PiRouter is directly connected to.

Our networks will be as follows:

172.16.0.0/24 – for Internet Access from an ISP

172.17.0.0/24 – for Sales & Service

172.18.0.0/24 – for Development and Manufacturing

172.19.0.0/24 – for IT access via WiFi

The PiRouter will need to “see” all networks, so we will assign the xxx.yyy.zzz.1 IP address for all the networks to the respective PiRouter interfaces. This simple connection would let the PiRouter itself offer services to each network, like DHCP for example.

The Build

Edit the /etc/network/interfaces file to configure the interfaces to use these network addresses. The auto option makes the interfaces automatically become available at boot time in the order they appear in this file, and allows you to restart all network interfaces more easily.

auto lo
iface lo inet loopback

# Native NIC for ISP Connection - assuming 172.16.1.0 network is used
auto eth0
iface eth0 iinet dhcp

#USB NIC 1 for the Sales and Service network
auto eth1
iface eth1 inet static
address 172.17.1.1
netmask 255.255.255.0
network 172.17.1.0
broadcast 172.17.1.255

#USB NIC 2 for the Development and Manufacturing network
auto eth2
iface eth2 inet static
address 172.18.1.1
netmask 255.255.255.0
network 172.18.1.0
broadcast 172.18.1.255

#WiFI USB NIC for the Access Point
auto wlan0
iface wlan0 inet static
address 172.19.1.1
netmask 255.255.255.0
network 172.19.1.0
broadcast 172.19.1.255

To make these settings effective, restart network services by running this set of commands.

    sudo ifdown -a && sudo ifup -a

    - or -

    sudo reboot (kinda brute force)

Even with the interfaces set up this way, the hosts on any given network are still isolated from each other, so we have to enable packet forwarding.

Packet Forwarding

To allow packets to move between networks, IP network forwarding must be enabled on the PiRouter. Activate IPv4 forwarding with the following command:

    sudo echo 1 > /proc/sys/net/ipv4/ip_forward

We want this to work after a reboot, so we need to edit the /etc/sysctl.conf file, looking for the following line:

    #net.ipv4.ip_forward=1

Remove the comment character (#) at the start of the line, save the file, and now the packet forwarding will survive a reboot.

This is enough to allow hosts on each network talk to hosts on the other networks. But what if you want all the computers to use the Internet? In our example we have used RFC1918 private network addressing for our networks, which will require Network Address Translation to the public network address provided by an Internet Service Provider.

Network Address Translation

In the WAP tutorial we created some simple rules for NAT where traffic from the wlan0 interface was able to be translated through the eth0 port. The rules only allowed return traffic to the wlan0 when the connection was initially established by a host on the wlan0 network. Pretty basic stuff that any home router would do. But our router has four interfaces not two. We have routing enabled between our ports, but if we want any of those networks (Exo network or PiServer network or wireless clients) to use the internet we need NAT rules to translate all those networks through eth0.

So we are going to expand on the NAT rules from the WAP tutorial to include the eth1 and eth2 interfaces. Do not reboot until the end of this section or all future changes will be lost.

Create the following iptables rules to allow NAT (assuming that the eth0 interface is connected to the internet).

    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
    iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
    iptables -A FORWARD -i eth0 -o eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i eth2 -o eth0 -j ACCEPT

We need to save these iptables settings so they are enabled every time you boot the RPi. To save these settings to a file, use the following command.

    iptables-save > /etc/iptables.up.rules

I have learned that restoring the iptables rules is more reliable if I place the restore command as the last line in the network interfaces file. Open the file in nano…

    nano /etc/network/interfaces

add the following line at the bottom of the listing…

    iptables-restore < /etc/iptables.up.rules

Dynamic Routing on the Pi

Our PiRouter project is pretty simple and truth be told its not a router in the typical sense. If you are interested in how to create a true router that uses a dynamic routing protocol to communicate with other routers of any kind about the networks that are connected to the PiRouter, check out the blog post for OSPF on the Pi – coming soon!