Motivation

I created this project in order to help you to take the control on the hardware you use to access the Internet. This is project is meant to be educational.

Nowadays, we are surrounded by connected devices (smartphone, smart-TV, IoT, ...). These devices are really easy to use - plug&play. Some of them are really complex in the inside but simple enough (from the outside) to be used by anyone. These devices are connected to Internet and can gather data about you, your life, your habits, ... But, do you really know what they do with your information?

The goals here are multiple and by creating this small 4G LTE/Wifi router, I will try to help you to:

  • understand how a network works
  • identify the different devices and softwares involved in providing an Internet connection
  • control the hardware you use
  • repair it
  • modify, customize it in order to fit your needs
  • discover what a malevolent person can do if she gains access to your hardware (physically or remotely)

Dive into the project

privacy

Introduction

We will try to build a secure 4G LTE/Wifi router you can bring everywhere with you. This story will tend to explain how to build this router from scratch.

I will take in account these requirements:

  • secure
  • low-power
  • small size
  • cheap

Hardware

To build this small and cheap router, we need:

Description Reference Price Buy
Raspberry Pi Zero Pi Zero v1.3 6€ Buy
USB 2.0 Hub - 3€ Buy
4G LTE USB dongle ZTE MF823 36€ Buy
Wifi USB dongle TL-WN821N 12€ Buy
Serial USB adapter - 2€ Buy
I2C 0.96" OLED screen SSD1306 3€ Buy
Power supply 5V 2.5A micro-A 7€ Buy
USB OTG adapter - 0.5€ Buy

Update on Mar. 11 2018

The total price is around 60€. You can use an old smartphone charger as well but be sure to pick one which delivers 1.5A. The previous list does not take account the stuff you probably already have:

  • a soldering iron
  • a spool of tin-lead soldering flux
  • a piece of desoldering braid
  • a computer running a Linux distribution
  • few small 12cm long wires
  • an old shielded USB cable which will be cut in 12cm long pieces
  • a mini-USB cable to connect the serial adapter to your computer
  • a SIM card
  • a 16GB microSD card

If you want to learn how to solder, have a look to the Sparkfun tutorial.

If you want to learn how to use Linux, have a look to the Linux journey tutorials.

Pi Zero

The Pi Zero will be running Debian to provide:

USB 2.0 hub

Because the Pi Zero offers only one USB port and because we have at least 2 USB dongles to attach, we need a USB 2.0 hub. It is easy to find cheap USB hub on ebay for 3€.

Following peripherals will be attached to the USB hub:

  • the Wifi dongle
  • the LTE dongle
  • a keyboard during the building process

On the Pi Zero, the 5V input voltage delivered by the PSU (a power bank for example) is directly connected to the pin 1 of the USB connector. So, if the PSU is able to deliver around 1A, everything should work well. The Pi Zero does not limit the current drawn by USB devices.

LTE dongle

The 4G LTE dongle we use is manufactured by ZTE. For around 30€, you can get one which is not locked. The dongle is directly recognized as an Ethernet port usb0. A web interface is provided in order to get information about the connection, to enter the pin code, ...

You can find all the specifications of the MF823 on the ZTE website.

Wifi dongle

The Wifi dongle we use is manufactured by TP-Link. You can find it for around 12€. Preliminary tests show that the embedded Wifi controller + antenna of the Pi Zero W and the Raspberry Pi 3 have bad performances. I was not able to get a bandwidth larger than 6Mbps. That is why I choose to base this project on a simple Pi Zero and attach to it the Wifi and 4G LTE dongles.

This Wifi dongle is directly recognized as a WLAN port wlan0.

You can find all the specifications of the TL-WN821N on the TP-Link website

I2C OLED screen

The screen is meant to display details about the status of your router like:

  • IP address
  • connection network
  • VPN state
  • amount of traffic
  • average ping

I choose this tiny 0.96" OLED screen because it costs around 2€. This screen uses the I2C communication protocol and Adafruit offers a python library meant to control a SSD1306 screen which the driver we need.

