I would like something like the folllowing:
Intercept and modify all DNS traffic (port 53)
Intercept and modify TCP and UDP flows going to a specific subnet.
An NEAppProxyProvider seems like an obvious choice since you can setup various rules for what you want to intercept. For example that you want to intercept traffic going to specific subnets and everything going to port 53. Also, it intercepts TCP flows rather than raw IP packets which is simpler. However:
According to the documentation for NEAppProxyProviderManager (https://developer.apple.com/documentation/networkextension/neappproxyprovidermanager ), an AppProxy can only be used for per-app VPN routing. So I guess an AppProxy is not an option given that I need to intercept traffic from all applications?
There is a (to me) somewhat mysterious class NETransparentProxyManager (https://developer.apple.com/documentation/networkextension/netransparentproxymanager ). It is not clear to me how NETransparentProxyManager is different from NEAppProxyProviderManager. But I assume that NETransparentProxyManager can also only be used to intercept traffic per-app?
One thing that puzzles me is that if NEAppProxyProviderManager and NETransparentProxyManager can only be used to intercept traffic on a per App basis, then why does NEAppProxyProvider (https://developer.apple.com/documentation/networkextension/neappproxyprovider ) have a routingMethod member (https://developer.apple.com/documentation/networkextension/netunnelprovider/1405979-routingmethod )? Shouldn’t this value always be ‘sourceApplication’? Perhaps it is because it is in the super class NETunnelProvider which is shared with NEPacketTunnelProvider. I did try to create an NEAppProxyProvider with an NETransparentProxyManager and the routingMethod member did get a value of ‘sourceApplication’
I cannot intercept all traffic to port 53 unless I intercept all subnets.
If there is some traffic to the intercepted destination IP subnets which I don’t want to intercept anyway, I will have create my own sockets and send the data from the raw TCP and UDP packets on them (which may be challenging as the local ports and source IPs may change when doing this)
One of the differences between NEAppProxyProviderManager and NETransparentProxyManager is that NEAppProxyProviderManager can be used with NEAppRule's to configure how the proxy is enabled and which app's activate the network configuration. NETransparentProxyManager does not have this capability as it's intention is to be more general purpose.There is a (to me) somewhat mysterious class NETransparentProxyManager (https://developer.apple.com/documentation/networkextension/netransparentproxymanager ). It is not clear to me how NETransparentProxyManager is different from NEAppProxyProviderManager. But I assume that NETransparentProxyManager can also only be used to intercept traffic per-app?
NETransparentProxyManager should be able to claim traffic for many different applications on the system using NENetworkRule's with NETransparentProxyNetworkSettings. As to why NEAppProxyProvider has a property of routingMethod, yes, you are correct that this is because this class shares a base class of NETunnelProvider, just like NEPacketTunnelProvider does.One thing that puzzles me is that if NEAppProxyProviderManager and NETransparentProxyManager can only be used to intercept traffic on a per App basis, then why does NEAppProxyProvider (https://developer.apple.com/documentation/networkextension/neappproxyprovider ) have a routingMethod member (https://developer.apple.com/documentation/networkextension/netunnelprovider/1405979-routingmethod )? Shouldn’t this value always be ‘sourceApplication’? Perhaps it is because it is in the super class NETunnelProvider which is shared with NEPacketTunnelProvider.
First, as I always do, I recommend that you do not use a packet tunnel as a means to capture and re-route all DNS traffic. If you find yourself in a situation where you are trying to capture a large amount of domains in your match domains list in your packet tunnel NEDNSSettings then there are mechanisms for doing this on macOS and iOS, such as NEDNSProxyProvider. (Note that for iOS NEDNSProxyProvider requires MDM) Packet Tunnels were not built as a means to claim and reroute all DNS traffic and you will most likely run into endless edge cases trying to get this right.If I cannot use an NEAppProxyProvider to intercept traffic from all applications, I guess my only option is to create a PacketTunnel and then deal with the raw IP packets?
If you are not constrained by version of macOS you want to support then I would recommend using NETransparentProxyProvider to fulfill both of your TCP and UDP needs stated at the top of your post. If you need to support TCP / UDP flows earlier than macOS 11 then you can still use NEAppProxyProvider / NETransparentProxyManager but you will need to proxy all of your flows and will not have the ability to return false and let the OS handle the flow you do not wish to proxy.
Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com