How to resolve DNS query locally using Network Extension?

The client application is responsible for tunneling the traffic based on host names. Hostname based applications are behind a private network and are not accessible from public internet. So, in order for us to tunnel the traffic based on host names, we are in a position to resolve the IP addresses locally on the client side, before tunneling the traffic. Please note that there are no custom / private DNS servers that can help us to resolve the IPs.

So essentially, we might have to resolve the DNS queries locally on the client for these specific set hostnames and then establish a connection to the remote endpoint in order to tunnel the traffic. We are kind of lost in weeds trying to identify a better solution to attain this functionality. Below is the approach that we are looking to give a try and would appreciate your inputs on what would be the best way to go about this.

Given that, we are establishing a tun interface on the PacketTunnelProvider to tunnel the traffic and we make use of the existing tun interface to filter out the DNS packets and resolve the host names programmatically.

Based on our research, AdBlock for iOS (https://adblockforios.com) also uses a VPN extension to resolve and blackhole the domain name based on the hosts list. So this is more in line with what we trying to achieve except for the fact that we would need to resolve the hostname rather than black holing it.

We were able to implement this and capture the DNS packets. We constructed the response packet for the DNS queries on the network extension and write it back to the packetflow. But post resolution the data packets are not flowing into the tun interface, instead we keep getting the DNS query packets on a loop.

Below is our implementation

    //setTunnelNetworkSettings

    let dnsSettings = NEDNSSettings(servers: ["8.8.8.8"])

    dnsSettings.matchDomains = ["apple.com"]

    dnsSettings.matchDomainsNoSearch = true

    settings.dnsSettings = dnsSettings

On the DNS resolver side, the code snippet is uploaded in the gist.

Even after this implementation, we are facing issue as mentioned above. Can you please help us by providing any insights on the issue and possible solution to get this implemented in the right way.

Hostname based applications are behind a private network and are not accessible from public internet.

This is a good start. Most folks with questions like yours are doing something silly, but this case is pretty much what the NE packet tunnel provider architecture was designed for. For more background on this, see TN3120 Expected use cases for Network Extension packet tunnel providers.

So essentially, we might have to resolve the DNS queries locally on the client for these specific set hostnames

Are these host names in some common domain?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Oh, hey, it turns out I’ll be helping aravindh23 in a different context.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

How to resolve DNS query locally using Network Extension?
 
 
Q