Intercepting VPN traffic with NEFilterPacketProvider

Hi there,

I'm exploring the possibilities of intercepting VPN traffic with NEFilterPacketProvider on macOS. After running a few tests it looks like NEFilterPacketProvider can intercept packets on virtual interfaces with Raw IP link-layer only. These interfaces are created by built-in IKEv2/IPsec personal VPN or by third-party VPN clients based on NEPacketTunnelProvider (e.g. ProtonVPN). I could see that tcpdump recognizes the data link type of these interfaces as Raw IP:

# tcpdump -L -i utun2
Data link types for utun2 (use option -y to set):
RAW (Raw IP)

Other virtual interfaces, I tested in Catalina 10.15.7, don't seem to be available for interception. For instance, an interface with BSD loopback link-layer created by PulseSecure VPN:

# tcpdump -L -i utun3
Data link types for utun3 (use option -y to set):
  NULL (BSD loopback)

or an interface with PPP link-layer created by built-in LT2P/IPsec personal VPN:

# tcpdump -L -i ppp0
Data link types for ppp0 (use option -y to set):
  PPP (PPP)

I reviewed Apple Developer Documentation but didn't find any clues about which data link-layer types NEFilterPacketProvider should support.

I think it is a severe limitation if NEFilterPacketProvider is able to monitor only virtual interfaces with Raw IP link-layer. How could we use it reliably if a user might accidentally/intentionally bypass it by very simple installation of built-in LT2P/IPsec VPN client?

A workaround suggestion would be much appreciated.

Answered by Systems Engineer in 693614022

BSD loopback (utun4) - packets are NOT intercepted

There's no documentation on this specifically for NEFilterPacketProvider, but on the NEFilterDataProvider side, loopback traffic will not hit the filter at all unless you specify it through the NENetworkRules, so this may provide some insight here.

As to your overall questions, I would open an Enhancement Request, or a bug report if you feel this does not work as it should.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

NEFilterPacketProvider is built to secure traffic via a route that will eventually egress the machine. Are you wanting to filter the traffic that is being sent through loopback? If so, this sounds like a content filter mechanism, and I would take a look at NEFilterDataProvider where you can evaluate the loopback interface specifically with NENetworkRule. Keep in mind, it will only be at the connection level, not the packet level.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hi Mat,

I want to filter the packets that are being sent through a virtual interface created by a VPN client. If I go to System Preferences -> Network and create IKEv2 client, NEFilterPacketProvider can intercept the traffic before the client starts encryptying it. But this is not true for LT2P/IPsec client:

# scutil --nc list
* (Disconnected)   A8BD8B26-2F38-4464-BD4B-87CC64BC556C   PPP --> L2TP   "VPN (L2TP)"   [PPP:L2TP]

This issue is easily reproducible on Catalina for some other third-party VPN clients.

I'm concerned that our security tool won't be able to filter or inspect traffic for apps sending the traffic through VPN servers as NEFilterPacketProvider doesn't seem to be compatible with a few VPN clients I tested.

I want to filter the packets that are being sent through a virtual interface created by a VPN client.

If a user has installed a VPN to secure traffic for a specific set of goals or business reasons, then this traffic that is being claimed by the tunnel and should should be left as is. If you want to filter traffic, use one of our Content Filter APIs.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hi Mat,

Let me clarify something. NEFilterDataProvider is designed to intercept TCP/UDP traffic only. It doesn't allow to block traffic on the Internet layer if a specific IP address is compromised. This is the main reason why we can't leave corporate/private VPN traffic as it is.

Anyway we were expecting that NEFilterPacketProvider could intercept all traffic passing through existing interfaces like tcpdump does. Do you confirm that there's a bug/limitation in a way it filters outbound traffic? If yes, we won't be able to use it for our business purposes until this issue is resolved.

Sincerely, Slava

Anyway we were expecting that NEFilterPacketProvider could intercept all traffic passing through existing interfaces like tcpdump does. Do you confirm that there's a bug/limitation in a way it filters outbound traffic?

The Network Extension APIs were created to handle UDP and TCP, and in some cases will handle ICMP. However, last time I checked raw IP traffic was not received on these APIs. Double check the packets that are sent through NEFilterPacketProvider, but if you do not see IP packets then I would open an Enhancement Request for this feature. Please follow up with your Feedback ID.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hi Mat,

It's a good idea to check whether NEFilterPacketProvider intercepts packets sent via raw and bpf sockets. But the scenario we are discussing is a bit different. I send HTTP traffic to interfaces with different data link-layers.

My findings are as follows:

  • Ethernet (en0) - packets are intercepted
  • Raw IP (utun3) - packets are intercepted
  • BSD loopback (utun4) - packets are NOT intercepted
  • PPP (ppp0) - packets are NOT intercepted

The question is this: why NEFilterPacketProvider intercepts HTTP traffic generated by Safari only on two interfaces of four?

Slava Dubrava
Senior Software Developer
Akamai Technologies
Accepted Answer

BSD loopback (utun4) - packets are NOT intercepted

There's no documentation on this specifically for NEFilterPacketProvider, but on the NEFilterDataProvider side, loopback traffic will not hit the filter at all unless you specify it through the NENetworkRules, so this may provide some insight here.

As to your overall questions, I would open an Enhancement Request, or a bug report if you feel this does not work as it should.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

I have tested NEFilterDataProvider and it does intercept the traffic sent to the interfaces mentioned above. It makes sense as they are not configured with the loopback address (127.0.0.1 or ::1).

The bug report number is FB9735800.

Thank you for your assistance, Mat.

Intercepting VPN traffic with NEFilterPacketProvider
 
 
Q