Internship Report

Hello,

I’m writing this to announce the end of internship and a hiatus of the project I’ve been working on. I’ve been asked by my team to start working on another projects and that is why I am putting a pause on this for now until further notice. However, I will come back and finish it when I can.

Here’s a short summary of what I did for the summer:

My first task was to find a way to cross compile docker for OpenWRT. This was a pretty tough challenge because a lot of people had tried but none had succeeded. What also made it even more difficult was the fact that I had never cross compiled anything before, so I wasn’t too familiar with it other than as a concept. So, I spent a few weeks learning how the GNF-Demo works and how to cross compile for OpenWRT and other compilation resources while at the same time also fixing some GNF-Demo bugs and writing a tutorial on how to properly use it. I learned a lot of stuff about OpenWRT and compiling in general but I also realized that this task would take far too long to complete with the things I already know since I would also have to cross compile every dependency that OpenWRT doesn’t support as well. Thus, I started the cross compilation and realized how tedious and boring it was and not too mention extremely time consuming. That is why I asked if there was another way to get GNF-Demo to work with containers and Levi suggested to use a Raspberry Pi router instead called the Banana Pi R1, which I was totally on board with.

That device however was a router from scratch, which meant I had to configure everything on it to get it to work. I was fairly familiar with routers before so I thought it would be a pretty simple task, but it turned out there were a lot of driver issues with the WIFI module and it took a lot of effort to fix. I even had to switch the OS to Armbian to check if its driver modules would work but they didn’t. After a lot of trial and error I managed to get it working on Kernel 3.4.113, but I needed kernel 4+ to have it support docker, which when I upgraded into, suddenly the driver stopped working again. However this time I found a patched module online that fixed some of the driver’s issues and finally got it working again. At the same time, I was also working on the docker support for GNF-Demo and wrote the code for it which I have pushed on Github on branch, learning how OVS works in case it is needed and writing a detailed guide on how to setup BPI R1.

Finally, I got some measurements both on Kernel 3.4.113 and Kernel 4.4.66 which turned out to be almost identical so I didn’t need to update my measurements. My last task was to get the GNF-Demo with docker to actually work but I got a very strange error while trying to do that. After trying to fix the error, I got asked by Levi and Richard to stop working on it and instead work on a new project of theirs, so I decided to put a pause on it. Thus, how my official internship ends, it was a very fruitful experience where I learned more than probably ever have done before, I learned a ton about OpenWRT, OVS, docker, cross compiling, Raspberry PIs and in general gained a lot of experience in networking and routers. Therefore, I’m still very keen on working with Netlab and maybe in the future pick this project up again. For now thought, I put this project on hiatus to work on a new one.

Thank you very much for reading.

Setting up the GNF-Demo on BPI-R1

(In Progress)

OS: Bananian 15.04

Kernel: 4.4.66-Bananian

Step 1: Install docker for debian following this tutorial for Jessie and Armhf architecture. Make sure the date and time is correct otherwise you might encounter errors.

Step 2: Git clone our repository ‘git clone https://github.com/UofG-netlab/gnf-demo.git‘, cd in gnf-demo and ‘rm -r openwrt/’ which contains an Openwrt image which we don’t need. Move the contents of agent/ in /root/ using ‘mv agent/* /root/’.

Step 3: Copy the gnfagent to /etc/init.d/ using ‘cp /root/gnfagent /etc/init.d/’. This makes the script run everytime the router boots.

Step 4: Install the WpaCtrl dependency using ‘git clone https://github.com/rbrunt/Pi_wps.git‘ and then ‘Pi_wps/depends/python-wpactrl/make install’

Banana Pi R1/Lamobo R1 Setup Tutorial

Note: Format needs to be fixed

Hello,

This is a tutorial on how to setup BPI R1 as an access point router using isc-dhcp-server and hostapd. This tutorial uses the default RTL8291CU driver module which despite its flaws seems to be working fine with a bit of tweaking. This tutorial will also give a bit more context for each step to help you understand how things work in a bit more detail. I’m in no way a networking expert, I’m still learning so for any errors I make, feedback is very much appreciated.

