25 January 2021
My parents live in a fairly rural area of Texas. There's no cable internet, and fiber is out of the question—they're the target demographic for Starlink. When I was in high school, we used our phone landline for a very-flaky, too-expensive DSL. Nowadays we use hotspots.
So if there's no hotspot, there's no internet.
And when I flew in this winter to visit, my paid hotspot plan didn't activate on time. So there I was, sitting in quarantine, trying to use my laptop with no internet. But annoyingly, I already had unlimited phone data.
I wondered: why can't I use my phone's LTE data to hotspot? As it turns out, it's not that you can't—-it's just that iOS doesn't want you to.
Here's how I managed to get a DIY hotspot working on a regular, non-jailbroken iPhone.
Logs from sshd -d -d
And the speed's not bad!
Note: Cloudflare Warp is the VPN app I use on iOS
When you use a hotspot on iOS, your device treats your hotspot's network packets differently than the network data that apps use. Hotspot packets get routed differently, and they get metered. And if your hotspot plan isn't activated, your device won't even let you hotspot at all.
Connecting through my built-in iOS hotspot doesn't route traffic through my iOS VPN
In order to prevent that, this custom hotspot tunnels your laptop's network packets through an app (in this case, iSH). This way, your laptop's traffic gets treated as if it's just an app making network connections.
Here's a quick visual overview of the process:
After setting this up once, subsequent runs take under a minute
After step 7, the custom hotspot is configured. Data from this hotspot is treated just like normal app data!
Here's how I got this working.
apkfor package management. New downloads have it enabled by default.
python3 -m http.server
cat publickey | base64 | pbcopy, then pasted the result into
http://$PHONE_IP/$RESULT. This hit the server on my phone (run using
python3 -m http.server), which showed it in the URL path of the server logs on my phone.
echo "[paste here]" | base64 -d > publickey.
ssh [email protected]$PHONE_IP -p 2222
Now, on your laptop you should be able to run
ssh -N -D 1080 [email protected]$PHONE_IP -p 2222 to create a SOCKS5 proxy server on port 1080! You can open your browser (Firefox, Chrome), configure this as a proxy, and use this to route traffic!
If you only need to use your browser, you're good! But you might also want to use other tools, and many of these tools don't respect system proxy settings. For that, we can use proxychains.
Since I'm on macOS, and proxychains-ng has better support, I used it here. Here's the setup:
brew install proxychains-ng
socks5 127.0.0.1 1080as the proxy
proxychains4 program_name [arguments]
Though this is a great backup internet solution, it's not as good as a normal carrier-enabled hotspot. Here's a little more depth on what its drawbacks are and why they occur.
On an unrooted iPhone, you can't modify iptables or truly run as root, so setting up a VPN server on the phone and connecting to it on your laptop doesn't work. You'll have to route the traffic through SSH or another protocol whose server can be run in iSH.
I spent a couple hours, but for whatever reason, I couldn't get sshuttle working. Proxychains works fine, but it means you need to manually launch every program you'd like proxied, and UDP traffic isn't supported, just TCP.
Note that you may be able to work around these limitations on Linux, where you have more control over the network stack than on macOS.
There are a couple of limitations to this method from the app side, as well. Though they're both bearable as-is.
When your phone locks, or you switch apps, iSH will get backgrounded, and your connection to the server will be lost.
To allow iSH to run into the background, you can run
cat/dev/location > dev/null &, which polls your location, though it's still a bit flaky. You could also disable auto-lock screen, though remember to re-enable it after you're done.
After an hour or two of constantly running
sshd on iSH, your phone gets warm and toasty. This is because iSH emulates all of its commands—-but for good reason, App Store approval!
However, with effort, a custom app could solve the above limitations by:
Until then, this is a proof-of-concept that leaves productionization as an exercise to the reader.