Network Extension flow source

How is it possible to create connection from a network extension (com.networkExtension1), such that, when intercepted in another network extension (com.netext2), the other network extension will see the connection as if it is made by the original source application?

This is a snippet from console logs:

com.networkExtension1 (0): Flow 2954186858 is connecting

com.networkExtension1 (2954186858): New flow: NEFlow type = stream, app = org.mozilla.firefox, name = , 192.168.0.228:0 <-> 35.209.241.59:443, filter_id = , interface = en0

com.networkExtension1 [Extension com.networkExtension1]: Calling handleNewFlow with TCP org.mozilla.firefox[{length = 20, bytes = 0xa2a22e10254b79501b5eda722e4bc1f5acfa70cf}] remote: 35.209.241.59:443 interface en0

com.networkExtension1 NESext handleNewFlow called

com.networkExtension1 [Extension com.networkExtension1]: provider accepted new flow TCP org.mozilla.firefox[{length = 20, bytes = 0xa2a22e10254b79501b5eda722e4bc1f5acfa70cf}] remote: 35.209.241.59:443 interface en0 com.networkExtension1 [C72 1DFFC5DD-817A-4B66-836F-12D80F038F41 IPv4#1a7fd949:443 tcp, indefinite, context: Default Network Context, proc: E43CF8FA-B973-3B6F-A3E7-B783A62940F0] start com.networkExtension1 [C72 IPv4#1a7fd949:443 initial path ((null))] event: path:start @0.000s com.networkExtension1 [C72 IPv4#1a7fd949:443 waiting path (satisfied (Path is satisfied), interface: en0, ipv4, dns, flow divert agg: 2)] event: path:satisfied @0.000s, uuid: F6A32047-4E9A-4420-A81A-58CCD66D8BA9

com.netext2 (0): Flow 3811671999 is connecting

com.networkExtension1 [C72 IPv4#1a7fd949:443 in_progress socket-flow (satisfied (Path is satisfied), interface: en0, ipv4, dns, flow divert agg: 2)] event: flow:start_connect @0.001s

com.netext2 (3811671999): New flow: NEFlow type = stream, app = com.networkExtension1, name = , 192.168.0.228:0 <-> 35.209.241.59:443, filter_id = , interface = en0

com.networkExtension1 nw_connection_report_state_with_handler_on_nw_queue [C72] reporting state preparing

com.netext2 [Extension com.netext2]: Calling handleNewFlow with TCP org.mozilla.firefox[{length = 20, bytes = 0xa2a22e10254b79501b5eda722e4bc1f5acfa70cf}] remote: 35.209.241.59:443 interface en0 com.netext2 Flow HANDLER: 4804657760 - TCP org.mozilla.firefox[{length = 20, bytes = 0xa2a22e10254b79501b5eda722e4bc1f5acfa70cf}] remote: 35.209.241.59:443 interface en0

In this case we have 2 network extensions: com.networkExtension1 (network extension 1), com.netext2 (network extension 2)

This is the scenario:

  1. one connection is made by Firefox browser (the browser is not important)
  2. the connection is intercepted by com.networkExtension1
  3. the connection is accepted by network extension 1
  4. a connection is made from network extension 1
  5. a new flow is generated (Flow 3811671999)
  6. (3811671999): New flow: NEFlow type = stream, app = com.networkExtension1 (here the app is network extension 1)
  7. in network extension 2 (com.netext2) in handleNewFlow function tcpFlow description is "org.mozilla.firefox" (not com.network extention1)

Why the same flow (3811671999 from example) once is displayed from network extension 1 and once from com.mozilla.firefox? It is possible to set metadata for a new connection as parameter in NWConnection? If yes how we can do this?

Why the same flow (3811671999 from example) once is displayed from network extension 1 and once from com.mozilla.firefox? It is

In this case the com.networkExtension1 is expected to be identified as handling a flow because it is now proxying the connection. As to why there are two identified flows here, that may be a bug or may be a result of the behavior of how the client is working with that flow. For example, it looks like there are two different flow IDs here (3811671999 associated with com.networkExtension1) and then (4804657760 associated with org.mozilla.firefox), so these may be different flows altogether.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hi Matt,

Thanks for your quick answer. If the flow is accepted by network extension 1 a new connection will be made and in network extension 2 we should receive connections from network extension 1. No connections are received in network extension 2 from network extension 1.

How it is possible to not see connections from network extension 1 in network extension 2?

No connections are received in network extension 2 from network extension 1. How it is possible to not see connections from network extension 1 in network extension 2?

It looked like that is what was happening here:

com.netext2 (3811671999): New flow: NEFlow type = stream, app = com.networkExtension1, name = , 192.168.0.228:0 <-> 35.209.241.59:443, filter_id = , interface = en0

Is that wrong?

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hi Matt,

The mentioned log is not from handleNewFlow(_ flow: NEAppProxyFlow) function. This is displayed in console log, but it is not my log (I suppose that was generate automatic by macOS).

com.netext2 (3811671999): New flow: NEFlow type = stream, app = com.networkExtension1, name = , 192.168.0.228:0 <-> 35.209.241.59:443, filter_id = , interface = en0 (not my log)

In network extension 2 in handleNewFlow function we no receive connections from network extension 1. I expect in the network extension 2's handleNewFlow to receive connections from network extension 1, yet this log: "Calling handleNewFlow with TCP org.mozilla.firefox[{length = 20, bytes...", appears to indicate that the flow is received directly from the Firefox browser.

Every time when in handleFlow function is logged the flow.metadata.sourceAppSigningIdentifier, the org.mozilla.firefox (Firefox browser) is displayed. (network extension 1 is an internet security solution)

The mentioned log is not from handleNewFlow(_ flow: NEAppProxyFlow) function. This is displayed in console log

Ah, okay, now I understand.

Regarding:

yet this log: "Calling handleNewFlow with TCP org.mozilla.firefox[{length = 20, bytes...", appears to indicate that the flow is received directly from the Firefox browser.

What is the goal of Network Extension 2? If it is proxy flows from userland applications, like the FireFox browser, then it sounds like this is working as you would want it to. If Network Extension 2 were to see an outbound flow handled by Network Extension 1, then there would be no identifier that describes the originating app. My point is that is sounds like the current scenario is the behavior that you would want in Network Extension 2 when proxying userland application flows.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hi Matt,

Yes this is the desired behaviour to receive in network extension 2 the source application. I tested with 2 anti-viruses and in network extension 2 we have the following results:

-> in both of the scenarios the network extension 1 accepts the flow -> when network extension 1 is from an antivirus solution, network extension 2 sees the source as "Firefox". But when network extension 1 is from another, different, antivirus solution, network extension 2 sees the source as "network extension 1".

Is there an explanation for the different results which were obtained?

In my testing I have observed Network System Extension 2 recognize Network System Extension 1 when 1 is handling a flow. This is because Network System Extension 1 was installed and started before Network System Extension 2. If you feel that you want more clarification here, then please open a bug report and respond back with your Feedback ID.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Network Extension flow source
 
 
Q