Raspberry pi as a home router part 2: Basic routing

Introduction

In the previous article we turned TP-LINK router into VLAN-enhanced switch to support our “router on a stick” configuration. In this article we will configure basic routing and services needed to get working internet connection for your LAN devices. In this tutorial we will be using Raspberry PI version B (the one with fast ethernet port) and Raspbian linux – one of the most popular RPI linux distributions based on Debian.

Configuring VLAN interfaces

First we need to install proper kernel modules that add VLAN functionality. We will be issuing all commands as root.

apt-get install vlan

We need to make sure that the modules are loaded on system startup.

echo 8021q >> /etc/modules

Reboot your raspberry pi. If you don’t want to reboot it you can load it manually by typing:

modprobe 8021q

Next, it’s time to create VLAN subinterfaces. We could accomplish that by using vconfig utility but we want our configuration to persist through reboot so we will be editing proper configuration files. Interface eth0 will capture and transmit untagged frames. On the other hand interfaces eth0.N will work with tagged frames belonging to VLAN number N. Since we have chosen to tag both VLAN 1 and VLAN 2 on the trunk link in the previous part of the tutorial , we will create proper configuration for this scenario. I’ll just paste my configuration file. The file responsible for basic network configuration in Debian-like systems is /etc/network/interfaces:

auto lo eth0.1 eth0.2
allow-hotplug eth0
iface lo inet loopback

iface eth0.1 inet static
 address 192.168.33.1
 netmask 255.255.255.0
iface eth0.2 inet dhcp

The first line is very important. According to the debian documentation auto keyword means that the interface will start with the system. In my understanding if you skipped this you would have to start the interface manually each time using ifconfig eth0.1 up command. This is not the case. If you don’t include this line the interface will not even be created at startup so it is mandatory. allow-hotplug should bring the interface up when cable is plugged in if I understand it correctly but it’s still not working for me. This is minor flaw and I will think about fixing it later. You can reboot and check if the settings are applied.

WAN side

You should get your ip address from ISP automatically with the above settings. You can also configure it statically if your ISP gave you static IP address.

DNS servers addresses will be save automatically to the /etc/resolv.conf file.

LAN side – DHCP server

Devices in your LAN will be getting addresses from the DHCP server on your router. This is not mandatory – you can configure all of them statically, however I recommend setting up DHCP server because it is very easy. First install it:

apt-get install isc-dhcp-server

I also recommend installing a tool that will help you to easily manage which daemons will be started automatically at boot time:

apt-get install chkconfig

DHCP server configuration file is in /etc/dhcp/dhcpd.conf. You just have to add additional section at the bottom specifying the settings for your LAN subnet:

subnet 192.168.33.0 netmask 255.255.255.0 {
range 192.168.33.100 192.168.33.200;
option routers 192.168.33.1;
default-lease-time 86400;
max-lease-time 604800;
option domain-name-servers 8.8.8.8, 8.8.4.4;
}

range value defines addresses range that can be assigned dynamically

routers value is the default gateway

default-lease-time and max-lease-time – when a client requests the ip address, it is given to it only for a limited amount of time called the lease time. Default-lease-time is given when the client doesn’t ask for specific lease time. Max-lease-time is a maximum client can get.

domain-name-servers are addresses of DNS servers

You can add reservation for a client. This way that client will always get the same IP address from DHCP. The clients are recognized based on MAC address. Example:

host my_pc { hardware ethernet 01:23:45:67:89:ab ; fixed-address 192.168.33.20;}

Host name (my_pc in this case) is arbitrary and doesn’t have to correspond to any real value. Reservations should be configured outside of range of dynamically assigned addresses. If for some reason you need it to be in the middle of dynamic range you can split the range. For example, if you wanted to assign reservation for address 192.168.33.150 inside range 192.168.33.100-200, you can split the range in two:

range 192.168.33.100 192.168.33.149;
range 192.168.33.151 192.168.33.200;

In order to apply configuration changes you need to restart the DHCP server:

service isc-dhcp-server restart

To make sure that it is always started after reboot enter:

chkconfig isc-dhcp-server on

Routing

You don’t need to worry about basic routing. Routes for directly connected networks are automatically added to the routing table. Default gateway is automatically added to routing table by DHCP client based on the information from your ISP. You can display your routing table by issuing command:

route

You only need to enable routing because by default it is disabled. To enable it immediately (it will not persist after reboot):

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

To enable it permanently (reboot required) add or change or uncomment the following line in /etc/sysctl.conf:

net.ipv4.ip_forward=1

Network Address Translation

You need NAT so that multiple machines behind your router can use a single global IP address that ISP gives you. To enable NAT enter:

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

If you want to forward a port (for example port 80 on 192.168.33.138 internal address) to the server inside your LAN enter:

iptables -t nat -A PREROUTING -i eth0.2 -p tcp --dport 80 -j DNAT --to-destination 192.168.33.138:80

The changes will not persist through reboot. First, save the rules to the file:

iptables-save > /etc/iptables

Then you need to make sure those rules are applied when the system starts. A good place for that is to create a script inside /etc/network/if-pre-up.d directory. All scripts inside that directory are executed when the interface is brought up.

