Proxying on iOS 7

January 27th, 2014
Spencer Nielsen Follow snielsen42 on Twitter

tethering

A large number of the world’s wireless carriers enable internet tethering by default for no extra charge when using an iPhone (because data is just data after all). In the United States, no major carrier has had the good sense to do it even with data caps and throttling. Any way you look at it, paying for tethering is a bad deal. So what then are your options when you want to use your phone’s internet connection on your laptop? You can always jailbreak and enable iOS’s built-in tethering (marketed as “Personal Hotspot“) using a tweaked carrier profile or install a stanadlone tethering app. However, jailbreaking has known risks associated with it and some US carriers have stated that they will cut your service if they detect tethering without the requisite contract on their end (exactly what detection methods they employ and how much work they have invested in enforcement remains unclear). What then are we left with? Proxying.

Proxying != Tethering

iPhone Halo

Proxying is different from tethering in significant ways. Instead of routing traffic on the network level, a proxy app receives requests from a client (the laptop) through a known proxying protocol to make network requests as itself on behalf of the client (essentially performing routing on the application level). As far as the rest of the internet is concerned, there is just some app on your phone using the internet connection. The proxying app on the phone is simply making all the requests for itself. It just so happens that when it receives the responses, it passes them back across the proxying protocol to the laptop.

OS X has support for proxying basic services like HTTP (80) and HTTPS (443) and a few others. So unlike tethering, you do not have the full range of ports at your command but you can still get a lot done over ports 80 and 443 these days. But the key difference from tethering to us is that the functionality to proxy can be performed entirely within a fully-sandboxed iOS app, running on an un-jailbroken iOS device.

App Store Intrigue

Appstore-icon

Proxying apps have appeared in Apple’s App Store from time to time. Sometimes the functionality is hidden within apps as easter eggs that need activation and sometimes it is just in plain sight. In every case, Apple always mysteriously pulls them without explanation (proxying does not violate any of the App Store Guidelines). It seems that the best way to get a proxying app on your iOS device is to simply build it yourself with a developer certificate. If you (or a friend) are a registered Apple developer with an iOS signing certificate, then you can download the source code to any number of proxying apps for iOS, build it yourself and load it on to your device directly. Even after building and getting it to run on your device, there are still complicated setup steps required (on both iOS and OS X) that are well documented but will not be covered here.

The most popular proxying app on iOS for the last couple of years has been iProxy. iProxy is open-source but it hasn’t been worked on for a few years. As time marches on, bit-rot emerges and future compatibility starts to falter. When I recently upgraded to an iPhone 5S (gold of course) I found that iProxy no longer worked. So I dug into the source and fired up the debugger to see what happened.

Well There’s Your Problem!

Screen Shot 2014-01-25 at 3.24.19 PM

After a fair amount of tests and debugging, it seemed that the main problem with iProxy on iOS 7 related to obtaining the IP address of the DNS server for the cell connection. Without that, it appears you can still create network requests to specific IPs, but you can’t resolve any domain names which severely limits what you can do on the internet.

Previously, polipo (the web proxying project that iProxy is based on) tried to obtain this IP by reading /etc/resolv.conf from the filesystem and parsing it’s contents. On iOS 7 it appears like this file either no longer exists or is no longer accessible from 3rd-party apps. Fortunately, this problem is easily fixed. libresolv contains routines that we can use to obtain the IP of the DNS server and so we can just use those. After integrating these new routines and making a couple of other small housekeeping changes, it looked like the broken functionality was now fixed on iOS 7.

Unfortunately, things still didn’t work on my new Mavericks laptop. What was curious though was that when I proxied my old Snow Leopard laptop, everything worked! After a lot of thrashing, some network capture sessions using Instruments.app and some dumb luck, I found the solution. You need to enter the IP of the iOS device running iProxy (as noted in the Wi-Fi Settings) into the “DNS Servers” list of the OS X Network Preferences Pane for the Wi-Fi connection. At last, it finally worked as intended! Update: It appears like there is some issue at play on the Mac side of things that may cause it to not work quite yet at this point. I have found that having the Mac disconnect itself from it’s own ad-hoc wireless network and then reconnecting it can help.

Wrap Up

So after getting my hands dirty for a bit, my new hardware setup now is complete with a proxying solution that lets me fix things in a pinch when I am out and about or keep my sanity on long family car trips. I have forked the original iProxy project on github and committed my changes for anyone else to play around with. iProxy is in great need of a complete overhaul, but in the meantime my little tweaks will keep it on life support as iOS moves forward.

6 Responses to “Proxying on iOS 7”

  1. Tan Says:

    Thanks for updating the code, unfortunately I have been trying to get proxying to work for while. iProxy hasn’t been very successful (even using DNS settings). However I have found this to work quite well:

    http://code.google.com/p/iphone-socks-proxy/

    The best combination is for me to use Firefox plus foxyproxy to route all traffic including DNS through the proxy.

  2. snielsen Says:

    I have noticed that occasionally I have to kick iProxy once by going through the motions, disconnecting and then trying setup over again.

    Thanks for the pointer to iphone-socks-proxy! I will check it out 🙂

  3. Darren Says:

    Thank you for updating the code! I have been trying this on my new iPhone 5S which I got for my birthday last weekend, and am unfortunately not having any luck on any of the proxy apps I can find (iProxy, iphone-socks-proxy, NetShare). I can get them all on a ad-hoc network, I can ping my phone’s ip address, I can even telnet in to the port it says the proxy is on, but nothing…

    I am on mavericks, 10.9.2. I did set the DNS on my laptop to the ip of my phone. But sadly nothing works. I’ve tried setting the HTTP / HTTPS proxy settings as well, tried SOCKS on the ports mentioned for HTTP, nothing. Quit my browsers, opened them again, etc etc. Nothing. Could you please help me?

    I just today updated my phone to 7.1 and Xcode to 5.1. So all is up do date now. I will say I was trying these apps on my iPhone 4S which was on the 7.1 beta 5, and so now my iPhone which is on 7.1, but, when I got my phone, so for the last week, it was on 7.0.6, and nothing. So not sure if 7.1 is the issue?

  4. snielsen Says:

    @Darren

    Sometimes you need to kick it a bit to get it to work. I tried it successfully this morning with an iPhone 5S on 7.1 and a Mac on 10.9.2. Here are the specific steps it took this morning:

    Created the ad-hoc wireless network on the Mac
    Applied the saved “iProxy” network setting in the Network System Preference Pane on the Mac
    Had the iPhone join the ad-hoc wireless network
    Launched iProxy on the iPhone
    Observed on the Mac that things weren’t working yet.
    Used the Wireless menu to “Disconnect” the Mac from it’s own ad-hoc wireless network
    Reconnected the Mac to the ad-hoc wireless network
    Now things are working as expected

    Let me know if that helps. I will updated the blog post post to note this weird reconnection workaround.

  5. Darren Says:

    @snielsen

    Wow, thank you! That is what did it for me, the last part of disconnecting and reconnecting to the ad-hoc wireless network. I was able to get online! Thank you!

  6. snielsen Says:

    @Darren No problem. Glad I could help 🙂

Leave a Reply

Entries (RSS) and Comments (RSS).