To start with the very basics, the first thing we need is a Class 10 microSD card to burn the Bananian image on. The image can be found here. To burn it we will be using dd, with the command ‘sudo dd if=[directory of img]/bananian-1604.img of=/dev/[sdcard] bs=1M && sync’ which will take around 5-10 minutes. If you don’t know the name of your sd card, use ‘sudo fdisk -l’ to find out. If the sd card is not empty, use GParted or something similar to format it before burning the img onto it.

After having the img burned, we need to setup Bananian properly. First we need to find its IP and ssh into it. To find the IP we can either get into the BPI with a keyboard and an HDMI screen and use ‘ifconfig’ or use ‘sudo nmap -sP 192.168.1.1/24’ or w/e the subnet of your network is. After we get the IP, we can use ‘ssh [IP of the BPI] -l root’ with the password pi, to get into the BPI. After getting inside, we first need to use ‘apt-get update’ and ‘apt-get upgrade’ and install all the necessary software ‘apt-get install bridge-utils isc-dhcp-server hostapd hostapd-rtl’. The dhcp server isn’t setup yet, so an error will appear but do not worry.

After that, we will need to setup the network interfaces. The BPI has 2 physical interfaces, eth0 and wlan0. However, to use it as a router we will need to create 2 virtual interfaces that correspond to the LAN and WAN ports and a bridge that connects the LAN ports with the wifi interface. In order to do that we will need to change some config files, starting with swconfig. Swconfig is a config file that sets up the vlans, the virtual interfaces of eth0. The reason it is not inside the interfaces config is for modularity and clarity so we can separate the two functions. The file will need to be created at ‘/etc/network/if-pre-up.d/swconfig’ and needs to contain:

#!/bin/sh

#—————————#
# BPI-R1 VLAN configuration #
#—————————#
#
# This will create the following ethernet ports:
# – eth0.101 = WAN (single port)
# – eth0.102 = LAN (4 port switch)
#
# You have to adjust your /etc/network/interfaces
#
# Comment out the next line to enable the VLAN configuration:
#exit 0

ifconfig eth0 up

# The swconfig port number are:
# |2|1|0|4| |3|
# (looking at front of ports)

swconfig dev eth0 set reset 1
swconfig dev eth0 set enable_vlan 1
swconfig dev eth0 vlan 101 set ports ‘3 8t’
swconfig dev eth0 vlan 102 set ports ‘4 0 1 2 8t’
swconfig dev eth0 set apply 1

If the file already exists, you only need to comment out the ‘exit 0’ line. If it doesn’t, run the following command that makes the file executable:

chmod 755 /etc/network/if-pre-up.d/swconfig

After that, we need to edit the interfaces file which is located in ‘/etc/network/interfaces’. It will need to contain:

auto lo
iface lo inet loopback

auto eth0.101
iface eth0.101 inet dhcp

auto eth0.102
iface eth0.102 inet manual

auto wlan0
iface wlan0 inet manual

auto br0
iface br0 inet static
bridge_ports eth0.102 wlan0
bridge_waitport 0
address 192.168.9.1
network 192.168.9.0
netmask 255.255.255.0

This will create the virtual interfaces, eth0.101 which corresponds to the WAN port and will get its IP from router or your ISP with dhcp, eth0.102 which corresponds to the LAN ports and br0 which is a bridge that connects wlan0 and eth0.102 and has its own static IP. Be careful though, because the address and network need to not be in use by any other network. So, if 192.168.9.0 is being used, choose something else. This will also be the subnet that devices that connect to your new router will get their IP from.

Then, we will need to setup the DHCP server that will decide  how each device gets its IP. First, we need to  deprecate the previous DHCP config file with ‘mv /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.old’. The we need to make a new dhcpd.conf file that contains the following:

ddns-update-style none;
option domain-name-servers 8.8.8.8, 8.8.4.4;

default-lease-time 600;
max-lease-time 7200;
authoritative;
log-facility local7;

subnet 192.168.9.0 netmask 255.255.255.0 {
range 192.168.9.100 192.168.9.200;
option routers 192.168.9.1;
}

If the BPI is used as an access point, you will need to add the gateway IP of your main router in the domain servers option, so it can use its DNS to get an IP from it. If 192.168.1.1 is your gateway, then:

option domain-name-servers 8.8.8.8, 8.8.4.4, 192.168.1.1;

Now to setup hostapd, we need to again edit its config file which is located at ‘/etc/hostapd/hostapd.conf’. It will need to contain:

ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
macaddr_acl=0
auth_algs=3
ignore_broadcast_ssid=0