vi /etc/network/if-pre-up.d/iptables

Paste the following content:

#!/bin/bash

iptables-restore < /etc/iptables

exit 0

Then make sure it is executable:

chmod +x /etc/network/if-pre-up.d/iptables

You can display the contents of your iptables NAT table by typing:

iptables -L -t nat

Iptables is quite powerful linux firewall and it has much more features. I will make an article about them sometime later.

Summary

This should get your Raspberry Pi router up and running really fast but with basic functionalities (similar to the features of cheap 20$ routers). I will be covering more advanced topis later. It is very possible that I forgot something or I made a mistake. If so, please let me know down below in comments section.

Raspberry pi as a home router part 1: VLANs on TP-LINK TL-WR740N

Introduction

I was previously using TP-LINK TL-WR740N v4 as my home router/switch/AP. It is cheap (about 25$) and does not provide too much features but it certainly works well and is enough for an average home user. I needed something that I could play with a lot more, something that could give me more control over my internet connection, provide logging capabilites, advanced routing, firewall, qos and security enhancements. All I really needed for this is just a linux box. There are readily available open source applications that could provide me with all these features. Of course it’s not plug-and-play solution and it needs a lot of insight and tinkering but that’s just the fun part for me.

Hardware

What I needed was a small, not-power-hungry, quiet and cheap linux server. It should preferably have 2 ethernet ports and built-in wifi (or at least pci or usb ports so I could plug additional interface cards). I considered mini-ITX mainboard based server as it would give me most flexibility and even possibility to run virtualization on x86 CPU with support for hardware virtualization and 2 HDDs for RAID 1. I didn’t go for it because I didn’t want to spend so much money plus it would most likely be actively cooled which would generate noise. Then my eyes turned to Raspberry Pi, which is a very cheap and small ARM-based computer. The main caveat of it is that it only has one FastEthernet port which makes it not very suitable for a router. You can add additional ethernet port as an USB adapter (or wifi adapter). However, I didn’t like the idea to add two USB adapters to have a complete router with AP. I also found more expensive alternative of Raspberry Pi called Utilite which would be just perfect as it has 2 x GbE ports plus Wifi built-in, but again the cost was much higher (plus shipping costs from Israel). That’s why I decided to work with what I have creating low-cost solution.

Architecture

The idea is to use TP-Link TL-WR740N as a switch and access point and Raspberry Pi as router. To accomplish that with only one FastEthernet port I would need VLAN support on the switch to deploy something called “router on a stick”.

 

 

 

VLANs allow you to create logically separated layer 2 networks. Without VLANs all ports on the switch belong to one logical network and frames sent from one port can freely travel to any other port. However if you put ports in separate VLANs then traffic from one VLAN can’t go to another VLAN without a router.

Cable modem connects you to the provider (it could as well be ADSL modem or radio antenna) and forwards L2 frames to the VLAN 2 (the numbers are arbitrary). If your modem already has a router built in then you can still use this topology but you will most likely have to double NAT. Frames which are untagged simply do not carry VLAN information within them. The switch recognizes which VLAN they belong to because the port is statically configured to be a member of specific VLAN. Switch port that has raspberry PI connected is a member of two VLANs (it is also called trunk port). Frames transmitted across this interface are tagged which means they contain VLAN infromation. That way router and the switch are able to tell which VLAN the frame belongs to.

When you receive a packet from the internet it travels through the modem, VLAN2 port, comes into raspberry PI via trunk port, RPI deals with routing, NAT and other functions that you implement, comes out of the same port (but this time via VLAN 1) and is forwarded to the PC or WiFi client which also belong to the VLAN1. Please note that the traffic needs to pass the trunk interface twice (once in inbound direction and once in outbound direction). This has performance implications. You can think of it as the half-duplex port even though it’s full-duplex port physically. When you download something from the internet with 100Mbps speed (the speed of RPI and TP-LINK WR740N ports) you can do this but it will also take up “upload” of the port. In other words your upload+download speed is capped at 100Mbps but I don’t think it’s the problem for most home users.

Switch configuration

Installation

Note that there is no Web interface by default for TP-LINK WR740N openwrt images.

http://wiki.openwrt.org/doc/howto/generic.flashing gives you a generic explanation of the installation process. You will not need most of the information given there. Let me walk you through the installation:

1. Identify your exact model (there are versions 1,2,3 and 4). http://wiki.openwrt.org/toh/tp-link/tl-wr740n can give you some useful information. Please note that there is “debricking” section in case something goes wrong. I did not need to do this but if you lose connectivity to your router you can find out how to get it back online in this section.

2. Download firmware from http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/

I used http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/openwrt-ar71xx-generic-tl-wr740n-v4-squashfs-factory.bin

There are “JFFS2” and “squasfs” versions. I am not sure what is the difference. Squashfs is recommended. “Factory” is for installing openwrt on router with factory image and “sysupgrade” is for upgrading.

3. Reset TP-LINK to factory defaults.

4. Use Firmware Upgrade function and select image of OpenWrt.

5. After the router reboots telnet to the address 192.168.1.1. There is no password.

