is it possible to redirect traffic after filtering using network extensions?

Hi,


I am looking to build an app where incoming/outgoing traffic to certain ports/ip addresses on a mac can be redirected to another machine. I understand that I can filter traffic using the content filter NE apis based on the port/ip address. However,the content filter apis only allow to either block or accept the packets whereas I want to redirect them instead of dropping them.Is it possible to do this ?

In linux i can do this using iptables nfqueue functionality very easily. Is there any alternative which provides such functionality in mac osx?


Any help in this regard is appreciated.

Replies

macOS 10.15 added three new Network Extension system extensions to macOS:

  • Content filter

  • Transparent proxy

  • Packet filter

You’ve explored the first, but it sounds like you need to look at the other two. I recommend that you start by watching WWDC 2019 Session 714 Network Extensions for the Modern Mac, which is a good overview of how these bits fit together.

Share and Enjoy

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

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

ps DTS is closed 21 Dec through 1 Jan.

Thanks for the response Quinn.

I have watched that video you are referring to. Few followup comments/questions:

1. By packet filter are you are referring to NEFilterPacketProvider class?Very little documentation exists for this class. Do we have any sample code for this class? How does one use NEFilterPacketContext ?


2. With respect to the Transparent proxy approach, I dont believe it is suitable for us because we would need packet level filtering.

For e.g: We may need to filter traffic based on TCP flags down the line, which I dont think is possible with the NEAppProxyProvider class since it only deals with flows. Is my understanding correct?



1. By packet filter are you are referring to

NEFilterPacketProvider
class?

Yes.

Do we have any sample code for this class?

No.

How does one use

NEFilterPacketContext
?

The basic idea is as follows:

  1. The system calls your packet handler function (

    NEFilterPacketHandler
    ) for every packet.
  2. Your function should inspect the packet to decide how to handle it, and then return an appropriate verdict (

    .allow
    ,
    .drop
    ,
    .delay
    ).
  3. In the case of

    .delay
    , before you return from your packet handler function, you should call
    delayCurrentPacket(_:)
    to get a packet object (
    NEPacket
    ).

This unusual design exists for efficiency reasons. A packet handler function is very ‘hot’, and thus we don’t want to allocate a packet object for every packet, only for those that you choose to delay.

The doc comments in

<NetworkExtension/NEFilterPacketProvider.h>
do a pretty good job of filling in the details.

2. With respect to the transparent proxy approach, …

NEAppProxyProvider
class … only deals with flows. Is my understanding correct?

Correct.

Share and Enjoy

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

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

Thanks once again Quinn. I have one more query wrt the packetFilter mechanism:


In the NEFilterDataProvider class description, it says "The sandbox prevents the Filter Data Provider extension from moving network content outside of its address space by blocking all network access, IPC, and disk write operations."


Are any similar restricitons also applicable to the packet handler function? My implementation is dependent on whether I can transfer the packet out to another module for detailed processing.

My idea was to do the following:

1. In packetHandler, parse the packet for ethernet ,ip and tcp headers to find if packet needs to be redirected. Default action will be allow.

2. If the packet is to be redirected , delay the packet and use ipc or another socket to transfer the NEPacket object for further processing to another module.

3. Once the final verdict for the packet comes, allow or drop the packet from the handler.



Is this possible?Or are there restrictions on this too, similar to NEFilterDataProvider?

use ipc or another socket to transfer the

NEPacket
object for further processing to another module

Packet filter providers run with the App Sandboxed enabled, which limits their access to IPC constructs. However, it is possible to do some IPC from a sandboxed process [1], and I can’t see any reason why that’d fail in this specific context.

Share and Enjoy

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

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

[1] The major exception here is filter data providers on iOS, which run in a very tight sandbox.

Thanks for the response Quinn.


While experimenting with packet filters, I came upon a strange error where the application suddenly stopped initializing with the error "SimpleFirewall: [1203:36222]:failed to register with the provider: Couldn't communicate with a helper application".

I removed all my changes, deleted the related files and folders and downloaded the sample code again , but still the error persists. So much so, that even a fresh copy of the sample code is throwing the same error. On looking around for this issue, it appears it is kind of a known issue(47227781) and was fixed in xcode11, but I am using the latest version of xcode 11.3.1 and I am still seeing this issue.


Is there a workaround for this issue? Has this been not solved yet?

Did a restart clear the error?

Share and Enjoy

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

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

No Quinn. Restart has not helped, I am still having the same issue.

I am still having the same issue.

Bummer. I’m not sure what might be causing this. Given that you’ve already confirmed that this isn’t a code problem, it is presumably something to do with your environment. My next step would be to test that presumption by installing the app on a freshly installed machine (I use a VM for this, and just restore to a snapshot taken just after installation).

Share and Enjoy

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

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

I also faced the same issue. The solution is to directly call stopFilter functionality (remove the filter configuration). It happens when for some reason you are unable to remove filter configuration.


Regards,

~Charu

Hi,
I want to write an application and a system extension to redirect the outgoing network traffic through the application.
My design is as follows:
  1. Create a thread as proxy server listener on a port (e.g., 1234). So App waits for connections on 127.0.0.1:1234

2. Whenever outgoing traffic is encountered on a specific port, say 567, this traffic should be diverted to proxy listener in the application. Application takes care of sending it out after the processing.

Can somebody help me in pointing the relevant APIs in Transparent Proxy and Packet Filter. If any sample code is available, please share with me.