You can find the SSD1306 specifications on the Olimex website


Install base system

Get Raspbian linux distribution

First of all, you have to download the latest Rasbian Jessie Lite from the Raspberry Pi website.

If you use a Debian based distribution, you can run these commands

cd /tmp
wget https://downloads.raspberrypi.org/raspbian_lite_latest

Check if the archive is the same as the one provided by Raspberry Pi by checking the insecure SHA-1 sum

sha1sum raspbian_lite_latest

and check if the sum computed by your computer is the same as the one specified on the Raspberry Pi download page. If sums are different, the archive has been corrupted or modified.

If sums are the same, unzip it

unzip raspbian_lite_latest

when I write this article, the extracted file is 2017-04-10-raspbian-jessie-lite.img.

Put Raspbian on a SD card

Then plug a microSD card to your computer in order to copy the Raspbian distribution on it. Determine the path to your SD card with fdisk

sudo fdisk -l

and identify your card. For example /dev/sdb in my case.

Finally, copy the image onto the card with dd. Be sure to adapt /dev/sdb to your setup.

sudo dd if=/tmp/2017-04-10-raspbian-jessie-lite.img of=/dev/sdb bs=4M

and wait until the end of the copy.

If you encounter issues during this process, please refer to the Installation guide of Raspberry PI.

Episode 1 - Access the LTE network

Insert the microSD card into the Pi Zero, plug the screen cable, plug the USB hub, plug a keyboard, plug the LTE dongle and power the Pi Zero. Your Raspbian distribution is starting. At the first boot, the system will resize the filesystem and then reboot by itself. After the boot sequence, a prompt will allow you to log in your system. By default the username is pi with the password raspberry.

List network interfaces

Now, you can check if the LTE dongle is recognized by executing this command

ifconfig

if the dongle is recognized, it will be listed as usb0.

Enter the PIN code

Finally, you have to enter your PIN code to unlock the SIM card. The classic way to enter the PIN code is to browse http://192.168.0.1 and fill the form. In your case, you cannot browse this page because a web browser is not available on the system.

To enter your PIN code, simply execute the following command on your Pi Zero. Be sure to adapt the command by replacing XXXX with your PIN code

wget -S --post-data \
     "isTest=false&goformId=ENTER_PIN&PinNumber=XXXX" \
     http://192.168.0.1/goform/goform_set_cmd_process \
      -O /tmp/response

and check the response of the dongle

cat /tmp/response

Is Google reachable?

To check if your Internet connection is working, just ping Google

ping google.com

Episode 2 - Setup a Wifi hotspot

Automatically enter the PIN

As we have seen in the previous step, we are able to unlock the SIM card directly using command lines.

To unlock the SIM card at the boot time of your system, you will create a system service enter_pin meant to execute the command

wget -S --post-data \
     "isTest=false&goformId=ENTER_PIN&PinNumber=XXXX" \
     http://192.168.0.1/goform/goform_set_cmd_process \
      -O /tmp/response

First of all, you have to create a script which will be executed during the boot sequence. This script will reside in the file /home/pi/enter_pin.sh. So create this file with the command

nano /home/pi/enter_pin.sh

and copy/paste this script

#! /bin/sh
sleep 4
wget -S --post-data "isTest=false&goformId=ENTER_PIN&PinNumber=XXXX" http://192.168.0.1/goform/goform_set_cmd_process -O /tmp/response
return 0

This script will wait 4 seconds (wait the LTE dongle to be up) and will send to PIN code. Be sure to replace XXXX with your own PIN code.

Make it executable

chmod +x /home/pi/enter_pin.sh

Secondly, you have to create a systemd service enter_pi.service in the file /etc/systemd/system/enter_pin.service. So, create this file with this command

sudo nano /etc/systemd/system/enter_pin.service

and paste this script into

[Unit]
Description=Enter PIN code
After=network-online.target

[Service]
Type=oneshot

ExecStart=/home/pi/enter_pin.sh

[Install]
WantedBy=default.target

Then, enable this service

sudo systemctl enable enter_pin.service

And finally, start it

