Saturday, August 11, 2012

Raspberry Pi as a Router

Raspberry Pis have started making there way into homes all across the world. When I got mine, the first thing I wanted to do was set it up as a router to replace my aging piece of D-link garbage.


This guide is somewhat geared towards those new to Linux so experienced users can feel free to skip around a bit and modify some of my commands.

The first step is to download and install Raspbian onto your SD card. You could just as easily use Debian, but Raspbian is preferred because it's optimized for the Pi. I'm using the Darkbasic minimal image because there's really no use for a GUI on a router and it would just hog resources but you can decide what flavor you like best.

I won't tell you how to install Raspbian because there's plenty of guides on the Raspbian site that explain it way better than I ever could.

From my experience, the Raspbian images you can download contain older versions of the Raspberry Pi firmware which is a problem because the kernel is not compiled with iptables support. Hexxeh to the rescue! The easiest way to install the new firmware is to use Hexxeh's rpi-updater which is available here with instructions as to how to install it. Remember to install ca-certificates before you wget the updater.

sudo apt-get update && sudo apt-get install ca-certificates

If I remember correctly, the script has one more dependency, but it will tell you what it is and it's available in the repositories and you can just apt-get it.

After your firmware has been updated, reboot the pi to activate it.

Here's where the fun begins, but first a bit of logic regarding my setup. As is shown in my video, the on-board NIC of the pi (eth0) is connected to the internet via my cable modem. My USB-NIC (eth1) is connected to my internal network, specifically in my case a wireless access point, but you could just as easily connect a switch if you need more wired ports.

As you can see in the video, I am using an apple branded USB-NIC because it's what I had lying around, but this is not a necessity. Debian has good support for lots of USB-NICs and in most cases they'll be recognized when you plug them in without any additional configuration.

The first step is to edit /etc/network/interfaces.

sudo nano /etc/network/interfaces

We want the internet facing NIC to get an address from our ISP via DHCP and our internal NIC to have a static address. I am using 192.168.50.0/24 as my internal subnet but you can use any subnet you like as long as it is RFC 1918 compliant. Keep in mind a /24 (255 addresses) is most always big enough for a home network.

Here is what my /etc/network/interfaces file looks like. If you decide to change the internal subnet, you'll need to edit my addresses to suit your setup.

# interfaces(5) file used by ifup(8) and ifdown(8)

auto lo
iface lo inet loopback

#Onboard NIC connecting to the Internet
auto eth0
iface eth0 inet dhcp

#USB NIC serving as internal gateway
auto eth1
iface eth1 inet static
address 192.168.50.1
netmask 255.255.255.0
network 192.168.50.0
broadcast 192.168.50.255
gateway 192.168.50.1
Save the file and restart networking (or reboot).

sudo /etc/init.d/networking restart

Next we need to install the DHCP server package on our Pi so we can allocate addresses to clients.

sudo apt-get install isc-dhcp-server

Now let's edit the DHCP server configuration file.

sudo nano /etc/dhcp/dhcpd.conf

The configuration files provides a lot of examples that are all commented out. Feel free to read them if you care to. Since this should be the only DHCP server on our network, let's make it authoritative. Uncomment out the authoratative line near the top of the file.

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

Next, lets add a new subnet. Scroll down to the bottom of the file and add something like this:

subnet 192.168.50.0 netmask 255.255.255.0 {
range 192.168.50.10 192.168.50.250;
option broadcast-address 192.168.50.255;
option routers 192.168.50.1;
default-lease-time 600;
max-lease-time 7200;
option domain-name "local";
option domain-name-servers 8.8.8.8, 8.8.4.4;
}

Again, this is assuming a 192.168.50.0/24 subnet. You'll need to change it if you've chosen a different subnet.

You'll also notice I'm using the Google public DNS servers, 8.8.8.8 and 8.8.4.4. If you prefer to use the DNS servers provided by your ISP, you'll need to change this line to reflect their addresses.

Save the file and restart the DHCP service.
sudo /etc/init.d/isc-dhcp-server restart
You should recieve two ok messages.

[ ok ] Stopping ISC DHCP server: dhcpd.
[ ok ] Starting ISC DHCP server: dhcpd.

If you receive an error about no interfaces being in the proper address space double check your configurations and make sure your static address on eth1 is in the same subnet as your DHCP subnet. if you need to make any changes you'll need to restart the relevant services.

At this point you should be able to plug a device into the USB NIC (eth1) interface of your pi and receive an IP address via dhcp. However, you won't be able to get any further on the network than your Pi itself. To solve this, we need to enable IP forwarding.

Guides I read said I needed to do one or the other of the following things, however, I had to do both. First run the following command:

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

