This guide allows you to convert a Raspberry Pi into a 3G or 4G Hotspot, using a 3G or 4G Modem and a WiFi card.

Prerequisites:

  1. You must have a 3G or 4G USB Modem (in this example, I am using a ZTE MF112 3G Modem from Three)
  2. You must have a wireless adaptor (either build in to the Pi or a compatible external one)
  3. You must have imaged the Pi with the latest Raspian build. The version I used is downloadable here.

Preparing the Raspberry Pi:

Firstly, you need update the Raspberry Pi image.

[sourcecode language="python" wraplines="false" collapse="false"]
your source code goes here
[/sourcecode]
sudo apt-get update
sudo apt-get upgrade

Then, you need to download and install some packages, as follows:

sudo apt-get install usb-modeswitch ppp dnsmasq hostapd

This installs usb-modeswitch (we’ll see this later) which allows you to configure your 3G Modem to be used as a 3G Modem, ppp which is the Point-to-Point Protocol daemon to establish internet links over dialup modems, dnsmasq which provides a DHCP server for the wireless LAN, and hostapd which allows you to create the wireless hotspot.

You’ll also need to download UTMS keeper, as follows:

mkdir umtskeeper
cd umtskeeper
sudo tar -xzvf umtskeeper.tar.gz
sudo mkdir /opt/umtskeeper
sudo cp -r . /opt/umtskeeper

Configuring your 3G Modem:

A lot of 3G / 4G Modems come with file systems which contain installers for Windows and OSX. The Raspberry Pi often detects these and registers the modem as a storage device, instead of its true purpose. This is why usb-modeswitch is used, to switch the mode of the USB Device.

To do this, we need to find all the USB devices on the Pi.

lsusb

This will churn out something like this:

Bus 001 Device 004: ID 050d:2103 Belkin Components F7D2102 802.11n N300 Micro Wireless Adapter v3000 [Realtek RTL8192CU]
Bus 001 Device 006: ID 19d2:0031 ZTE WCDMA Technologies MSM MF110/MF627/MF636
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. SMC9512/9514 USB Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

My device (ZTE WCDMA Technologies…) is showing up here. To confirm that your device is acting as a modem as not as removable storage, you need to edit the modeswitch config file. For this, you need the DefaultVendor and DefaultProduct parameters, which usually can be found by going a quick Google search for ‘<<Dongle Model Number>> usb_modeswitch’.

sudo nano /etc/usb_modeswitch.conf

At the bottom of this file, add the following lines:

DefaultVendor = 0x<<VendorID>>
DefaultProduct = 0x<<ProductID>>
MessageEndPoint = "0x01"
MessageContent = "55534243000000000000000000000011060000000000000000 000000000000"

Where <<VendorID>> and <<ProductID>> are the information you found online. Sometimes, they are revelaed in the lsusb command, but you must ensure that they are correct (i.e. actually a modem). In my lsusb, the VendorID is 19d2 and the ProductID is 0031 but in my modeswitch config file, I enter 0103 for my ProductID.

Connecting to the cellular network:

We installed UMTSkeeper earlier, who’s job it is to automatically connect (and re-connect should the connection drop out) the 3G connection. This uses sakis3g to do that. It’s prudent to check the 3G connection before we script the connection automatically with UMTSkeeper .

Firstly, we need to sakis3g and utmskeeper executable.

sudo chmod +x /opt/umtskeeper/sakis3g
sudo chmod +x /opt/umtskeeper/umtskeeper

Then, we can run sakis3g with the interactive flag to test our 3G connection:

sudo ./sakis3g --interactive

