在网络方面,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")
}
}
}
}
问题/问题:
- 为什么不调用
startProxy
或handleNewFlow
?设置有什么问题吗? - 如何提及自定义 DNS 地址?
最佳答案
我设法通过系统在 DNSProxyProvider
上触发了 startProxy
和 handleFlow
。我的配置是这样的:
-
应用目标上的
- 权利
应用委托(delegate)
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") } } } }
不要忘记在此处更改 BUNDLE IDENTIFIER proto.providerBundleIdentifier = "EXTENSION_BUNDLE_IDENTIFIER_WHICH_HAS_DNS_PROXY"
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 } }
作为最后一步,在真实的 iOS 设备 上运行该应用。
如果您想显示扩展日志,请从您的 Mac 打开 Console.app。
要调试扩展:您的主应用应从运行菜单中选择。从 Xcode 的 Debug 菜单中选择
Attach to Process by PID or Name...
然后输入你的扩展名,按Attach
按钮。在您看到Waiting to attach to EXTENSION_NAME on XYZ's iPhone
之后。在 iOS 设备上运行您的应用目标。
关于ios - 如何在 iOS 11 中使用 NEDNSProxyProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45508605/