如何在iOS 11中使用NEDNSProxyProvider

vsdwdz23  于 2022-12-24  发布在  iOS
关注(0)|答案(1)|浏览(211)

在网络方面,DNS代理是iOS 11最大的功能之一。但他们没有提供太多关于它的文档或示例。在它上面有一个talk,他们刚刚描述了DNS代理的功能。
我想创建一个它的工作示例,但到目前为止还没有成功。所以我创建了一个具有DNS代理权限的网络扩展,并添加了一个DNS代理提供程序。下面是代码:

class DNSProxyProvider: NEDNSProxyProvider {
    let defaults = UserDefaults(suiteName: "group.com.securly.dnsProxy")

    override init() {
        NSLog("QNEDNSProxy.Provider: init")
        super.init()
        // +++ might want to set up KVO on `systemDNSSettings`
    }

    override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) {
        NSLog("QNEDNSProxy.Provider: start")
        // self.defaults?.set("DidStart", forKey: "DidStart")
        completionHandler(nil)
    }

    override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
        NSLog("QNEDNSProxy.Provider: stop")
        completionHandler()
    }

    override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
        NSLog("QNEDNSProxy.Provider: new flow (denied)")
        // self.defaults?.set("DidHandleNewFlow", forKey: "DidHandleNewFlow")
        return true
    }

}

然后在AppDelegate中,我声明一个NEDNSProxyManager并将其用作:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let manager = NEDNSProxyManager.shared()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        self.enable()
        return true
    }

    private func enable() {
        self.update {
            self.manager.localizedDescription = "DNSProxySample"
            let proto = NEDNSProxyProviderProtocol()
            // proto.providerConfiguration = +++
            proto.providerBundleIdentifier = "com.securly.dnsProxy"
            self.manager.providerProtocol = proto
            self.manager.isEnabled = true
        }
    }

    private func disable() {
        self.update {
            self.manager.isEnabled = false
        }
    }

    private func update(_ body: @escaping () -> Void) {
        self.manager.loadFromPreferences { (error) in
            guard error == nil else {
                NSLog("DNSProxySample.App: load error")
                return
            }
            body()
            self.manager.saveToPreferences { (error) in
                guard error == nil else {
                    NSLog("DNSProxySample.App: save error")
                    return
                }
                NSLog("DNSProxySample.App: saved")
            }
        }
    }
}

疑问/问题:
1.为什么没有调用startProxyhandleNewFlow?设置有什么问题吗?
1.如何提及自定义DNS地址?

hmmo2u0o

hmmo2u0o1#

DNSProxyProvider上通过系统触发了startProxyhandleFlow,配置如下:
1.应用程序目标

上的授权
1.授权在DNSProxy扩展

上红线类似于:组.com.xzy.项目名称
1.扩展名为

的信息.plist
文件
1.应用程序委托

import UIKit
import NetworkExtension

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let manager = NEDNSProxyManager.shared()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        self.enable()
        return true
    }

    private func enable() {
        self.update {
            self.manager.localizedDescription = "DNS"
            let proto = NEDNSProxyProviderProtocol()
            proto.providerBundleIdentifier = "EXTENSION_BUNDLE_IDENTIFIER_WHICH_HAS_DNS_PROXY"
            self.manager.providerProtocol = proto
            self.manager.isEnabled = true
        }
    }

    private func disable() {
        self.update {
            self.manager.isEnabled = false
        }
    }

    private func update(_ body: @escaping () -> Void) {
        self.manager.loadFromPreferences { (error) in
            guard error == nil else {
                NSLog("DNS Test App: load error")
                return
            }
            body()
            self.manager.saveToPreferences { (error) in
                guard error == nil else {
                    NSLog("DNS Test App: save error")
                    return
                }
                NSLog("DNS Test App: saved")
            }
        }
    }
}

不要忘记在此处proto.providerBundleIdentifier = "EXTENSION_BUNDLE_IDENTIFIER_WHICH_HAS_DNS_PROXY"更改线束标识符

  1. DNS代理提供程序
import NetworkExtension

class DNSProxyProvider: NEDNSProxyProvider {

    override init() {
        NSLog("DNSProxyProvider: init")
        super.init()
    }

    override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) {
        NSLog("DNSProxyProvider: startProxy")
        completionHandler(nil)
    }

    override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
        NSLog("DNSProxyProvider: stopProxy")
        completionHandler()
    }

    override func sleep(completionHandler: @escaping () -> Void) {
        NSLog("DNSProxyProvider: sleep")
        completionHandler()
    }

    override func wake() {
        NSLog("DNSProxyProvider: wake")
    }

    override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
        NSLog("DNSProxyProvider: handleFlow")
        if let tcpFlow = flow as? NEAppProxyTCPFlow {
            let remoteHost = (tcpFlow.remoteEndpoint as! NWHostEndpoint).hostname
            let remotePort = (tcpFlow.remoteEndpoint as! NWHostEndpoint).port
            NSLog("DNSProxyProvider TCP HOST : \(remoteHost)")
            NSLog("DNSProxyProvider TCP PORT : \(remotePort)")
        } else if let udpFlow = flow as? NEAppProxyUDPFlow {
            let localHost = (udpFlow.localEndpoint as! NWHostEndpoint).hostname
            let localPort = (udpFlow.localEndpoint as! NWHostEndpoint).port
            NSLog("DNSProxyProvider UDP HOST : \(localHost)")
            NSLog("DNSProxyProvider UDP PORT : \(localPort)")
        }
        return true
    }

}

1.最后一步,在真实的的iOS设备上运行应用程序。
1.如果要显示扩展日志,请从Mac打开Console.app
1.要调试扩展:您的主应用应该从运行菜单中选择。从Xcode的调试菜单中选择Attach to Process by PID or Name...,然后输入扩展名,按Attach按钮。看到Waiting to attach to EXTENSION_NAME on XYZ's iPhone后,在iOS设备上运行您的应用目标。

相关问题