June 6th, 2021: I’ve written an updated version of this article.
Dec 5th, 2020: See the footnote at the bottom of the page. You may not really need EasyTether.
I recently built a simple cellular router/interface which provides a portable internet connection by tethering to either an Android or iOS phone. Of course most phones can act as a hotspot but this has several advantages over the default hotspot application.
- For Android phones, all data is considered as device data. To the carrier, it looks like you’re using an app directly on the phone, not using the phone as a hotspot. Many phone plans have generous or “unlimited” device data but quite limited hotspot data. This is achieved through an inexpensive app called EasyTether.
- All data is transparently encrypted by the WireGuard VPN.
The following describes how I built this. There’s nothing new or revolutionary here but it might save some digging for anyone doing the same. I make the following assumptions:
- You are familiar with basic Linux console commands, file editing (with
nano
or other editor) and have some understanding of networking. Mostly what I’m providing here are links and comments. When editing most system files you’ll need to usesudo
. - You have a NAT router, probably with WiFi, to connect this to. The goal of the project is to use a phone or tablet to provide the WAN connection for a router.
- You have an existing internet connection available to get started with, again probably using WiFi.
The instructions are primarily for Android with iOS being a bit of an afterthought at the end. The following steps are the order I took.
I started with this complete “getting started” kit for the Raspberry Pi 4 from Canakit. The kit seems good quality, well documented and went together in a few minutes. I’m away from home right now without the usual collection of bits and pieces so it was an easy way to go but you can obviously do it cheaper by buying just the board and hanging it together with whatever connectors, cables, power source and enclosure you have. This is my first experience with the Pi. I wished I’d looked at them earlier. What a great little device and community.
You can do most things though SSH or VNC but you need a physical screen, keyboard and probably a mouse to get started.
Boot up the Pi for the first time and go through the setup steps. As part of this, enable WiFi and connect to your home WiFi.
While you’re in the desktop GUI, go to Preferences / Raspberry Pi Configuration / Interfaces and enable SSH and, if you want to use the desktop remotely, VNC.
Open a console window from the top toolbar. Run the command ip address
and note the IP (inet) address of the wlan0 interface.
You can now disconnect the physical screen and keyboard and work, probably more conveniently, from another computer on your home WiFi.
From another computer run ssh pi@x.x.x.x
where x.x.x.x
is the IP address of the Pi. It should prompt you for the password you entered during setup.
Set the Ethernet port eth0 to a static IP address by editing /etc/dhcpcd.conf
and adding the following lines:
interface eth0
static ip_address=192.168.115.1/24
You can choose any private address but avoid 192.168.117.0/24. because that is used by EasyTether.
Download EasyTether using the Raspbian buster link here. I used wget with this command but make sure you get the latest version.
wget http://www.mobile-stream.com/beta/raspbian/9/easytether_0.8.9_armhf.deb
Install EasyTether with this substituting the exact file name.
sudo dpkg -i easytether_0.8.9_armhf.deb
While you’re at it, install telnet and speedtest-cli to use for testing.
sudo apt install telnet
sudo apt install speedtest-cli
Reboot with sudo reboot
You need to buy EasyTether pro for $9.99 USD. I suggest buying it from the Google Play store, not directly from Mobile Stream’s web site. See my explanation below about that.
Setup EasyTether on the phone by following the wizard in the app.
Plug the phone into the Pi. I used one of the USB3 ports. The app should indicate that a connection is established. Running route -n
should return something like this.
As you can see, EasyTether established a network of two between the Pi and the phone. The Pi is 192.168.117.0
and the phone is 192.168.117.1
.
Edit /etc/sysctl.conf
and uncomment the following line:
net.ipv4.ip_forward=1
Set MTU for EasyTether by editing /etc/network/interfaces.d/tun-easytether
It will look much like this. Insert the mtu 1464
line as shown.
I came to the 1464 number by trial and error. There is probably a more precise way to do it and I’m not sure if the optimal value will be the same for everyone. It makes a dramatic difference to performance. If it is too high, performance is abysmal, too low and it is not as good as it could be. For me 1465 is too high, 1464 is good.
Reboot with sudo reboot
.
Disable WiFi on the Pi. I did this by connecting to the desktop with VNC and using the setting at the top right of the screen. Assuming you’re using WiFi to connect, your screen will appear to freeze when you do that because you’ve lost the connection.
Now comes the real test. Connect to the Ethernet port on the Pi. This is on the 192.168.115.0/24
network so you’ll need a device with an address in that range other than 192.168.115.1
. My configuration and the intended use is to connect the Pi to the WAN port of a NAT router / WiFi access point. I gave my router a static address of 192.168.115.2
and specified the gateway as 192.168.115.1
I also told the router to use CloudFlare’s DNS servers at 1.1.1.1
and 1.0.0.1
for DHCP to clients on the LAN side.
If all is well, you should have an internet connection to the outside world. Note that EasyTether does not pass ICMP packets which means that ping does not work. I think it only does TCP and UDP so web browsing should work. To test at the Pi command line, try wget, curl or telnet to a known web server. Perhaps ping google.com on another computer to see the IP address and then try something like telnet 172.217.195.101 80
. That should connect.
WireGuard
You can stop here if you don’t want to use WireGuard VPN. However WireGuard provides some nice advantages in addition to security. WireGuard uses UDP only and EasyTether does a good job passing UDP. This solves the ping issue and pretty much any other limitations of EasyTether.
I used the instructions here to install WireGuard from the Raspberry Pi “Testing” repository. I found those instructions easy enough to follow. Don’t skip the step about changing the repository priority because you probably don’t want your Pi loaded with all bleeding edge packages. You’ll probably want to temporarily re-enable the Pi’s WiFi and use your home broadband connection for these downloads.
I first setup my own WireGuard server on a $5/month VPS at Digital Ocean. That worked well but then I discovered Windscribe which seems to be a great service. Unlike many VPNs, they provide raw config files which is exactly what we need here. I signed up for a year at $49.99, less than what I was paying at Digital Ocean. 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. Other than the host name, there’s nothing Windscribe specific in the following.
Use the Windscribe config generator to grab a config file. It looks like this. Copy to /etc/wireguard/wg0.conf
We need some scripts to configure iptables. Create these two files in some convenient directory. I put them in /usr/local/bin
Click to see the contents.
/usr/local/bin/wireguard-up.sh
/usr/local/bin/wireguard-down.sh
I’m no iptables expert so I admit that I found these somewhere without fully understanding them. The purpose is to pass packets between eth0 and wg0.
Add the PostUp and PostDown lines to wg0.conf like this.
It’s probably a good time to reboot with sudo reboot
and then start WireGuard with:
sudo systemctl start wg-quick@wg0
With some luck and if the wind is blowing in the right direction, you should have a full internet connection on eth0. You should be able to use it from the LAN side of the router.
Run the following to make WireGuard start on boot.
sudo systemctl enable wg-quick@wg0
iOS devices
I primarily use a cheap Android phone for this but I also have an old iPhone on Visible. I installed the following packages.
sudo apt install usbmuxd ipheth-utils libimobiledevice-utils
That works! I can unplug the Android and plug in the iPhone. Port eth1 appears and everything “just works” including WireGuard. You’ll need to enable the native USB tethering feature on the iPhone because EasyTether is only for Android. Visible has “unlimited” hotspot data so EasyTether wouldn’t give me any advantage.
The only thing I usually need to do when changing phones is to restart WireGuard with:
sudo systemctl restart wg-quick@wg0
There’s probably some way to script that when a phone is plugged in.
Performance
EasyTether, WireGuard and Windscribe together perform very well. I haven’t made exact measurements but after many runs at speedtest.net and similar sites, I don’t notice much difference at all between using WireGuard or not. Speed on my laptop on the LAN is similar to running a test on the phone itself. On my AT&T plan, the phone by itself struggles at speedtest.net. For some reason, it often seems to take forever “finding optimal server” but with WireGuard it works quickly and smoothly.
It’s also very reliable. I can work on it all day and it never misses a beat. It places very little load on the Pi. According to htop, the CPU is barely ticking above idle.
Speed will obviously depend on the phone, the plan (de-prioritized or not), signal strength etc. Here’s a typical test for me on T-Mobile.
A note about EasyTether: I bought it directly from the web site and immediately received the activation code but could not activate it on the phone. It always returned an error about not being able to read the phone’s IMEI. Maybe it was related to the phone being dual SIM. Two emails to Mobile Stream support several days apart went unanswered. In the end I took a gamble and bought it from the Google Play store which doesn’t require activation and that worked. I’m impressed with the app, it works perfectly but I’m a little disappointed with the support. Luckily $9.99 isn’t enough to get too upset about. I thought I was doing them a favor because they probably receive more money when they sell directly. I guess I could make a case to claim the first payment back from PayPal but I haven’t bothered.
Conclusion
I think that’s about it. It’s been a fun project and I’m very happy with the result. I think you could probably do the same with a commercial router (GL.iNet?) with OpenWRT etc. You could also run OpenWRT on the Pi although I don’t think there is a stable release for RPi 4 yet. I think the Pi could do it all and then you wouldn’t need the router so I’m aware that there are other ways of doing this with less hardware but I wanted to give this a go and I like the simplicity and flexibility.
For what it’s worth, I’m running it with this cheap Samsung Galaxy from Amazon. It works well and, as a bonus, is dual SIM. I currently have it running two plans, T-Mobile Magenta and a Cricket (AT&T) plan similar to this from Amazon. The dual SIM feature allows me to easily switch between them. I also have the iPhone running Visible (Verizon).
My motivation for this project is to provide internet connectivity for our RV / motorhome. I’m still playing with ideas and a little undecided if I’ll use it in the RV or not. It’s a frustrating fact that you cannot connect an external antenna to a phone. An undeniably better technical solution is to have a modem/router connected to an external antenna but that comes with some non-technical issues. As far as I know, there really is no legitimate data plan that an ordinary person in the USA can buy and run in a router and use typical “home broadband replacement” amounts of data. I know plenty of people happily get away with putting phone SIMs in routers but they always run the risk of being shut down for terms of service violations. Various sites and forums seem to be full of “my modem just stopped working” stories. Some people change their router’s IMEI so that it looks like a phone or tablet to the carrier which is probably illegal. Data plans promising high data caps or no caps at all are available from resellers but they tend to be dubiously legitimate and can be expensive. My two phone plans on the Android for about $50/month each plus Visible on the iPhone for $25 (with party plan) gives me all three networks for redundancy at about the same price as a single, all eggs in one basket, dubious reseller plan. Provided that I don’t go crazy with the amount of traffic, I think this is pretty safe from raising any flags at the carrier for TOS violation.
I’m leaning towards using this in the RV and maybe getting a booster. Boosters come with their own set of problems and limitations but I think with care and planning that it could be a workable solution. It occurs to me is that many people on the likes of LTE Hacks etc are really striving for speed. That’s not such a big deal for me. 20 or even 10 Mbps is usually enough for me to work with. It’s more important for me to have multiple options to lessen the chance of being unconnected. Most of my work involves Slack, Zoom and pushes to GitHub. I don’t care about HD movies or gaming. This streams live TV nicely using Sling. I just need some boost when camping where the signal is weak.
Thanks for making it this far. I hope this has been helpful.
Footnote
I should probably write version 2 of this but I’ve stopped using EasyTether. There was nothing wrong with it but I discovered that I don’t really need it. Many cellular services seem to use TTL as a way to distinguish between phone data and tethering. In the US, I believe this is true for Verizon and T-Mobile but not AT&T. EasyTether and similar apps are useful as an easy way to connect a phone directly to a laptop or desktop without having the ability to fiddle with TTL settings etc. They are also useful if the carrier (e.g., AT&T) uses some other way to detect tethering or a plan doesn’t officially allow tethering at all.
I now have a Moto G Power Android phone running on Visible. Native USB tethering to the Pi works nicely.
I made the following changes:
Comment out (i.e., put a #
in front of) the first line of /etc/network/interfaces.d/tun-easytether
to prevent it from starting or if you’re starting from scratch, don’t install EasyTether at all. I have kept it installed in case it’s useful for other phones or services.
Native USB tethering should now work. The phone appears on interface usb0
with an IP address in the 192.168.42.0/24 range. That works perfectly with WireGuard just as EasyTether did.
Set the TTL by adding this to /etc/sysctl.conf
net.ipv4.ip_default_ttl=65
On Visible, this gives me the full speed rather than being throttled to 5 Mbps. 65 seems to be “magic” number for most services.
I also set the MTU by adding this to /etc/dhcpcd.conf
interface usb0
static interface_mtu=1420
The MTU setting doesn’t seem to make a lot of difference but 1420 works well.