sudo systemctl start enter_pin

The LTE dongle should blink in green or blue. Now, you have your Internet connection!

Update your system

First of all, you need to upgrade your system

sudo apt-get update
sudo apt-get dist-upgrade

To keep your system secure, keep in mind that you have to upgrade it frequently and keep an eye on security updates. You can find them on the Debian Security Information and subscribe to the Debian Security Announce mailing list

Install required softwares

To turn your Pi Zero into a Wifi access point, we need the following softwares

  • hostapd will allow you to turn the Wifi dongle into an access point
  • udhcpd will allow you to provide IP addresses by setting up a DHCP server
  • openssl will allow you to generate passwords and will be used in the next steps to secure your connection using encryption
  • iptables-persistent will allow you to save and restore your firewall configuration
sudo apt-get install -y udhcpd hostapd openssl iptables-persistent

Since the configuration is not ready, you have to stop these 2 services

sudo systemctl stop udhcpd
sudo systemctl stop hostapd

Configure the DHCP server

To configure your DHCP server, you need to edit the file /etc/udhcpd.conf.

To edit the file, run the command

sudo nano /etc/udhcpd.conf

Delete the entire content of the existing file and paste the following lines

start           192.168.3.20
end             192.168.3.254

interface       wlan0

remaining       yes

# Sets the DNS to use, here it points to the FDN resolvers
opt     dns     80.67.169.12  80.67.169.40
option  subnet  255.255.255.0
opt     router  192.168.3.1
opt     lease   864000          # 10 days of seconds

Here, we use the DNS resolvers of FDN.

Now, you have to enable your DHCP server by editing the file /etc/default/udhcpd with the command

sudo nano /etc/default/udhcpd

and comment the line

DHCPD_ENABLED="no"

by adding a # at the beginning of the line.

Configure the Wifi hotspot

First of all, we have to check if the Wifi dongle is correctly recognized by your system. To do so, list the network interfaces

ifconfig

you should see wlan0.

Then, you have to configure hostapd. Its configuration resides in the /etc/hostapd/hostapd.conf file. Thus, edit it

sudo nano /etc/hostapd/hostapd.conf

and paste the following lines into it

interface=wlan0
country_code=<put your country code here>
driver=nl80211
ssid=<put your desired Wifi network name (SSID) here>
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=<put your Wifi passphrase here>
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
ieee80211n=1          # 802.11n support
wmm_enabled=1         # QoS support
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]

Be sure to replace:

  • <put your country code here> by your country code. hostapd follows the ISO 3166-1 norm. To find your country code, refer to the ISO 3166-1 norm.
  • <put your desired Wifi network name (SSID) here> by the name you want. It is the public advertised name of your Wifi network.
  • <put your Wifi passphrase here> by a strong pass-phrase. You will have to type this pass-phrase on each device you want to connect to your Wifi network. You can use the following command openssl rand -base64 32 to generate your pass-phrase.

Now, you have to specify the hostapd configuration file in /etc/default/hostapd by editing it with the command

sudo nano /etc/default/hostapd

and append the following line at the bottom of the file

DAEMON_CONF="/etc/hostapd/hostapd.conf"

Configure the Wifi interface

Because you have configured a DHCP server on the network 192.168.3.0/24 with 192.168.3.1 as default gateway for the interface wlan0, you have to assign a static IP address to your wlan0 Wifi interface.

To assign a static IP address to wlan0, edit the file /etc/network/interfaces with the following command

sudo nano /etc/network/interfaces

and replace the wlan0 section by this one

auto wlan0
allow-hotplug wlan0
iface wlan0 inet static
    address 192.168.3.1
    netmask 255.255.255.0

To apply the configuration, you have to restart the network manager with this command

sudo /etc/init.d/networking restart

Share the Internet connection

To share your 4G LTE connection with your Wifi devices, you will route the traffic between wlan0 and usb0. You will use the linux firewall iptables. You will tell the firewall to forward connections from the Wifi to the 4G LTE network and vice-versa.

First of all, you have to enable NAT which is a technique that allows several devices to use a single Internet connection.

