test NEAppProxyProvider without MDM?

This discussion is for iOS/iPadOS.

  1. I've written an NEAppProxyProvider network extension. I'd like to test it. I thought that using the "NETestAppMapping" dictionary was a way to get there, but when I try to instantiate an NEAppProxyProviderManager to try to install stuff, the console tells me "must be MDM managed" and I get nowhere. So can someone tell me, can I at least test the idea without needing to first get MDM going?

  2. I'd like to know if how I'm approaching the core problem even makes sense. My custom application needs to stream video, via the SRT protocol, to some place like youtube or castr.

The problem is that in the environment we are in (big convention centers), our devices are on a LAN, but the connection from the LAN out to the rest of the world just sucks.

Surprisingly, cellular has better performance. So I am trying to do the perverse thing of forcing traffix that is NOT local to go out over cellular. And traffic that is completely local (i.e. talking to a purely local server/other devices on the LAN) happens over ethernet. [To simplify things, wifi is not connected.]

Is an app proxy the right tool for this? Is there any other tool? Unfortunately, I cannot rewrite the code to force everything through Apple's Network framework, which is the one place I know we can say "use cellular." [E.g. URLSession() has absolutely no way of forcing cellular, and even so, the low level streaming library I use is written with raw sockets, and its not feasible for me to rewrite it.]

Any other suggestions of how to accomplish this "send non-local traffic to cellular, all local traffic out over ethernet" gratefully welcomed!

First up, have a read of TN3134 Network Extension provider deployment. This explains your deployment options for this technology. Specifically, for an app proxy on iOS the device must be managed. That’s because the MDM system is used to associate your app proxy with the apps that it proxies, by matching up the VPNUUID properties on both.

During development you can use NETestAppMapping to establish this mapping. You’ll still need a configuration profile to enable your app proxy, because of the requirement to provide a VPNUUID property with the configuration.

Is an app proxy the right tool for this?

Before you can answer that you have to first see if an app proxy will actually work. That is, in production:

  • Are the target devices managed?
  • Is the target app installed via MDM?

If either of those is false, an app proxy won’t work and thus it’s definitely not the right tool (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Assume the target devices are managed and the app is installed by MDM.

My question of is an app proxy the right tool is really:

  1. Will an app proxy let me split the traffic in the way I envision? I have zero experience in this area.
  2. Can you suggest an easier way of getting this done.

As always, thanks for your attention. Could you perhaps give a simple explanation of what a minimal configuration file would be, and how, simply for testing in dev, I can install it? I’ve looked at the reference document and it is a bit… daunting.

I know what MDM is, I have a vague idea about configurations, and absolutely no experience here.

Actually, the document you referred to isn’t so daunting. It’s the PDF about configurations which is overwhelming. That said, there is no place that I know of that documents how to set up the dictionary with NETestpAppMapping nor where it should go (the main app’s info file I assume).

If there’s any documentation, or one can spell out exactly how you’re supposed to use an NEAppProxyProviderManager in dev to get going, that’d be great. I tried to create one but the console printed an error message that “must be MDM blah blah.”

Presumably that’s because my attempt at providing the app mapping was flawed. I hope.

This stuff is all so hard when there’s basically no good documents telling you how to start (without MDM) to even test.

thanks again, you’re a life saver.

is an app proxy the right tool

My general impression is that it is not, but it’s hard to but sure knowing more details about your situation. Specifically, this bit:

And traffic that is completely local … happens over ethernet.

Can you clarify what “local” means in this context? Is there a DHCP server on this Ethernet? Or is everything using link-local addresses [1]?


On the app proxy provider front:

  • The documentation for NETestAppMapping is here.
  • The configuration profile documentation is here.

I’ve posted examples of post in the past… but where? OK, some spelunking found this.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] For IPv4 this means RFC 3927 Dynamic Configuration of IPv4 Link-Local Addresses.

There is a DHCP server on the local LAN to assign addresses to devices.

The criteria is simple: if my iPad is trying to talk to anything on say 192.168, it should use ethernet.

Otherwise, it should use cellular.

If an app proxy is the wrong tool for this, then can you suggest any other way to accomplish this?

I could, just maybe, rewrite the low level libsrt library to use sockets provided from Network, where I can force traffic over cellular.

The problem would be that my HTTP rest requests, which use URLSession, would have no way of being forced over cellular.

Is there any library/framework that exists on top of Network that lets me make REST calls? If so, possibly doing all of this completely in app, i.e. forcing certain connections onto cellular while letting others do whatever the OS thinks is best, could be done.

The other thing that could work is if the OS had some way of knowing: “yeah, this device is on a LAN. But I know the LAN won’t send traffic out to the general WAN, so any connections that aren’t local can’t try to go the LAN.”

But I don’t believe it works that way… tell me if I’m wrong there.

I said "I could, just maybe, rewrite the low level libsrt library to use sockets provided from Network, where I can force traffic over cellular."