6. Use command “passwd”. It will prompt you to choose your root password. After you choose it telnet will be disabled and SSH will be enabled. Type “exit”.

7. Log in with your chosen password on “root” account using SSH. You can now configure your OpenWrt device.

 

Network configuration

All the interesting configuration is in the directory /etc/config.

Network configuration is stored in /etc/config/network. Let’s view the defaults.

config interface 'loopback'
 option ifname 'lo'
 option proto 'static'
 option ipaddr '127.0.0.1'
 option netmask '255.0.0.0'

config globals 'globals'
 option ula_prefix 'fd9c:6323:7240::/48'

config interface 'lan'
 option ifname 'eth0'
 option type 'bridge'
 option proto 'static'
 option ipaddr '192.168.1.1'
 option netmask '255.255.255.0'
 option ip6assign '60'

config interface 'wan'
 option ifname 'eth1'
 option proto 'dhcp'

config interface 'wan6'
 option ifname '@wan'
 option proto 'dhcpv6'

config switch
 option name 'switch0'
 option reset '1'
 option enable_vlan '1'

config switch_vlan
 option device 'switch0'
 option vlan '1'
 option ports '0 1 2 3 4'
  •  config interface ‘lan’ s section is pretty straifghtforward. You can set ip address and netmask of lan interface of your TP-LINK router.
  • config switch section is misleading. I would expect that you need to enable additional VLANs here but this is not the case. You don’t need to do anything here. I don’t know what it’s for.
  • config switch_vlan

This is where you’ll be configuring VLAN settings. If you need to add additional VLAN just add another config switch_vlan section (identical section name). Leave the option device ‘switch0’ as is. Specify which VLAN you want to configure in option vlan.

Option ports is a list of physical and logical ports that are members of the VLAN. If you use number alone like 1,2,3 and so on it means that the VLAN will be untagged on that port (of course you can have only one untagged VLAN on port). If you append letter “t” to the number it will tag the frames of that VLAN on that port.

Port numbering

 0 – logical port that connects the switch to the CPU of the device. You will only need to add VLAN to this interface when you need to manage the device using IP from that VLAN or if you want it to provide services like DHCP or DNS on that VLAN. We will add VLAN 1 (which coressponds to LAN) to the port 0 untagged.

1,2,3,4 – physical ports

Please note the numbering is not in order!

If you are unsure which ports are you configuring or you find this information incorrect you can display which ports are currently up/down by issuing command:

swconfig dev switch0 show

This is the configuration that I use:

config interface 'loopback'
option ifname 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'

config globals 'globals'
option ula_prefix 'fd9c:6323:7240::/48'

config interface 'lan'
option ifname 'eth0'
option type 'bridge'
option proto 'static'
option ipaddr '192.168.33.254'
option netmask '255.255.255.0'
option ip6assign '60'

config interface 'wan'
option ifname 'eth1'
option proto 'dhcp'

config interface 'wan6'
option ifname '@wan'
option proto 'dhcpv6'

config switch
option name 'switch0'
option reset '1'
option enable_vlan '1'

config switch_vlan
option device 'switch0'
option vlan '1'
option ports '0 1 3t 4'

config switch_vlan
option device 'switch0'
option vlan '2'
option ports '2 3t'

As you can see port 3 is being being used as trunk and will be connected to RPI. Port 2 will be connected to WAN and port 1 and 4 will be LAN ports. I will not be using eth1 which is normally WAN port when using stock firmware.

Optional

If you want to create multiple IP interfaces (one for each VLAN) you can just add another config interface section and specify ifname as eth0.N where N is VLAN number. Example:

config interface 'lan2'
option ifname 'eth0.2'
option type 'bridge'
option proto 'static'
option ipaddr '192.168.2.1'
option netmask '255.255.255.0'

Don’t forget to add tagged VLAN to the port 0!

Wireless

Wifi is disabled by default on openwrt. The relevant configuration file is /etc/config/wireless. In order to enable the wireless you need to set option disabled to 0 (or remove the line).

The most popular,secure and completely sufficient configuration for home users is just WPA2-encrypted connection using pre-shared key.

Sample configuration is here:

config wifi-device radio0
 option type mac80211
 option channel 1
 option hwmode 11ng
 option path 'platform/ar933x_wmac'
 option htmode HT20
 list ht_capab SHORT-GI-20
 list ht_capab SHORT-GI-40
 list ht_capab RX-STBC1
 list ht_capab DSSS_CCK-40
 # REMOVE THIS LINE TO ENABLE WIFI:
 option disabled 0

config wifi-iface
 option device radio0
 option network lan
 option mode ap
 option ssid your_ssid_here
 option encryption psk2
 option key your_password_here

Disable unnecessary services

RPI will provide DHCP and DNS services for our network. You certainly do not want two DHCP servers running concurrently in your LAN. Daemon which is responsible for both of these functions is called dnsmasq. To prevent it from starting automatically after reboot type:

/etc/init.d/dnsmasq disable

Apply settings

After all configuration changes you can just reboot your router and hope you do not cut yourself out of management:

reboot

Final words

This was first part of the tutorial. I will add routing part which is more interesting soon!