It is clear that Packets that are read from NEPacketTunnelFlow are meant to be sent over a tunnel connection to a remote server for injection into a remote network. They are not meant to be dropped or re-injected back into the system.
In my usecase:
-
NEPacketTunnelProvider is separate process. which reads the packet using packetFlow.readPacketObjects
-
Send it over to other process i.e privileged helper(Non-bundle/command line tool/non sandboxed) via UDS IPC.
-
Helpers send to to remote tunnel and return back the packet to NEPacketTunnelFlow via same IPC.
-
NEPacketTunnelProvider uses packetFlow.writePacketObjects to inject packets.
Things works fine. We don't distribute it via Appstore.
We are now attempting to implement a on device bypass mechanism from helper tool side. Could you please suggest if there is any approach I could try, even if it involves proceeding at my own risk?
instead of tunneling certain webstites to a remote VPN server, I want to allow those traffics to go directly
Yeah, we don’t support that. And by “we” I mean “DTS”, specifically. One of my erstwhile colleagues wrote TN3120 that talks about this in general terms, but I can be more specific here.
IMPORTANT The ‘tunnel what you claim’ issue described below is only one example of the problems you might encounter when you use a packet tunnel provider for unsupported things. There are others [1].
In general, Network Extension VPN providers (packet tunnel and app proxy) are expected to tunnel all traffic that they claim. So, in the case of a packet tunnel in destination IP mode [2], if your tunnel claims a destination network then it’s expected to forward traffic for that network through the tunnel.
DTS has, over the years, received a lot of cases like this, where folks claim a wide range of destination networks and then try to send some traffic through their tunnel and some traffic directly. This rarely ends well, and it’s not something we support.
This is mostly a problem on iOS, where folks really want to use a packet tunnel provider to bypass the privacy limitations imposed by other provider types. macOS is more forgiving on that front. In most cases you can get around this problem on macOS by moving up a layer to implement a transparent proxy.
In terms of unsupported techniques, I strongly recommend that you avoid trying to re-inject packets. I’ve never found a way to do that reliably.
One technique that typically works is to run your own TCP/IP stack and use that to turn the packets back into flows. You can then use standard networking APIs to proxy those flows. However, this approach has its own problems, which is why DTS doesn’t support it.
The ‘tunnel what you claim’ explanation above was largely copy’n’pasted from a response I sent on a recent DTS case, where the developer is doing just that and now they’ve stumbled into a horrible pitfall that causes things to fail badly in some very specific network environments.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] The other commons issue I see is folks running into problems trying to use VPN On Demand to implement Always-on VPN. That’s another thing that rarely ends well )-:
[2] As opposed to source application mode, which is one form of per-app VPN.