Adventures with EasyTether, WireGuard, Android and a Raspberry Pi 4

Six months ago I wrote this story about using EasyTether and WireGuard with a Raspberry Pi 4. I’ve learned a lot since then and there’s been some changes so it feels like it’s time for an update. The following is intended as another standalone article.

The end result is to turn a Raspberry Pi into a Wi-Fi hotspot by tethering it to an Android phone or tablet via USB. My motivation for this is to use it in my RV / motorhome. It’s also been a fun educational project as my first time working with a Raspberry Pi.

Of course tethering to a phone or tablet is nothing new. Unfortunately many plans and devices come with limitations in their tethering abilities. A plan might have “unlimited” data but that usually only applies to so called “device data” which means apps on the device itself. The data allowance via tethering is often quite limited. There can also be limitations on the number of devices that can be simultaneously connected or the tethering speed may be limited compared to device data. This project works around these limitations by using an app called EasyTether which provides its own tethering functionality separate to the device’s native tethering. It also uses WireGuard VPN for security and to smooth over some limitations of EasyTether.

Other than the Raspberry Pi, total cost will be a once only price of $9.99 USD for EasyTether and a subscription to a VPN service. I use Windscribe at $49 per year. They also have a $1 per month option.

The Raspberry Pi fits this use very well. It has multiple USB ports, an ethernet port and a Wi-Fi radio interface. I used this kit from CanaKit. https://www.amazon.com/gp/product/B07V5JTMV9

I’ll describe the steps I took for building this along with some comments. I’m assuming that you’re reasonably comfortable with the Linux command line, you have a laptop (or desktop) computer and you’re doing this somewhere with existing Wi-Fi. I use nano to edit files. I won’t bother giving the command to start nano to edit every file. It’s sudo nano followed by the file name. e.g., sudo nano /etc/dhcpcd.conf These are all system files in /etc or /usr so sudo is required. Sorry for being a little inconsistent in describing these files. I’ve pasted them here directly unless the lines are long enough to wrap on Medium. For those I created gists on Github.

Start with a clean installation of the latest version of Raspberry Pi OS. One of the improvements since my last article is that WireGuard is now in the main repository. There’s no longer any need to use the “Testing” repository. I suggest installing Raspberry Pi Imager on a laptop or desktop to load a memory card with the latest. The image I used was dated 2021–05–07.

Connect a monitor, keyboard and mouse to the RPi. Boot it up and follow the normal setup steps. Connect to your house Wi-Fi, let it install updates etc and restart.

On the menu, go to Preferences / Raspberry Pi Configuration.
On the Interfaces tab enable SSH.

While we have an internet connection we’ll download everything we need.

Start the Chromium browser, go to the EasyTether drivers page and download the driver for Raspbian Buster. Remember where it’s saved (probably /home/pi/Downloads).

Open a terminal window and do the following.

sudo apt install libbluetooth3
sudo apt install wireguard
sudo apt install hostapd
sudo apt install dnsmasq
sudo pip install speedtest-cli

We’re not doing anything with Bluetooth but libbluetooth3 is a dependency of EasyTether. We’ll work on the Wi-Fi access point first. I used a subset of the instructions here.

Edit /etc/dhcpcd.confand add this to the bottom of the file.

interface wlan0
static ip_address=192.168.4.1/24
nohook wpa_supplicant

Create the file /etc/dnsmasq.d/wlan0 containing the following:

interface=wlan0
dhcp-range=192.168.4.10,192.168.4.50,24h

Create the file/etc/hostapd/hostapd.conf containing the following:

country_code=XX
interface=wlan0
ssid=YourNetworkName
hw_mode=g
channel=7
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=YourWiFiPassword
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

Edit that and set the country_code, the ssid and wpa_passphrase. The country code is important because it determines what frequencies the radio transceiver will use based on the regulations in that country. See here for a list of country codes. Mine is set to US. Also note the instructions on that page. The above configuration sets it for channel 7 on 2.4 GHz which is probably a good place to start but you might want to fiddle with that once you get it going. I have mine set to channel 48 on 5 GHz (hw_mode=a). That seems to give me slightly better speed than 2.4 GHz.