So, you will enable IP forwarding in the kernel with this command

sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

and to persist this configuration after reboot, edit the file /etc/sysctl.conf with this command

sudo nano /etc/sysctl.conf

and add this line at the bottom of the file

net.ipv4.ip_forward=1

And to enable the NAT, execute the following commands

sudo iptables \
  -t nat -A POSTROUTING -o usb0 -j MASQUERADE
sudo iptables \
  -A FORWARD -i usb0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables \
  -A FORWARD -i wlan0 -o usb0 -j ACCEPT

Now, you have to save your firewall rules with this command

sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"

and because iptables forgets its rules when you shutdown the system, you will have to reload these rules at the boot time. To do so, edit the file /etc/network/interfaces with the command

sudo nano /etc/network/interfaces

and add the following line at the bottom of the file

up iptables-restore < /etc/iptables.ipv4.nat

The configuration of your hotspot is now complete so you can enable and start appropriated services

sudo update-rc.d hostapd enable
sudo update-rc.d udhcpd enable
sudo service hostapd start
sudo service udhcpd start

Take your smartphone and connect it to your LTE/Wifi router. Normally, your smartphone is connected to the Internet. Try to browse https://esther.codes!

Issues

If the LTE dongle is not available after the boot sequence, it is probably due to the boot time of the dongle itself. The solution is to delay the boot of the Pi Zero. To do so, edit the /boot/config.txt

sudo nano /boot/config.txt

and add the following line at the bottom of the file

boot_delay=15

Episode 3 - Route the traffic through a VPN

In this step we will route the entire traffic of your router through a VPN. The goal here is to keep your traffic far away from the eyes of your ISP. You can read the EFF Surveillance Self-Defense guide to get more information.

Choose your VPN provider

Here is an important, critical task. In fact, using no VPN is better than using a bad VPN! To help you in your quest of a good VPN provider, here is few hints:

Install OpenVPN

OpenVPN is the most common VPN protocol. To install and configure the VPN client on your router, put the different files like keys, configuration, ... on a USB key. Before copying your VPN related files on the USB key, you have to format it securely. This tutorial will show you how to securely wipe your USB key. Then put your VPN related files on the USB key.

Next, install OpenVPN with this command

sudo apt-get install -y openvpn

And copy configuration and key files in the OpenVPN directory (/etc/openvpn/). Be sure to adapt the following commands

