Change the IP / Port of a packet by NEAppProxyProvider in macOS

Is it possible to change the IP / Port of a packet that connects to a specific address using the API provided by "NEPacketTunnelProvider" or "NEAppProxyProvider" when a user tries to connect to a specific address in macOS?

More specifically, when a user attempts to connect to a remote ip / port using a protocol such as Telnet, SSH, or FTP, is it possible to change the ip / port by catching the outbound packet information of the connection?

If you provide such an API in "NEPacketTunnelProvider" or "NEAppProxyProvider", what is its API?

Replies

I want to start by saying that Network Extension packet tunnel and app proxy providers are not intended to be a general-purpose ‘munge all the packets’ facility. Rather, they are there to allow folks to implement custom VPN transports. It’s possible that you might be able to use them for other tasks, but you’re likely to run into snags because that’s not what they were designed for.

Next, be aware that per-app VPN (of which app proxy providers are one example) has very specific deployment limitations, that is:

  • On iOS it can only be deployed via MDM

  • On macOS it can only be deployed via a configuration profile (which is typically deployed via MDM but you could do that manually)

Is that in line with your product requirements? If not, you can rule out that avenue of attack completely.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

The requirements of the products we develop are as follows.


Example Situation

1. The destination address the user attempts to contact: 10.10.10.20:1000

2. When the user tries to connect, change the destination address of the packet to the local address: 127.0.0.1:54321

3. The local module(127.0.0.1:54321) audit user packets and connect to the original destination address.

4. The local module(127.0.0.1:54321) relay user packets to the original destination address.


Desired result

- The user recognizes that he or she is connected to the original destination address (10.10.10.20:1000).


According to you, it seems difficult to implement the requirements we want to develop with the Network Extension API.

Thanks for the extra info but I was hoping you’d address my question as to whether the restrictions imposed by per-app VPN are in line with your product’s expected deployment scenarios.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Is there any way on MacOS, I mean at all, to generically handle packet routing in user space? Like the OP, all I'm seeking is a way to transparently handle TCP connections so I can pass them through a transparent proxy globally or on a per-app basis. I've been researching for weeks now trying to port a content filter I've written and here's what I've come up with.


- NKE's, which you're not allowed to use without special permission and in another forum post, you've confirmed these are getting deprecated so it's wasted effort to start into this now.

- Network extensions (packet tunnel/per-app proxy). You've mentioned here that you need to be on a managed profile/configuration for these to work. Not an acceptable constraint for mass/arbitrary distribution.

- Everything else that should work is purposely broken. Raw sockets won't receive TCP payloads, divert-to in pf is a broken implementation, berkely packet filter system intentionally omits the feedback prevention mechanism so you can only read or write but not both. Divert sockets are a broken implementation.

People are looking to me to answer whether or not to invest tens of thousands of dollars in trying to reach users of your platform. Can you please advise if my current conclusion is correct? That is, the return on investment is either unacceptable, or it's maybe even impossible to reach a product that is viable and will continue to function? Managed devices is not acceptable, writing a NKE only to have it get deprecated and we start from scratch in the next handful of years also isn't acceptable. So I'm just hoping I'm missing something here before I return to the people in charge and tell them to burn the project.


Thanks for your time.

Is there any way on MacOS, I mean at all, to generically handle packet routing in user space?

That depends on your specific requirements. You wrote:

pass [connections] through a transparent proxy globally or on a per-app basis

This last point makes per-app VPN the most obvious contender. Whether this is a contender depends on your security model. Per-app VPN was designed for an enterprise environment, where the connection won’t work without the VPN (it’s otherwise blocked by the enterprise firewall). However, it sounds like you’re actually trying to create a security product — like a personal firewall or a data egress checker — where the connection will work without your product but you don’t want it to. In that case per-app VPN is a non-starter, and your best option — albeit not a good option — is an NKE.

Creating a new NKE today is, as you’ve noted, likely to be a compatibility problem sometime down the line. From a technical perspective your best option would be to:

  • Minimise the code within the kernel itself

  • Isolate the bulk of your user space code from the specific mechanism used to catch the connections, making it easier to adapt to future changes

IMPORTANT Deploying an NKE requires a KEXT-enabled Developer ID. If you go down this path, I recommend that you apply for the early. Before applying, file an enhancement request describing what you’d like to do and why an NKE is your only option right now. I’d appreciate you posting that bug number here so that I can add it to my records.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
I have the similar scenario.

Can you point me to the APIs for NEAppProxyprovider and NEPacketTunnelProvider which can be used to divert the ip/port of outgoing packets