Run this to enable the access point.

sudo systemctl unmask hostapd
sudo systemctl enable hostapd

Reboot the RPi either from Logout on the menu or simply sudo reboot.

When it restarts, you should be able to see the new hotspot on your laptop. Connect to it. It won’t provide an internet connection yet but the Wi-Fi should connect.

Open a terminal window on the laptop and login to the RPi with this:

ssh pi@192.168.4.1

If this is successful then you can disconnect the monitor, keyboard and mouse from the RPi and work from the laptop which, at least for me, is more convenient. You can temporarily flip the laptop’s Wi-Fi from the RPi to the house Wi-Fi if you need to access something on the internet while completing the installation.

From here on I’m assuming that you’re on the laptop, connected to the RPi via Wi-Fi and logged in at the command line with ssh pi@192.168.4.1. The RPi has nothing connected to it except power. At this point you should have no internet connection. If you can access the internet from the laptop then you probably have some other connection to your house Wi-Fi. You really need to find and stop that otherwise it will be difficult to know if the tethering is working.

EasyTether

You don’t necessarily need to install EasyTether if your phone and plan provides useful native tethering or at least with limitations that can be worked around by setting the TTL or other means as I’ll describe later. EasyTether works very well for me even in cases where I might not strictly need it.

To install, cd to the directory where you downloaded EasyTether and run the following to install. Change the file name if it’s different.

sudo dpkg -i easytether_0.8.9_armhf.deb

Edit /etc/sysctl.conf and uncomment this line to tell the RPi to act as a router.

net.ipv4.ip_forward=1

Reboot the RPi with sudo reboot. Reconnect the laptop to the RPi Wi-Fi when it returns.

You need to buy EasyTether pro for $9.99 USD. I suggest buying it from the Google Play store on your phone, not directly from Mobile Stream’s web site. See my previous article for an explanation why.

Setup EasyTether on the phone by following the wizard in the app. This involves putting the phone in developer mode.

With EasyTether running on the phone with USB checked, plug the phone into the RPi. You will be prompted on the phone to “Allow USB debugging”.

With any luck, you should now have an internet connection on the laptop. If it doesn’t work, run ip link on the RPi. The list should include the tun-easytether interface. Check cables etc, reboot both the phone and the RPi.

Note that ping (e.g., ping 1.1.1.1) times out with no reply because of limitations of EasyTether. WireGuard will fix that.

WireGuard

You can stop here and you will have perfectly usable internet connection but I suggest installing WireGuard for several reasons.

It’s no secret that your cellular carrier is probably not thrilled at the use of something like EasyTether to work around tethering limitations. It’s probably a grey area with the terms of service. WireGuard will completely hide anything about your traffic from the carrier.

The other reason to use WireGuard is that EasyTether does not provide a complete internet connection. It only supports the TCP and UDP network protocols. Most people probably won’t notice this but as a technical user, I want a full connection with the ability to use ICMP (ping) and other protocols. WireGuard only uses UDP which means that it effectively eliminates the limitations of EasyTether and provides a full internet connection. EasyTether and WireGuard together are a nice combination.

It doesn’t matter much to me but a VPN effectively bypasses any “stream saver” speed and therefore stream quality limitations when streaming from popular services such as Netflix.

A VPN can potentially give you a static IP address and port forwarding if you have a need for that.

WireGuard is very efficient. I haven’t done any real tests but any speed loss seems to be almost unnoticeable. I’ve seen reports of 10% speed loss. With that said, see my notes below about Visible.

I suggest signing up for Windscribe. I have the $49 per year tier but there are other options and no doubt other providers that will work. Windscribe is nice in that it provides config files without insisting on using their client application. It’s a little hard to find on Windscribe’s site but if you ask Garry the chatbot nicely, he’ll give you a 24 hours free trial of the paid version. I have played with building my own WireGuard server. It’s quite easy to do with a $5 per month server at the likes of Digital Ocean or Linode but in the end I decided it wasn’t worth the trouble since Windscribe performs well and has a large selection of endpoints around the world.

