Recently I needed to find an alternative to my Broadband ADSL due to various connection issues and slow performance (lower than 4 Mbps). The only viable alternative is an LTE connection, so I choose to go with a 4G Mobile Broadband Dongle.
As I have my own private wired/wifi network, there is a need to have something more sophisticated than just plugging the dongle into a single PC! So my recipe is to set up my Raspberry Pi with the USB dongle as a Router.
What I have
- Raspberry Pi 3 Model B (Red) Buy on Amazon (paid link)
- Tp-Link RE450 Access Point / Range Extender (Blue) Buy on Amazon (paid link)
- Switch Gigabit Ethernet (Blue) Buy on Amazon (paid link)
What I need
- LTE Mobile Broadband Dongle (Violet) Buy on Amazon (paid link)
- LTE External Antenna Buy on Amazon (paid link)
The 4G LTE dongle I’ve used is manufactured by ZTE (MF823). 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, …
Because I’m building a private network I’m using the following IPv4 address ranges (Class C network):
usb0interface (the LTE Dongle one)
eth0interface (the rest of the network)
The following guide applies to the Raspbian operating system.
Setup the dongle and access the LTE network
First check if the LTE dongle is recognized:
$ lsusb ... ZTE WCDMA Technologies MSM
The dongle should be recognized as a network card, providing an interface for transmitting Ethernet frames, and as a mass storage device (to access the Memory Card content).
$ ifconfig usb0 Link encap:Ethernet HWaddr XX:XX:XX:XX:XX:XX inet addr:192.168.0.185 Bcast:192.168.0.255 Mask:255.255.255.0 ...
The dongle will be listed as
usb0 and the interface should get an ip address in the
192.168.0.0/24 from the dongle DHCP.
To configure the dongle connection, connect it to a PC (I’ve used my Mac) with the SIM card installed, the dongle is provided with a led indicator which have three states:
- Red: the dongle is booting
- Blu: boot complete and ready to connect
- Green: connected to Broadband
Fire up a Web Browser and go to
http://192.168.0.1/ (the gateway address). You should be presented with a little configuration site, change or set the correct APN value depending on the carrier parameters.
Assuming the dongle is successfully connected to the internet (green light), test if the connection is working: just ping Google!
Bonus fact: the dongle is a Linux-like machine that run BusyBox, you can tweak the internal network parameters following this guide.
Configure the network
Assign a static IP address on the internal network with
sudo vi /etc/network/interfaces
# The loopback network interface auto lo iface lo inet loopback # The internal network interface auto eth0 iface eth0 inet static address 192.168.1.1 netmask 255.255.255.0 # The dongle network interface auto usb0 iface usb0 inet dhcp
DHCP for internal network
See DNS Sinkhole on how to install and configure the DHCP server, I report here the values:
- Range of IP addresses:
- Gateway address:
- Broadcast address:
- Subnet mask
- DNS address:
- DHCP Lease Time:
- Static Leases: list devices which must have a static assigned address (possibly below
To share the 4G LTE connection with the internal network devices, the traffic must be routed between
usb0. The tool needed is the Linux firewall: iptables. The firewall forwards connections from the internal network to the 4G LTE network and vice-versa.
sudo apt-get install iptables
First enable IPv4 forwarding: edit the file with
sudo vi /etc/sysctl.conf and uncomment the line:
to enable IP forwarding immediately:
sudo sysctl -w net.ipv4.ip_forward=1
To enable Network Address Translation, NAT and forwarding:
sudo iptables -t nat -A POSTROUTING -o usb0 -j MASQUERADE sudo iptables -A FORWARD -i usb0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A FORWARD -i eth0 -o usb0 -j ACCEPT
to save these firewall rules:
sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
to reload these rules at the boot time, create a file
sudo vi /etc/network/if-up.d/iptables with the following contents:
#!/bin/bash /sbin/iptables-restore < /etc/iptables.ipv4.nat exit 0
and make it executable
sudo chmod +x /etc/network/if-up.d/iptables.
A DNS sinkhole, is a DNS server that gives out false information, to prevent the use of a domain name.
The best implementation that works smoothly on the Raspberry Pi is Pi-hole.
To install it:
curl -sSL https://install.pi-hole.net | bash
Then use the Web Interface Dashboard to configure upstream DNS servers (like Cloudflare DNS
18.104.22.168 22.214.171.124) and enable DHCP server.
Wireless Access Point
The extender can work as an access point, transforming the wired network to a wireless one.
To select this operating mode is as simple as clicking Mode in the top right corner of the page. Select Access Point and click Save. The extender will reboot and switch to Access Point mode. Connect the extender to the switch via an Ethernet cable and configure it broadcasts the signal in the same network class.
Run Kodi on the Rpi
The previous purpose of my Raspberry was to run Kodi, it can be installed in many operating systems, including Raspbian but there are better choices that are more optimized while remaining Debian-based.
I chose to use OSMC, which is based on Debian 9.5 Stretch and has all Debian packages (for the Raspberry architecture obviously).
Changes for OSMC
OSMC is different from Debian in some respects such as networking and startup scripts. Accessing the command line is described here.
/etc/network/interfaces doesn’t exist, OSMC uses a Connection Manager as to handle connections rather than the traditional networking service.
The ConnMan documentation page states that ConnMan contains a very useful command line tool,
connmanctl, which can be used to configure network interfaces.
Each network interface is presented as a service identified with
<technology type>_<mac address>_<other info>:
$ connmanctl services *AR Wired ethernet_abcdef012345_cable *AR Wired ethernet_abcdef678901_cable
ifconfig command identify each interface looking at the MAC address and configure them accordingly:
# Internal network eth0 $ connmanctl config ethernet_abcdef012345_cable ipv4 192.168.1.1 255.255.255.0 # Dongle network usb0 $ connmanctl config ethernet_abcdef678901_cable ipv4 192.168.0.100 255.255.255.0 192.168.0.1 # Or with DHCP $ connmanctl config ethernet_abcdef678901_cable ipv4 dhcp
Optionally the ConnMan service provisioning file can be used.
To run a script or start a program when OSMC starts, the better approach is to use OSMC’s init system, called systemd.
First save the script file to reload iptables rules and make it executable:
$ cd /home/osmc $ mkdir scripts $ cd scripts $ touch last.log $ vi iptables-restore.sh # write the script content $ chmod +x iptables-restore.sh
The script content remains the same:
#!/bin/bash echo $(date -u) > /home/osmc/scripts/last.log /sbin/iptables-restore < /etc/iptables.ipv4.nat exit 0
Create the Unit File
sudo vi /lib/systemd/system/iptables-restore.service:
[Unit] Description = Restore iptables rules After = network.target network-online.target [Service] Type = simple ExecStart = /home/osmc/scripts/iptables-restore.sh [Install] WantedBy = multi-user.target
Notify systemd that a new
iptables-restore.service file exists by executing the following commands:
systemctl daemon-reload systemctl enable iptables-restore.service systemctl start iptables-restore.service
Conclusions and future work
With this project I’ve had the chance to learn interesting things on Linux networking stack also I’ve enjoyed the pleasure of build and control my private network.
In the near future, I’d like to add a way to access my network from the outside (using a VPN service or similar) and fine tune the Raspberry firewall.