Custom DNS server in personal VPN app

Hi,

I am developing a VPN application for professional use and I have a problem with DNS redirection. I want to use my own DNS server, so according to Apple documentation, I wrote this piece of code to redirect specific URLs to my DNS server. But it doesn't seem to work. My DNS server is never reached.


import NetworkExtension

open class Vpn {
    let manager = NEVPNManager.shared()

    public func setProtocol(vpnProtocol: NEVPNProtocol, vpnError: @escaping((_ error: Error?) ->())) {
        manager.loadFromPreferences(completionHandler: { [unowned self] error in
               if let errorVpn = error {
                 print("[Vpn.setProtocol] - Load From Preferences error: \(errorVpn)")
                       vpnError(errorVpn)
            }

            self.manager.protocolConfiguration = vpnProtocol
            self.manager.isEnabled = true
                self.manager.localizedDescription = "CustomVPN"

            let evaluationRule = NEEvaluateConnectionRule(matchDomains: ["url1.com", "url2.com"], andAction: .connectIfNeeded)
                evaluationRule.useDNSServers = ["***.***.***.***"]
    
            let onDemandRule = NEOnDemandRuleEvaluateConnection()
                onDemandRule.connectionRules = [evaluationRule]
    
            self.manager.onDemandRules = [onDemandRule]
                self.manager.isOnDemandEnabled = true

            self.manager.saveToPreferences(completionHandler: { error in
                    if let errorSaving = error {
                     print("[Vpn.setProtocol] - Save To Preferences error: \(errorSaving)")
                        vpnError(errorSaving)
                    }
            })
        })
    }
}


And

vnpProtocol = NEVPNProtocolIKEv2()


I'm using Swift 5 and testing on iOS 13.4.1


I hope that someone could help me.


Thanks,


IDNSTW

Replies

Does your VPN connect and start as normal but just ignores the useDNSServers property?

If you have your personal VPN off, and use NSURLSession to try and connect to one of these URLs from the matchDomains array from within the context of your iOS app, do you see the VPN kick on?


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

Yes, my VPN connects and starts correctly and just ignores useDNSServers. And when I shut down my personal VPN and use one of the URLs from the matchDomains, the VPN starts correctly.

OK, so the NEEvaluateConnectionRule is working to trigger on the VPN, that is good. Are you able to detect what DNS servers are being used for resolution on these URLs? If so, are they previously cached DNS servers?


Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

No, I am not able to detect what DNS servers are used. I am just able to get the system DNS servers with this code:


- (NSString *) getDNSAddressesStr {
    NSMutableString *addressStr = [[NSMutableString alloc]initWithString:@"DNS Addresses \n"];

     res_state res = malloc(sizeof(struct __res_state));

     int result = res_ninit(res);

     if ( result == 0 )
     {
         for ( int i = 0; i < res->nscount; i++ )
         {
             NSString *s = [NSString stringWithUTF8String :  inet_ntoa(res->nsaddr_list[i].sin_addr)];
             [addressStr appendFormat:@"%@\n",s];
             NSLog(@"%@",s);
         }
     }
     else
         [addressStr appendString:@" res_init result != 0"];

     return addressStr;
}


For information, this VPN application provides access to private URLs. These private URLs can only be resolved through the VPN and its DNS server.

Currently, when I try to access these URLs, I get the error: "Safari cannot open the page because the server cannot be found."

Take a packet trace from your iOS device to see what DNS servers are being used and try to work that backwards. As a note, unless you have manually setup your active Wi-Fi network to point at an explicit DNS server, you may not be getting the DNS server you expected from that code you posted. You may be getting the nearest access point addres that is acting as your DNS. You could lookup from that AP what is being used as the resolving address though.




Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com