Edit the file /etc/network/interfaces.d/tun-easytether which was created by the EasyTether installation and add the following. I’ll comment on the mtu setting later.

# mtu 1448# Uncomment these lines to use WireGuard.
post-up systemctl restart wg-quick@wg0
post-down systemctl stop wg-quick@wg0

The final file should look like this.

Use the Windscribe config generator to generate a WireGuard configuration file. You’ll need to pick an exit point / city. I use port 1194. The file looks like this. Copy to /etc/wireguard/wg0.conf

We need some scripts to configure iptables to provide NAT (network address translation) for WireGuard. Create these two files. Click to see the contents.

/usr/local/bin/wireguard-up.sh
/usr/local/bin/wireguard-down.sh

Make them executable with:

sudo chmod +x /usr/local/bin/wireguard-up.sh
sudo chmod +x /usr/local/bin/wireguard-down.sh

Add PostUp and PostDown lines to /etc/wireguard/wg0.conf so that it looks like this.

Unplug the USB cable from the phone, wait a few seconds and plug it in again. You should still have an internet connection on the laptop but now it is going through WireGuard. ip link will show the wg0 interface. A speed test at speedtest.net should show your data as coming from the WireGuard exit point. This is now a full internet connection. ping 1.1.1.1 should return pings which is something that doesn’t work when EasyTether is used without WireGuard.

That’s pretty much it for the basic configuration.

MTU

You may need to set the MTU value for the tun-easytether interface. See the setting commented out in /etc/network/interfaces.d/tun-easytether. If you you’re getting very slow speeds, try uncommenting that. I understand what it means and can visualize the fragmentation problem if it’s wrong but I’m no expert and results seem a little unpredictable.

When I tether from my phone to the RPi and connect to the Wi-Fi with a tablet, everything works great until I try to access cnn.com on the tablet. The connection completely stalls on that site. Setting the MTU to a lower value immediately fixes the problem. By trial and error, I determined that 1448 is the maximum value that works. 1448 works, 1449 doesn’t.

Here’s the really weird thing. I only need that setting if I have the access point (hostapd.conf) configured for 5 GHz. 2.4 GHz doesn’t seem to need it. I‘m not sure what’s going on there.

Native tethering

You may not need EasyTether if you have a phone plan with good native tethering or with limitations that you can work around by setting the TTL (time to live).

To use native tethering, create these two files:
/etc/network/interfaces.d/usb0
/etc/dhcp/dhclient-exit-hooks.d/usb0

Disable EasyTether on the phone (i.e., uncheck USB in EasyTether or don’t start or don’t install EasyTether). Now when you plug the phone in and enable the native Android tethering on the phone, ip link should show a usb0 interface. It will work with WireGuard or by commenting and uncommenting the appropriate lines in /etc/network/interfaces.d/usb0, you can use it directly without WireGuard.

Some carriers use TTL to detect tethering. See the iptables line that sets TTL to 65. This works for the US carrier named Visible. Other carriers might use a different value.

The dhcp exit hook file is the only way I’ve found to reliably set MTU for usb0. It might be worth uncommenting that line and adjusting.

Ethernet port

The RPi has a wired Ethernet port. I give this a static IP address. Add the following to /etc/dhcpcd.conf

interface eth0
static ip_address=192.168.5.1/24

Create the file /etc/dnsmasq.d/eth0 containing the following so that it has its own DHCP address range.

interface=eth0
dhcp-range=192.168.5.10,192.168.5.50,24h

I think it is possible to have wired and wireless share the same DHCP address range but that requires defining a network bridge. I have not tried this.

I find this useful to connect to an external wireless access point or the WAN port of another router. I have a Pepwave cellular router in my RV. All our client devices are configured to connect to the Pepwave. This has a 100 GB per month plan which is not really enough for two people working and streaming TV etc so we use the RPi with a phone or tablet to spread the data consumption and as a backup. I do this by setting the WAN port of the Pepwave to use DHCP and connect it to the ethernet port of the RPi. This means the client devices don’t need to change.

