如何在 iOS 11 中使用 NEDNSProxyProvider [英] How to use NEDNSProxyProvider in iOS 11

查看:31
本文介绍了如何在 iOS 11 中使用 NEDNSProxyProvider的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在网络方面,DNS 代理是 iOS 11 最大的特性之一.但他们没有提供太多关于它的文档或示例.有一个

  • 关于 DNSProxy 扩展的权利红线类似于:group.com.xzy.project_name

  • Info.plist 扩展文件

  • AppDelegate

    导入 UIKit导入网络扩展@UIApplicationMain类 AppDelegate: UIResponder, UIApplicationDelegate {变量窗口:UIWindow?让经理 = NEDNSProxyManager.shared()func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) ->布尔{self.enable()返回真}私人功能启用(){自我更新{self.manager.localizedDescription = "DNS"让 proto = NEDNSProxyProviderProtocol()proto.providerBundleIdentifier = "EXTENSION_BUNDLE_IDENTIFIER_WHICH_HAS_DNS_PROXY"self.manager.providerProtocol = protoself.manager.isEnabled = true}}私有功能禁用(){自我更新{self.manager.isEnabled = false}}private func update(_ body: @escaping () -> Void) {self.manager.loadFromPreferences { (error) in守卫错误== nil else {NSLog("DNS 测试应用:加载错误")返回}身体()self.manager.saveToPreferences {(错误)在守卫错误== nil else {NSLog("DNS 测试应用程序:保存错误")返回}NSLog("DNS 测试应用程序:已保存")}}}}

  • 不要忘记在此处更改捆绑标识符 proto.providerBundleIdentifier = "EXTENSION_BUNDLE_IDENTIFIER_WHICH_HAS_DNS_PROXY"

    1. DNSProxyProvider

      导入网络扩展类 DNSProxyProvider:NEDNSProxyProvider {覆盖初始化(){NSLog("DNSProxyProvider: init")超级初始化()}覆盖 func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) {NSLog("DNSProxyProvider: startProxy")完成处理程序(无)}覆盖 func stopProxy(原因:NEProviderStopReason,completionHandler:@escaping () -> Void){NSLog("DNSProxyProvider: stopProxy")完成处理程序()}覆盖 func sleep(completionHandler: @escaping () -> Void) {NSLog("DNSProxyProvider: sleep")完成处理程序()}覆盖 func 唤醒(){NSLog("DNSProxyProvider: 唤醒")}覆盖 func handleNewFlow(_ flow: NEAppProxyFlow) ->布尔{NSLog("DNSProxyProvider: handleFlow")如果让 tcpFlow = 流为?NEAppProxyTCPFlow {让 remoteHost = (tcpFlow.remoteEndpoint as!NWHostEndpoint).hostname让 remotePort = (tcpFlow.remoteEndpoint as!NWHostEndpoint).portNSLog("DNSProxyProvider TCP HOST :(remoteHost)")NSLog("DNSProxyProvider TCP 端口:(remotePort)")} else if let udpFlow = flow as?NEAppProxyUDPFlow {让 localHost = (udpFlow.localEndpoint as!NWHostEndpoint).hostname让 localPort = (udpFlow.localEndpoint as!NWHostEndpoint).portNSLog("DNSProxyProvider UDP 主机:(localHost)")NSLog("DNSProxyProvider UDP 端口:(localPort)")}返回真}}

    2. 最后一步是在真正的 iOS 设备上运行该应用.

    3. 如果您想显示扩展日志,请从您的 Mac 打开 Console.app.

    4. 要调试扩展:应从运行菜单中选择您的主应用程序.从 Xcode 的 调试 菜单中选择 Attach to Process by PID or Name...,然后输入您的扩展名,按 Attach 按钮.在您看到 Waiting to attach to EXTENSION_NAME on XYZ's iPhone 之后.在 iOS 设备上运行您的应用目标.

    On the networking side, DNS Proxy is one of the biggest features of iOS 11. But they haven't provided much documentation or samples regarding it. There's a talk on it as well where they have just given a description of what is possible with DNS Proxy.

    I want to create a working sample of it but didn't get success till now. So I have created a Network Extension with DNS Proxy entitlements and added a DNS Proxy Provider. Here's the code:

    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
        }
    
    }
    

    Then in AppDelegate, I declare a NEDNSProxyManager and use it as:

    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")
                }
            }
        }
    }
    

    Questions/Issues:

    1. Why isn't startProxy or handleNewFlow called? Is there anything wrong in the setup?
    2. How do I mention custom DNS address?

    解决方案

    I managed to trigger startProxy and handleFlow on DNSProxyProvider by system. My configurations are like this:

    1. Entitlements on app target
    2. Entitlements on DNSProxy Extension Red line is something similar to: group.com.xzy.project_name

    3. Info.plist file on Extension

    4. AppDelegate

      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")
                  }
              }
          }
      }
      

    DO NOT FORGET TO CHANGE BUNDLE IDENTIFIER at here proto.providerBundleIdentifier = "EXTENSION_BUNDLE_IDENTIFIER_WHICH_HAS_DNS_PROXY"

    1. DNSProxyProvider

      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
          }
      
      }
      

    2. As a last step run the app on a real iOS Device.

    3. If you want to display extension logs open Console.app from your Mac.

    4. To debug the extension: Your main app should be selected from run menu. Select Attach to Process by PID or Name... from Xcode's Debug menu and then type your extension's name, press Attach button. After you see the Waiting to attach to EXTENSION_NAME on XYZ's iPhone. Run your app target on a iOS device.

    这篇关于如何在 iOS 11 中使用 NEDNSProxyProvider的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