# 802.11n related stuff
ieee80211n=1
noscan=1
ht_capab=[HT40+][SHORT-GI-20][SHORT-GI-40]

#WPA2 settings
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

# Most modern wireless drivers in the kernel need driver=nl80211
#driver=nl80211
driver=rtl871xdrv
max_num_sta=8
beacon_int=100
wme_enabled=1
wpa_group_rekey=86400
device_name=RTL8192CU
manufacturer=Realtek

# set proper interface
interface=wlan0
bridge=br0
hw_mode=g
# best channels are 1 6 11 14 (scan networks first to find which slot is free)
channel=6
# this is the network name
ssid=ExampleSSID

wpa_passphrase=ExamplePassphrase

Change the  ssid and wpa_passphrase parameters to what you want. After that, reboot!

Finally, we need setup the IPtables rules and IP forwarding. For the IP forwarding, uncomment ‘#net.ipv4.ip_forward=1’ from ‘/etc/sysctl.conf‘. For the IPtables, run the following commands:

iptables -A INPUT -i br0 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 192.168.9.0/24 -i br0 -j ACCEPT
iptables -A FORWARD -d 192.168.9.0/24 -i eth0.101 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0.101 -j MASQUERADE
iptables -P INPUT DROP
iptables -P FORWARD DROP

To save your IP table rules for every restart, run these commands:

cat < /etc/network/if-pre-up.d/iptables
#!/bin/sh
iptables-restore --counters /etc/iptables/rules.v4

Now restart, and congrats! You now have a working router/access point!

However, this will not work if you are using the mainline kernel. This is because the wifi driver module doesn’t work correctly for the new kernel. In order to fix this we need to install a patched module. The module that I tested and found out that it’s working is this one. Follow the instructions in the README.md on how to install it. It was tested on kernel 4.4.66-Bananian.

GNF-Demo Tutorial

This tutorial is focused on how to use the GNF-Demo at its current version with a setup of a server running the UI, a normal TP-Link WDR3600 router with the default OEM and a router of the same model which includes the network functions and we will call AP. First we connect the normal router to the internet with an ethernet cable which is the orange cable in the picture below. Then connect another cable from the ethernet port of the router to the internet port of the AP.

Afterwards, connect the computer/server to the main router and change its IP to anything that doesn’t start with 192.168.0/1, for example we used 192.168.2.200, reserve the IP for the server and the AP in a similar fashion, we used 192.168.2.160 and 192.168.2.102. After that, using scp copy the agent files to the AP on the ~ directory, open agent.py, change the server IP variable to the one you have reserved above (192.168.2.160) and restart the network functionality with ‘/etc/init.d/network restart’.

Finally for the server UI, the packages that are needed are npm and bower. Assuming the system already has npm, to install bower use ‘npm install -g bower’ with super user privileges if needed. If the system is Ubuntu, ‘sudo ln -s /usr/bin/nodejs /usr/bin/node’ might also be needed to make a system link between the nodejs and node directories (which is the same for Ubuntu for some reason). After having both bower and npm installed, go to the GNF-Demo/server directory and run ‘npm install’ to install the node dependencies and then cd to the public/ directory and run ‘bower install’ to install the bower dependencies. After all the dependencies have been installed, go back to the server directory and run ‘npm start’, then go to 127.0.0.1:8080 in a browser and the UI will be there.

Flashing OpenWRT on the WDR3600 router

This tutorial is focused on flashing the custom demo OpenWRT image on the TP Link – WDR3600 N600 router which already has a version of OpenWRT.

The way I did it is by logging into the router using ssh. First, I connected to the router using Wifi and I found the gateway IP address of the router using ‘route -n’ which was 192.168.1.1, then using ‘ssh root@192.168.1.1’ to login the router as root. Then I checked how much empty space the tmp directory(RAM) of router has using ‘free’ which fortunately was 90 MB that was enough to flash the new image. Then I transferred the image to the router from my host system using ‘scp [image location] root@192.168.1.1:/tmp/. If needed, I could use wget instead to download the image file. Finally, since my system supported it, I used mtd to write the firmware on the router with the command ‘mtd -r write [location of the image file in the router] firmware’. After rebooting and waiting for a few minutes, I had a new working version of OpenWRT on my router.

The resources I used were mostly from the wiki pages of OpenWRT.