sudo mkdir /media/usb-drive/
sudo mount /dev/<your USB key partition> /media/usb-drive
sudo cp -r /media/usb-drive/<openvpn file directory>/* /etc/openvpn/
sudo umount /media/usb-drive/

unplug your USB key and securely swipe it.

Now, you have to enable the OpenVPN service

sudo systemctl enable openvpn@client

NB: in @client, client refers to the name of your configuration file without its extension, here client.conf.

and start it

sudo systemctl start openvpn@client

After few seconds, you will be connected to your VPN.

You can check if your VPN client is happy by checking its state

sudo systemctl status openvpn@client

and see its logs

sudo journalctl -xe | grep ovpn

If your VPN client is not connected or errors occurred, refer to your VPN provider documentation.

Control the network traffic

Here, you have to block all the traffic by default and only accept the relevant one.

First of all, remove all the existing rules

sudo iptables -F
sudo iptables -X
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -t mangle -F
sudo iptables -t mangle -X

Drop all the traffic

sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT DROP

Allow all loopback (lo) traffic

sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT

Allow all loopback traffic to usb0

sudo iptables -A OUTPUT -o usb0 -j ACCEPT
sudo iptables -A INPUT -i usb0 -m state --state ESTABLISHED,RELATED -j ACCEPT

Allow all loopback traffic to tun0

sudo iptables -A INPUT -i tun0 -j ACCEPT
sudo iptables -A OUTPUT -o tun0 -j ACCEPT

Deny the access to the dongle server

sudo iptables -A FORWARD -i wlan0 -d 192.168.0.1 -j DROP

Allow DHCP

sudo iptables  -I INPUT -i wlan0 -p udp --dport 67:68 --sport  67:68 -j ACCEPT

Forward the traffic to the VPN

sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
sudo iptables -A FORWARD -i tun0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o tun0 -j ACCEPT

Save these rules

sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"

Episode 4 - Display stats on the screen

In order to get information about your LTE/Wifi router, you have to connect the OLED screen to your Pi Zero.

raspberry-pi-pinout

Connect the screen to the Pi Zero

To control the screen, you have to connect 4 wires:

  • VCC: the 3.3V supply - Red wire
  • GND: the ground - Black wire
  • SCL: the I2C clock signal - Blue wire
  • SDA: the I2C data signal - Green wire

According to the Raspberry Pi pin-out, you will connect

  • VCC pin of the screen to the 3.3V pin (1) of the Pi Zero with the red wire
  • GND pin of the screen to the GND pin (6) of the Pi Zero with the black wire
  • SCL pin of the screen to the SCL pin (4) of the Pi Zero with the blue wire
  • SDA pin of the screen to the SDA pin (3) of the Pi Zero with the green wire

At the end, your screen is connected to the Pi Zero like this
oled_schematics

Install the Python library

You will use the Adafruit SSD1306 library to send I2C commands. To install the library, you need git and other tools

sudo apt-get install -y git build-essential python-dev python-pip python-imaging python-smbus
sudo pip install RPi.GPIO
git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git
cd Adafruit_Python_SSD1306
sudo python setup.py install

Enable I2C interface

To use your OLED screen, you have to enable the I2C interface. To do so, use the raspi-config tool

sudo raspi-config
  • navigate to Interfacing Options and press Enter
  • navigate to P5 I2C and press Enter
  • select Yes and press Enter

press Esc to quit.

Get display scripts

You have to clone my Git repository containing

  • the Minecraftia.ttf file which is the drawing font
  • the screen.py script which will display the router details
  • the boot.py script which will display a boot message
  • the display_details.service system service definition

So, clone the Pi Router OLED git repository in the pi home directory

cd
git clone https://git.0x39b.fr/lambda/pi-router-oled.git  

It is the time for you to customize the boot screen and the information screen. To do so, edit the different files and add your touch!

Display the boot screen

You will add a crontab entry in order to execute the boot.py script during the boot sequence. So, open the crontab editor

sudo crontab -e

select 2 which is the nano editor (if asked).

Add the following line at the bottom of the file

@reboot /usr/bin/python /home/pi/pi-router-oled/boot.py

then, save and quit. Now, when your router will boot, your boot message will be displayed on the screen.

Display the details screen

In order to start the information display automatically, you have to create a new system service display_details.service.

So, copy the service definition in /etc/systemd/system/

sudo cp display_details.service /etc/systemd/system/

and enable and start it

sudo systemctl enable display_details.service
sudo systemctl start display_details.service

oled-screen

Episode 5 - Wire them together

Connect the serial adapter

In the 7th episode, you will encrypt the SD-card of your router. And because it is encrypted, each you will power it on, you will have to enter a pass-phrase. To do so, you will use your smartphone connected to the serial adapter allowing you to enter the pass-phrase without physical keyboard.

You have to use simple wires to connect:

  • the GND of the serial adapter to the pin 14 (GND) of the Pi Zero
  • the Tx of the serial adapter to the pin 10 (Rx) of the Pi Zero
  • the Rx of the serial adapter to the pin 8 (Tx) of the Pi Zero

serial_port

Connect the USB hub and devices

Firt of all, have a look to the USB type A connectors pinout.

usb-a_pinout

Now you have to connect:

  • the USB hub to the OTG USB port of the Pi Zero
  • the 4G LTE dongle to the USB hub
  • the Wifi dongle to the USB hub

You have to use shielded cable like this one. You can cut an old USB cable in 12cm long pieces.
shielded_cable

And follow this wiring schema:
pizero_usb_wiring

Episode 6 - Design a 3D printable case

Episode 7 - Encrypt the disk

Episode 8 - Route the traffic through Tor