Actually, no, I can't. I thought Network could give me the equivalent of a socket, which I could fold back into libsrt, but it doesn't work that way.

So at the application level, I cannot do this.

The only choice appears to be something outside the app which forces the traffic onto a route through cellular.

If that's not an app proxy, what could it be?

There is a DHCP server on the local LAN to assign addresses to devices.

Do you actually need that? Or is this something you can’t control?

if my iPad is trying to talk to anything on say 192.168

Does that include multiple subnets? That is, does the DHCP server hand out a 192.168/16 address? Or does it hand out a 192.168.x/24 address? And in that case, are there resources on other 192.168.y/24 networks that you need to talk to?

can you suggest any other way to accomplish this?

Depending on your answers to the above, you could potentially do this with an off-the-shelf VPN. Specifically, this would work if you can configure the VPN to:

  • Always run over WWAN.
  • Claim the default route.
Is there any library/framework that exists on top of Network that lets me make REST calls?

Yes. TN3151 Choosing the right networking API talks about this, in the HTTP alternatives section.

The other thing that could work is if the OS had some way of …

The OS does have infrastructure like this, but it probably won’t help in this situation because:

  • You’re on Ethernet, not Wi-Fi.
  • The Ethernet does have external connectivity, just connectivity that you don’t want to use.
I thought Network could give me the equivalent of a socket, which I could fold back into libsrt, but it doesn't work that way.

Correct. But if you have some control over the BSD Sockets code you can force it to run over WWAN. Extra-ordinary Networking > Network Interface Techniques > Binding to an Interface.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

We have total control of our local network. It's convenient to plug in 10 to 20 ipads and let them just obtain addresses via DHCP, but if for example we needed to give pre-assign the iPad static IP addresses, we can do that.

If we need to put all these devices on some isolated subnetwork with no DHCP server we can do that. (I have no idea what the 192.168/x16 vs 24 distinction is or means but I'm sure we can do that too.) It's our local network.

In short, we can do any freakin' thing required on the local network that helps us crack this problem.

With that in mind, if you don't mind answering two questions you've raised now:

  1. Do you know of any off the shelf VPNs that can be configured in the way you describe?

  2. Going back the other direction: I can potentially rewrite libsrt (which is C/C++) to use sockets that only use cellular. I didn't think however that was possible on iOS (and Network was the only place I could do that).

If you could point me to sample C/C++ code or the specific APIs from C/C++ that let me open sockets that will only use cellular, I can take a stab at it.

My HTTP REST needs are quite modest, and I could probably roll something simple on top of Network to do those very few calls that absolutely have to be over cellular.

Given all the above, if no VPNs exist with the required capabilities, if the socket rewrite doesn't pan out, will the App proxy, which can detect if a route is local or not, and simply uses a Network connection of the required type to just relay traffic to/from the original location work?

Do you know of any off the shelf VPNs that can be configured in the way you describe?

No. But my expertise is in VPN APIs, not VPN products.

If you could point me [at code to] open sockets that will only use cellular

To start you off:

  • Extra-ordinary Networking > Network Interface Techniques > Binding to an Interface explains how to bind a socket to a specific interface.
  • Extra-ordinary Networking > Network Interface APIs > Network Interface Type explains how to identify the WWAN interface.

We have total control of our local network.

So what happens if you don’t deploy a DHCP server on that network?

I would expect that you’ll still be able to communicate with your iPads using link-local addressing [1]. And your iPhone will leave WWAN as the default route because it hasn’t got a routable address from Ethernet. Thus code running on the iPhone will automatically use WWAN for non-local destinations.

Extra-ordinary Networking > Network Interface Concepts explains these ideas in more detail.


I have no idea what the 192.168/x16 vs 24 distinction is

192.168/16 is CIDR notation for an IPv4 network with addresses in the range 192.168.0.0 through 192.168.255.255, and hence a subnet mask of 255.255.0.0, also known as a 16-bit prefix.

192.168/16 is one of the standard IPv4 networks. It’s 16-bit prefix yields roughly 64K IPv4 addresses, which is usually excessive, so most folks split it up into N small network. For example, my Mac on my home network reports this:

% ifconfig en0
en0: …
    inet 192.168.1.93 netmask 0xffffff00 broadcast 192.168.1.255
    …

The subnet mask is 0xffffff00, aka 255.255.255.0. That’s a 24-bit prefix, hence the network in 192.168.1/24.

And there could be 256-ish other networks, 192.168.2/24, 192.168.3/24, and so on, each with 256-ish IPv4 addresses.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Link-local addressing is a fundamental component of IPv6, and thus you’re better off if you write your code to support IPv6. However, Apple devices, and most other platforms, support it on IPv4 (via RFC 3927) so if you have to use IPv4 for other reasons it should still work.

test NEAppProxyProvider without MDM?
 
 
Q