NSURLSession DNS resolve not follows the NEDNSSettings

We have an app using NetworkExtension to handle network traffic, using NEPacketTunnelProvider, NEDNSSettings.

When the app works normally, system wide DNS requests will be sent to the DNS IP we set and enter our app.

No DNS requests will be send to the system's DHCP DNS IP

It works fine untill upgrade to iOS 14.5

We found that apps which using NSURLSession will not follow the DNS we set into NEDNSSettings, these apps will send 2 DNS queries, one to the Custom DNS IP we set,another to the DHCP DNS IP。
And the app only take the result which return by the DHCP config one.

Is this a BUG or some features ?

Replies

Regarding:

When the app works normally, system wide DNS requests will be sent to the DNS IP we set
and enter our app.

No DNS requests will be send to the system's DHCP DNS IP

Taking a step back for a moment; You should not be trying to handle all DNS queries on your device. That is not what the NEPacketTunnelProvider and NEDNSSettings APIs are built for. These APIs are built for a small sub set of DNS traffic that is important to your business and tunnel. If you wish to proxy system wide DNS traffic then you should look at NEDNSProxyProvider. Note that on iOS NEDNSProxyProvider requires a supervised device.

Regarding:

Is this a BUG or some features ?

Regarding the situation that you have described, please open a bug report if you believe you have found a bug. Please respond back with a Feedback ID.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Thanks, meaton.

The code may clarify the problem better 😀

Pseudo Code


NetworkExtension

Code Block
[[NEPacketTunnelNetworkSettings alloc] initWithTunnelRemoteAddress:@"<Remove_IP>"];
tunnel.DNSSettings = [[NEDNSSettings alloc] initWithServers:@"<DNS_IP>"];
tunnel.DNSSettings.matchDomains = @["example.com"]
tunnel.IPv4Settings.includedRoutes = @[[[NEIPv4Route alloc] initWithDestinationAddress:@"<DNS_IP>" subnetMask:@"255.255.255.255"],
[[NEIPv4Route alloc] initWithDestinationAddress:@"<Intranet_IP>" subnetMask:@"255.255.255.255"],]
// in the NetworkExtension all *.example.com will be resolved to <Intranet_IP>

Client App

Code Block
NSURL *url =[NSURL URLWithString:@"http://www.example.com/"]
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {/* ... */}];
[dataTask resume];


Trace

Let's say that www.example.com = <Real_IP>

Run the NetworkExtension

Run the Client App

The Client App lookup www.example.com to<DNS_IP> and the <Intranet_IP> return from the NetworkExtension

But another DNS query also sent out from Client APP and return the <Real_IP> from the DHCP DNS

Finally the Client App using the <Real_IP> to initialize the TCP connection

Finally the Client App using the <Real_IP> to initialize the TCP connection

Okay. This traffic for example.com in the client app must not be going over through your tunnel? The reason I am saying this is because if this HTTP and DNS request was being handled by the tunnel I suspect that this would not be an issue. For example the DNS request and HTTP would be under your control because you have issued example.com as domain that is of business importance to your tunnel via NEDNSSettings.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hi!

Just wanted to mention that I've also bumped into this exact issue (duplicate queries to different DNS servers), although I'm NOT trying to filter all DNS traffic: I was able to reproduce DNS queries "leaking" past my tunnel even when matchDomains in my NEDNSSettings contains just a few specific domains that I want to be resolved through the tunnel.

In my case, this seems to only reproduce in third-party apps, Safari for example doesn't exhibit this behaviour. I've filed a bugreport: FB9126588 and attached a simple reproducer app and tunnel to it.

@ngorskikh I took a look at your sample project on FB9126588 and I tested this with a local NEPacketTunnelProvider sample project I wrote and I was able to claim the DNS packets for the NEDNSSettings in the SendRequestsSampleApp.zip app. Well, I only tested this with the example.org subdomain set, but this seemed to work. I would build out your NEIPv4Settings and add at least one NEIPv4Route and test this further with the readPacketsWithCompletionHandler method on the NEPacketTunnelFlow for your provider. If you are still experiencing issues after WWDC, open a TSI and I can dig into this further with you.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com