When I use this at home I connect an external wireless access point to the RPI’s ethernet port. This gives better performance than the Wi-Fi access point in the RPi. Using a simple access point rather than another router avoids another NAT. My laptop gets a 192.168.5.x address from the RPi’s DHCP server.

Real world experience

I haven’t used it much in the RV yet but I have used it quite successfully for work purposes while staying at a relative’s house.

I use it with the following Android devices:

Samsung Galaxy S5e tablet: This is on the AT&T postpaid $20 standalone tablet plan. EasyTether is required since the native hotspot allowance is only 10 GB per month and AT&T doesn’t use TTL to detect hotspot data. It works very well and effectively provides a reliable “unlimited” hotspot for $20 per month. Speed varies but is usually about 30 Mbps and seldom below 15.

We used the tablet one day on a long drive in the RV. The RPi was connected to the Pepwave as described above to provide Wi-Fi throughout the coach with the tablet lying on the bed above the cab which is just below the fiberglass roof. Streaming radio only stopped a couple of times for 30 seconds or so on the eight hour trip. If the signal drops out, it seems to reliably reconnect automatically when the signal returns. It’s kind of cool to be driving through the American south listening to a radio station in Australia 😄 . In general I’m very happy with the tablet, RPi, EasyTether and WireGuard combination. It basically “just works” and is quite consistent.

Moto G Power phone: This is on Visible which is a $25 per month prepaid plan using the Verizon network. The Visible company is owned by Verizon and I’ve heard it said that it’s basically selling Verizon’s “spare” bandwidth at a low priority. It’s a good deal but a bit of a mixed bag. It provides “unlimited” native hotspot / tethering data but limited to 5 Mbps speed and one connected device. I can use it with the RPi in two ways. I can either use native tethering with a TTL of 65 or use EasyTether. Native tethering seems to give somewhat better speeds than EasyTether but the difference is not huge.

I’ve observed some strange behavior. For example, speed tests that start very slow (< 2 Mbps) and slowly ramp up over the next 10 seconds or so. It seems like some of this is related to the use of WireGuard. The speed “cost” of using WireGuard is sometimes unusually high with Visible but much of the time it works very well which is puzzling and frustrating. With the AT&T tablet plan described above, the speed cost of WireGuard is pretty much unnoticeable but with Visible I can be getting a disappointing 2 Mbps followed by a slow ramp up to 9 maybe but then if I stop WireGuard, I get an instant and consistent 20 Mbps. To play with this on the fly you can stop and start WireGuard with sudo systemctl stop wg-quick@wg0 and sudo systemctl start wg-quick@wg0. To leave WireGuard off permanently, comment out the post-up systemctl restart wg-quick@wg0 line in /etc/network/interfaces.d/tun-easytether.

I don’t know what goes on behind the scenes at Visible or Verizon. My observations make me wonder if Visible behaves strangely when the only traffic it sees is all UDP going to a single address.

There are many variables to play with and it can be a good time wasting rabbit hole for a rainy day 😃 . It’s difficult to get consistent results. The speed tests may be part of the strange behavior so all this might be a bit of an illusion. I mostly use speedtest.net. The speedtest command line installed at the beginning can be useful to measure speed without Wi-Fi speed involved. There is some sort of “stream saver” technology in play because I usually get better speeds at Netflix’s fast.com with WireGuard enabled than without WireGuard. Some of this might also be device and location related. I’ve mostly only played with Visible in one location.

All that said, I’ve spent several days working quite successfully tethering to the phone on Visible using EasyTether and WireGuard. Once I set and forget, it seems to work quite well. For me it’s good to have another low cost option, especially on a different carrier in case we’re in a location with poor AT&T but good Verizon coverage.

Final thoughts and ramblings