This will guide you through the process of connecting to the internet using your 3G Modem.

  1. Choose ‘Connect with 3G’
  2. In the ‘Select Modem Type’, choose ‘1. USB device’
  3. Under ‘Please select USB modem’, select your USB Modem (in my case, it’s ZTE WCDMA Technologies MSM).
  4. Under ‘Please select an APN’, either choose your carrier’s APN or select ‘Custom APN’ (in my case, it’s offered ‘Mobile Device (three.co.uk)’ which I know is the correct APN’
  5. You should receive a notification confirming the device is connected. In my case, it says ‘MF112 connected to 3’.
  6. Under ‘Please select an action’, click ‘Exit’ and you will return to the command line.

To make sure the device is actually connected:

pi@raspberrypi:/opt/umtskeeper ifconfig
ppp0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 10.120.8.29  netmask 255.255.255.255  destination 10.64.64.64
        ppp  txqueuelen 3  (Point-to-Point Protocol)
        RX packets 6  bytes 102 (102.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 141 (141.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Now we’ve proven the connection, we need to automate it. Let’s disconnect from 3G to not waste that data! Hop back in to the sakis3g interactive session and select ‘Disconnect’.

In doing this, we’ve established some settings we’ll need to use with UTMSkeeper. We’ve established that:

  • The APN is three.co.uk
  • The APN does not require a username or password
  • The USB Modem is running correctly

We can run that connection in one command:

sudo /opt/umtskeeper/sakis3g connect --nostorage --pppd APN="three.co.uk" APN_USER="0" APN_PASS="0" USBINTERFACE="19d2:0031" USBDRIVER="option" OTHER="USBMODEM" USBMODEM="19d2:0031"

Here are the components of that command:

  • APN – the APNof your carrier
  • APN_USER – the APN user of your carrier. If you didn’t need one, enter 0
  • APN_PASS – the APN password of your carrier. If you didn’t need one, enter 0
  • USBINTERFACE – the ID of your USB Modem, found above when we did lsusb.
  • USBMODEM – also the ID of your USB Modem

So running that command connects the device up to the internet again. We can confirm this by performing ifconfig again. Now we’ve confirmed the parameters we need for UMTSkeeper. To disconnect, just run sakis3g with disconnect.

sudo /opt/umtskeeper/sakis3g disconnect

The UMTSkeeper command is similar, as follows:

/opt/umtskeeper/umtskeeper --sakisoperators "USBINTERFACE='19d2:0031' OTHER='USBMODEM' USBMODEM='19d2:0031' USBDRIVER='option' OTHER='USBMODEM' APN='CUSTOM_APN' CUSTOM_APN='three.co.uk' APN_USER='0' APN_PASS='0'" --sakisswitches "--sudo --console" --devicename 'MF112' --log --silent --monthstart 8 --nat 'no' &

Ensure that the options you set up using the sakis3g executable are placed in the correct bits in the UMTSkeeper executable..

Clearly, we want this to start when the pi boots, so we need to put it into /etc/rc.local which will run that command on start.

sudo nano /etc/rc.local

I added the command straight above the commands to print the IP Address of the Pi when it boots.

Creating a WiFi Hotspot:

As we haven’t configured anything, we need to stop dnsmasq and hostapd:

sudo systemctl stop dnsmasq
sudo systemctl stop hostapd

We then need to configure a static IP address on to the Wireless interface. Hop in to:

sudo nano /etc/dhcpcd.conf

At the bottom (but above any other interface configuration options), enter the following information:

interface wlan0
static ip_address=<<IP_Address>>/24

The name of the interface can be found by running the ifconfig command. Change <<IP_Address>> with your intended IP Address.

To configure the DHCP Server, we need to edit options in the DHCP config file:

sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
sudo nano /etc/dnsmasq.conf

Then, enter the following information:

interface=wlan0      # Use the require wireless interface - usually wlan0
  dhcp-range=<<Subnet_Start>>,<<Subnet_Stop>>,255.255.255.0,24h

Change <<Subnet_Start>> and <<Subnet_Stop>> with your intended IP Addresses.

Now we’re ready to configure the access point:

sudo nano /etc/hostapd/hostapd.conf

Enter the following information:

interface=wlan0
driver=nl80211
ssid=<<Your_Network_Name>>
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=<<Your_Network_Passcode>>
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

Replace <<Your_Network_Name>> and <<Your_Network_Passcode>> with your own values.

We need to tell the system where to find the configuration file:

sudo nano /etc/default/hostapd

Find the line with #DAEMON_CONF and replace it with the following:

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

Finally, reboot the Pi.

sudo reboot

NATting the Connection:

Firstly, we need to enable IP Forwarding:

sudo nano /etc/sysctl.conf

Remove the # before the line that reads #net.ipv4.ip_forward=1 and save the file.

Then, run the following commands:

sudo iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
sudo iptables -A FORWARD -i ppp0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o ppp0 -j ACCEPT
sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"

To have the IP Tables load each time the Pi starts:

sudo nano /etc/rc.local

And add the following line above the UMTSkeeper command we added earlier.

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

Finally, reboot the Pi.

sudo reboot

Congratulations! When the Pi boots back up, it should be a fully functioning 3G WiFi hotspot.

Firewalling

Since your Pi will be out on the open internet, it’s probably a good idea to have some sort of a firewall going! We’ll use UFW.

sudo apt-get install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from <<Your_IP_Subnet>>/24 to any port 80
sudo ufw allow from <<Your_IP_Subnet>>/24 to any port 443
sudo ufw allow from <<Your_IP_Subnet>>/24 to any port 53

If you’re SSHing in to your pie, you’ll want to add:

sudo apt-get install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh

You’ll also need to tell UFW to allow IP Forwarding, as follows:

sudo nano /etc/default/ufw

Change ‘DEFAULT_FORWARD_POLICY’ from ‘DROP’ to ‘ACCEPT’. Then, run the final command.