Yesterday I made my Raspberry Pi function as a router! It took me a long time, mostly because I was using my own custom compiled kernel (don’t worry, you don’t have to do that). There’s probably already enough blogs on the subject, but I thought I’d make one, too!
- Raspberry pi (duh)
For Ethernet routing:
- An ethernet switch
- IPTables – This comes with the stock raspberry pi kernel, so you shouldn’t have a problem if you’re not using your own like I do
- udhcpd, if you want clients to get addresses over dhcp
For wireless routing
The above, plus:
- haveged may be required to generate entropy if wireless is being very slow
- A supported wireless adapter (I have RT5372). this post lists what you can use (and is another decent tutorial). What you need is an adapter that can do access point mode. You can
apt-get install iwthen
iw listand look for ‘AP’ in ‘Supported interface modes’ to determine if your adapter supports it.
If you have a custom kernel like I do, now is probably the time to re-compile it if it doesn’t already come with what you need. If not, skip this paragraph and the next. Your kernel needs IP tables and drivers for your wireless card, if doing wireless routing. I spent a lot of time finding the right options, and don’t want anybody else to go through the same pain, so I’m providing my kernel compliation .config file. Note that you’ll probably need to build on top of it to get the right drivers if doing wifi and not using the RT5372 chipset.
The most important options for IP tables if compiling are the *_NF_*, *IPV4*, *NET* and *INET* options I have selected in my config. If you want to do it on your own, make sure at least networking, network filtering, IP tables, IPV4 connection tracking, conntrack, and IPV4 NAT are enabled. In the GUI tool for the config you can go to edit->find to find what you need and it gives you some information of where the option is and what it requires. Note that some options require others to be selected before they even show in the configuration tool which is really annoying.
If you’re doing wireless routing, the first thing to do is to make sure your wifi is working – is it showing wlan0 in
ifconfig -a? Does
sudo iw dev wlan0 scan bring back a list of wireless networks? Does connecting to one work? If yes, good. If not, look at dmesg and try to find out what’s wrong. For example, I needed the firmware-ralink package to get my card to work.
Now that IP tables and your wireless card are working, you can set up the router!
You need to run the following as root.
First let’s give ourselves an IP address that we will use on our NAT:
ip link set up dev eth0:1 ip addr add 192.168.4.1/24 dev eth0:1 # You can change the IP address here
Make sure packet forwarding is enabled:
Set up forwarding:
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -A FORWARD -i eth0:1 -o eth0 -j ACCEPT iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Now, if you connect another device on the network and give it a 192.168.4.* address, setting 192.168.4.1 as the gateway, you should have Internet access routed to it!
If it’s working, and you want to make your changes permanent, edit
# Internet from the wall, DHCP auto eth0 allow-hotplug eth0 iface eth0 inet dhcp # Static IP address for your pi router auto eth0:1 iface eth0 inet static address 192.168.4.1 netmask 255.255.255.0 gateway 192.168.4.1
/etc/sysctl.d/30-ipforward.conf to permanently allow IP forwarding:
net.ipv4.ip_forward=1 net.ipv6.conf.default.forwarding=1 net.ipv6.conf.all.forwarding=1
Save IP tables rules:
iptables-save > /etc/iptables/rules
exit 0 you can add this:
/sbin/iptables-restore < /etc/iptables/rules
And your rules will be restored on boot.
Make sure hostapd is installed. Edit
/etc/hostapd/hostapd.conf, change options as appropriate:
### Wireless network name ### interface=wlan0 ## This is required ## country_code=UK ssid=NSA-Central-Mainframe hw_mode=g channel=6 wpa=2 wpa_passphrase=YourAwesomePassword42 ## Key management algorithms ## wpa_key_mgmt=WPA-PSK ## Set cipher suites (encryption algorithms) ## ## TKIP = Temporal Key Integrity Protocol ## CCMP = AES in Counter mode with CBC-MAC wpa_pairwise=TKIP rsn_pairwise=CCMP ## Shared Key Authentication ## auth_algs=3 ## Accept all MAC address ### macaddr_acl=0 ## Most cards work with this ## driver=nl80211
Now, similar to before with ethernet routing:
ip link set up dev wlan0 ip addr add 192.168.123.100/24 dev wlan0 # You can change the IP address here
If you ran the iptables commands for ethernet forwarding before, you can run only the second command here:
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo hostapd /etc/hostapd/hostapd.conf will start hostapd up without errors. If so, you can edit
/etc/default/hostapd and set
DAEMON_CONF="/etc/hostapd/hostapd.conf" if you want it to start automatically.
You should be able to see a wireless network with the name you gave above. Connect a client to the wireless network – if you’ve installed the dhcp server it should automatically get an address but if not give it a 192.168.123.* address and set 192.168.123.100 as the gateway. Hopefully you have internet access!!!
If you want the changes to be permanent, see the wired NAT guide above and make the appropriate changes.
As you might imagine, not too impressive. The raspberry pi ethernet port is backed via usb, and my usb wireless adapter isn’t fast enough for wireless routing. For me, wired routing works pretty well – I don’t see a difference between using my raspberry pi as a router and connecting directly to the wall but note that I only have a 10mbps speed anyway. However, wireless routing although it works ‘hangs’ and becomes slow when transferring any non-trivial amount of data, such as downloading files. Still an interesting experiment to try though!