For anyone interested in the AT&T $20 tablet plan, it’s a bit of an oddball which takes some knowledge and effort to buy. It’s not available online and many AT&T reps don’t know it exists. The best source of info is the LTE Hacks Facebook group. It’s a great deal so I hope it lasts. I try not to abuse it so I haven’t done more than 100 GB in a month yet but I hear reports of people doing many hundreds of GB and even a TB which makes me a little concerned about how long the “all you can eat for $20” party is going to last. I suggest getting it while you can. Hopefully it will be grandfathered if it ends. There’s something weird about the fact that AT&T sells 100 GB for $55 but if you know how and where to ask, they also sell unlimited for $20. Even if you buy a tablet from AT&T, they don’t offer this plan.

I have tried a few other ways of bypassing the AT&T hotspot limitations on the tablet without success. This and other sources talk about the Android command settings put global tether_dun_required 0 . I managed to get adb shell etc working and tried that but native tethering still used hotspot data. Others seem to have success changing the APN from the Android menu as discussed here but that didn’t work for me either. My tablet is AT&T branded which I think gives it some limitations on setting APN etc so others might have more success. For me, EasyTether works so well that there doesn’t seem much point in pursuing other methods.

Even though EasyTether works very well, I’m a little concerned that it hasn’t been updated since 2018. I hope it doesn’t break with an Android update and the author is not around to fix it. My tablet received an update to Android 11 a few days ago and it’s still working well. There are lots of tethering apps in the Google Play store but very few run on Linux. Tetrd looks like a promising alternative but it doesn’t run on the ARM processor of a RPi. I’ve had some communication with the author and I think he is working on an RPi version.

There is a potential problem of the battery being overcharged when a device is permanently connected via USB. Here’s my hacky solution for that. It seems like most devices have a voltage level which is low enough to stop the battery charging but high enough to keep the data circuit enabled. I insert that cable with the resistor and diode, let it discharge which takes about a day, then take it out and recharge. Repeat every day or so.

A little off topic but in my last article I talked about the difficulty of getting a good data plan for a modem/router. This has improved somewhat since then with AT&T now selling a prepaid plan which provides 100 GB for $55 per month. That’s the same plan I mention above which is listed as being for tablets and hotspots. It works great in my Pepwave MAX BR1 MK2. This is a step in the right direction although not enough for anyone using it full time, especially if streaming video. Of course you can buy more than one but that gets expensive so I still have a good use for this tethering project. The big advantage of a modem/router compared to a tablet is that you can use an external antenna.

The Wi-Fi transceiver in the RPi is okay but not great when it comes to speed and distance coverage. It seems to max out at about 25 Mbps when talking to my Mac laptop even if the actual cellular speed is better. I know this because I can connect another router / access point into the ethernet port, connect to that instead of the RPi directly and get better speeds. I guess it’s limited by lack of external antenna.

I’m aware that there are probably easier “out of the box” solutions to do the same as this. The inexpensive GL-AR750S router runs OpenWRT and seems to have the ability to integrate WireGuard and EasyTether. I haven’t tried it but I probably will. I like the RPi solution because it keeps things “light” and simple and, as I said earlier, it’s been a bit of an educational project. There’s also an OpenWRT build for the RPi which I’m sure is worth a try but I don’t think there is a stable release for the RPi 4 yet.

Update on above: I finally got around to try tethering to a GL-AR750S. I guess I was a little nervous because if it works brilliantly then all my efforts messing with the RPi could be considered an unnecessary waste of time. 😬 Well, it’s a very nice versatile little device with an easy to use UI. Native tethering is plug and play. Setting up WireGuard is simple through the UI. I installed EasyTether roughly following this. That all worked although somehow the end result didn’t feel as smooth as the RPi when I was changing devices or changing from native tethering to EasyTether. It crashed with a segfault once while doing that. Maybe I’m a little biased but for now I’m sticking with the RPi which switches smoothly between devices and tethering methods and just feels more robust. I use the GL-AR750S in AP mode purely as an access point connected to the RPi to get better speed than the access point in the RPi.

I think that’s about it. Thanks for reading. I’m happy to receive feedback or corrections.

Just a burst of data