Next edit /etc/sysctl.conf and uncomment out the line that says net.ipv4.ip_forward = 1.

sudo nano /etc/sysctl.conf

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Save the file.

The final step is to insert an iptables rule to allow NAT.

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Time for final testing. Plug a computer into the eth1 interface on your pi and plug the onboard NIC into your modem.

After the negotiation phase, your computer will pull an address and you should be able to access the internet! if it doesn't work, ssh to the Pi by using the address you gave eth1 (192.168.50.1 in my case) and ensure that eth0 has a public address by running ifconfig.

sudo ifconfig -a
eth0      Link encap:Ethernet  HWaddr b8:27:eb:e8:4a:fe  
          inet addr:68.229.57.30  Bcast:68.229.51.255  Mask:255.255.255.0
          inet6 addr: fe80::ba27:ebff:fee8:4afe/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1851717 errors:0 dropped:0 overruns:0 frame:0
          TX packets:680737 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1493496473 (1.3 GiB)  TX bytes:131062180 (124.9 MiB)

eth1      Link encap:Ethernet  HWaddr 40:3c:fc:00:74:b0  
          inet addr:192.168.50.1  Bcast:192.168.50.255  Mask:255.255.255.0
          inet6 addr: fe80::423c:fcff:fe00:74b0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:675292 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1052136 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:116080201 (110.7 MiB)  TX bytes:1474222354 (1.3 GiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:152 (152.0 B)  TX bytes:152 (152.0 B)
If your eth0 still shows a private address it probably didn't renew when you moved it to your modem. Fix this by running:

sudo ifdown eth0 && sudo ifup eth0

Check your IP address by running ifconfig again and see if you can reach the internet. You may need to reboot your modem, however do not reboot your Pi for the reasons that are to follow.

If it's still not working, stop here and go back and make sure you've not missed any steps.

You should not reboot your Pi at this point because the iptables rules for nat we inserted earlier are not persistent and if you reboot they will be overridden by the default configuration (nothing). We can fix this by saving the rules and creating a little script to restore them as the network interfaces come up during boot.

First, save your iptables rules to a file.

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

You don't have to save them to /etc/iptables.up.rules, that's just where I save mine.

Next create a script in /etc/network/if-pre-up.d/ with the following contents:

sudo nano /etc/network/if-pre-up.d/iptables
#!/bin/sh
#This script restores iptables upon reboot

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

exit 0

Change ownership and permissions of the script so it will run at boot.

sudo chown root:root /etc/network/if-pre-up.d/iptables && sudo chmod +x /etc/network/if-pre-up.d/iptables && sudo chmod 755 /etc/network/if-pre-up.d/iptables

Voila. You can now reboot and your iptables rules will stay persistent.

For some additional security, lets add some more iptables rules:

sudo iptables -A INPUT -s 192.168.0.0/24 -i eth0 -j DROP
sudo iptables -A INPUT -s 10.0.0.0/8 -i eth0 -j DROP
sudo iptables -A INPUT -s 172.16.0.0/12 -i eth0 -j DROP
sudo iptables -A INPUT -s 224.0.0.0/4 -i eth0 -j DROP
sudo iptables -A INPUT -s 240.0.0.0/5 -i eth0 -j DROP
sudo iptables -A INPUT -s 127.0.0.0/8 -i eth0 -j DROP
sudo iptables -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j DROP
sudo iptables -A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j DROP

This blocks access from RFC 1918 subnets on your internet (eth0) interface as well as ICMP (ping) packets and ssh connections.

Remember to save whenever you make changes!

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

If you want to see how many packets your firewall is blocking, run this command:

iptables -L -n -v

Chain INPUT (policy ACCEPT 215 packets, 23539 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  eth0   *       192.168.0.0/24       0.0.0.0/0           
  126 34570 DROP       all  --  eth0   *       10.0.0.0/8           0.0.0.0/0           
    0     0 DROP       all  --  eth0   *       172.16.0.0/12        0.0.0.0/0           
    0     0 DROP       all  --  eth0   *       224.0.0.0/4          0.0.0.0/0           
    0     0 DROP       all  --  eth0   *       240.0.0.0/5          0.0.0.0/0           
    0     0 DROP       all  --  eth0   *       127.0.0.0/8          0.0.0.0/0           
    0     0 DROP       tcp  --  eth0   *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
    0     0 DROP       icmp --  eth0   *       0.0.0.0/0            0.0.0.0/0            icmptype 8
    0     0 DROP       all  --  eth0   *       192.168.0.0/24       0.0.0.0/0           

Chain FORWARD (policy ACCEPT 15696 packets, 14M bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 191 packets, 25875 bytes)
 pkts bytes target     prot opt in     out     source               destination  

At this point, you should have a fully functional router that has extremely low power usage and some basic security.

In the future, I plan to add a switch to my network and add some 802.1q trunks to my USB Nic so I can have multiple LANs, but that's a different article.

23 comments:

  1. Looking forward to your post detailing adding vlans

    ReplyDelete
  2. Thanks for the guide! Worked perfectly for me - with slight modifications for connecting the pi to the internet with a 3G modem.

    ReplyDelete
  3. Could be fun to have ipv6 running too. Thanks for the guide!

    ReplyDelete
  4. Does the apple usb-ethernet adapter work in managed / AP mode?

    ReplyDelete
  5. This is almost perfect, but does anyone know how to do this with a USB wifi adaptor?

    J.

    ReplyDelete
  6. When I try to run the command, "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" I get all kids of iptables errors. What does this mean and how to fix this:

    FATAL: Module ip_tables not found.
    iptables v1.4.14: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
    Perhaps iptables or your kernel needs to be upgraded.

    ReplyDelete
    Replies
    1. You probably didn't run it as root. (sudo)

      Delete
  7. I found a bug that perhaps only affects me.

    When I set up everything, DHCP working, all that was fine, but I was unable to ping anything out of my local network.

    I was convinces that the script wasn't working correctly, but I saw that there was a double default "Gateway" One on eth0 (Given by DHCP from the router) and a static on eth1. That led to a double default route, that confused the iptables for routing.

    I deleted the eth1 Gateway Ip address (Using the default one given by the router) and all was well.

    ReplyDelete
    Replies
    1. Same here, thanks for the remark Eric!

      @Qckdrw777: might be useful to others to note this in your article?

      Delete
  8. Hello,
    I came over to get to the ssh
    What to do?

    ReplyDelete
  9. http://askubuntu.com/questions/90314/unable-to-edit-proc-sys-net-ipv4-ip-forward-in-xubuntu refers .I couldn't get the sudo echo 1 > /proc/sys/net/ipv4/ip_forward to work, kept on getting permission denied. So used sudo bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward' instead-sorted!

    ReplyDelete
  10. THANK YOU. Got tired of my Verizon MiFi's substandard wifi range.

    Built this monstrosity. http://twitpic.com/czy0n6

    Still waiting on the 4 port powered usb hub (the Pi cant charge the MiFi), And a 2 watt 12-5 volt adapter I'll savage the guts out of and transplant into the linksys to power everything.

    ReplyDelete
  11. I want to understand how does lan card works can you give me some pointers to information i.e. what should i know microcontrollers or avr or what exactly I am trying to understand each of them

    ReplyDelete
  12. Content that you just created is extremely fascinating and helpful on behalf of me, I love it. Is also helpful for U.S. all.. Thanks

    Read more information :- Brother Printer Technical Support

    ReplyDelete
  13. Really Very Excellent Detail.....Thanks for sharing this information...

    To get How to reset Linksys E1200 Wi-fi N-Router,Please visit the link.

    Thankyou
    Lacy Brown

    ReplyDelete
  14. Thanks for the info my router has turned out well, however i have one slight problem i have a computer on the internal side of the network that i need to access from the WAN side. previously i did this with port forwarding to its specific IP address, how would i do this with this setup? i have looked for info re port forwarding with IP tables online however none of them seamed to work. is this something you can help me with ?

    ReplyDelete
  15. From my experience, you will face many problems because the kernel is compiled with ip tables support. The best way to install the new firmware updater to RPI Hexxeh is available with instructions on how to install here. Do not forget to ca-certificates wget before installing the update.

    Norton Antivirus Support | Mcafee Antivirus Support

    ReplyDelete
  16. Who oh Who can help me.
    Whatever I try , everytime i get the warning( notification)

    failed to bring up eth1

    I use the manual described on this page

    William

    ReplyDelete
  17. The router support is a necessity for everyone and everything, when you need a good network .. Linksys Router is one of the best wireless router ..
    Linksys Router Technical Support

    ReplyDelete
  18. Nice post for Raspberry Pi as a Router. Router is an electronic device that forwards data packets from one network to another. It connects two or more networks, and when a data packet comes in one network it reads the address of it and determines the ultimate destination. I am also working as Guide for Linksys Router Support. Join me on Twitter @sarahts01 .

    ReplyDelete
  19. Thanks for this blog its very helpful for solving router problems. Good work. Please visit this link……. Linksys Router Technical Support .

    ReplyDelete
  20. Thanks for using this blog its very helpful for solving router problems. Good work. Please visit this link……. Linksys Router Technical Support .

    ReplyDelete