我正在努力让这个工作。
我的客户端有一个DNS服务器,有时我会发送电子邮件给他们的DNS设置。但现在我想通过ios应用程序做到这一点。 有没有办法我可以让他们下载应用程序,然后单击应用程序上的一个按钮来完成它?
我看着这个 https://developer.apple.com/library/ios/documentation/NetworkExtension/Reference/NEDNSSettingsClassRef/index.html#//apple_ref/occ/cl/NEDNSSettings但不确定
感谢
答案 0 :(得分:0)
查看Network Extensions类。使用NETunnelProviderManager课程,您可以使用onDemandRules设置NEEvaluateConnectionRule。 NEEvaluateConnectionRule constructor可以将带有顶级域名(即["*.com", "*.net", "*.org", "*.io"]
)的通配符列表作为域名,并使用NEEvaluateConnectionRuleAction.connectIfNeeded作为操作。将您创建的onDemandRules的NEEvaluateConnectionRule设置为所有tlds作为域。然后创建NEOnDemandRuleEvaluateConnection并将其connectionRules设置为使用所有顶级域创建的NEEvaluateConnectionRule,并将其interfaceTypeMatch设置为NEOnDemandRuleInterfaceType.any。将NETunnelProviderManager.onDemandRules设置为以此方式创建的NEOnDemandRuleEvaluateConnection。如果您如上所述创建了NETunnelProviderManager和load it以及save it,则可以使用NETunnelProviderManager.isEnabled和NETunnelProviderManager.isOnDemandEnabled属性打开和关闭它。< / p>
这是一个完全相同的示例类。
import Foundation
import NetworkExtension
public class VPNConnect {
private static let vpnDescription = "DNS OnDemand to GoogleDNS"
private static let vpnServerDescription = "OnDemand DNS to GoogleDNS"
public var manager:NETunnelProviderManager = NETunnelProviderManager()
public var dnsEndpoint1:String = "8.8.8.8"
public var dnsEndpoint2:String = "8.8.4.4"
public var connected:Bool {
get {
return self.manager.isOnDemandEnabled
}
set {
if newValue != self.connected {
update(
body: {
self.manager.isEnabled = newValue
self.manager.isOnDemandEnabled = newValue
},
complete: {
if newValue {
do {
try (self.manager.connection as? NETunnelProviderSession)?.startVPNTunnel(options: nil)
} catch let err as NSError {
NSLog("\(err.localizedDescription)")
}
} else {
(self.manager.connection as? NETunnelProviderSession)?.stopVPNTunnel()
}
}
)
}
}
}
public init() {
refreshManager()
}
public func refreshManager() -> Void {
NETunnelProviderManager.loadAllFromPreferences(completionHandler: { (managers, error) in
if nil == error {
if let managers = managers {
for manager in managers {
if manager.localizedDescription == VPNConnect.vpnDescription {
self.manager = manager
return
}
}
}
}
self.setPreferences()
})
}
private func update(body: @escaping ()->Void, complete: @escaping ()->Void) {
manager.loadFromPreferences { error in
if (error != nil) {
NSLog("Load error: \(String(describing: error?.localizedDescription))")
return
}
body()
self.manager.saveToPreferences { (error) in
if nil != error {
NSLog("vpn_connect: save error \(error!)")
} else {
complete()
}
}
}
}
private func setPreferences() {
self.manager.localizedDescription = VPNConnect.vpnDescription
let proto = NETunnelProviderProtocol()
proto.providerBundleIdentifier = "com.popmedic.vpntunnel.provider"
proto.serverAddress = VPNConnect.vpnServerDescription
self.manager.protocolConfiguration = proto
// TLDList is a struct I created in its own swift file that has an array of all top level domains
let evaluationRule = NEEvaluateConnectionRule(matchDomains: TLDList.tlds,
andAction: NEEvaluateConnectionRuleAction.connectIfNeeded)
evaluationRule.useDNSServers = [self.dnsEndpoint1, self.dnsEndpoint2]
let onDemandRule = NEOnDemandRuleEvaluateConnection()
onDemandRule.connectionRules = [evaluationRule]
onDemandRule.interfaceTypeMatch = NEOnDemandRuleInterfaceType.any
self.manager.onDemandRules = [onDemandRule]
}
}
请注意,您必须打开网络扩展功能,然后会出现一个对话框,告诉用户您正在打开VPN连接,但当状态栏中没有[VPN]图标时连接已打开,因为我们没有设置vpn,只使用按需规则。
尽可能多地讨厌谷歌,也许将此用于您设置的DNS ... Quad9
答案 1 :(得分:0)
请考虑构建DNSProxy扩展(网络扩展之一),以拦截设备上生成的所有DNS流量并使用自定义/内部DNS服务器。