您好,我正在开发一个应用程序,可以拦截来自iPhone的访问网络流量IP地址列表(类似于Charles Proxy)。
目前我已经编写了代码来使用 NETunnelProviderManager 类创建 VPN 配置文件。
NETunnelProviderManager.loadAllFromPreferences { [weak self] managers, error in
guard let self = self else { return }
if self.manager != managers?.first {
self.manager = managers?.first
} else {
self.manager = self.makeManager()
}
self.manager?.saveToPreferences(completionHandler: { (error) in
if let error = error {
print("Error in saving VPN Config: \(error.localizedDescription)")
}
self.manager?.loadFromPreferences(completionHandler: { (error) in
if error == nil {
do {
try self.manager?.connection.startVPNTunnel()
} catch let vpnTunnelError {
print("Unable to start VPN Tunnel by error: \(vpnTunnelError.localizedDescription)")
}
} else {
print("Load From Preference Error")
}
})
})
}
}
private func makeManager() -> NETunnelProviderManager {
let manager = NETunnelProviderManager()
manager.localizedDescription = "NetworkTrafficVPN"
let proto = NETunnelProviderProtocol()
proto.providerBundleIdentifier = "com.NetworkTraffic.vpn-tunnel"
proto.serverAddress = "Network Traffic"
manager.protocolConfiguration = proto
let onDemandRule = NEOnDemandRuleConnect()
onDemandRule.interfaceTypeMatch = .any
manager.isOnDemandEnabled = true
manager.onDemandRules = [onDemandRule]
manager.isEnabled = true
return manager
}
一旦我从创建的 NETunnelProviderManager 对象启动 VPN 隧道 (self.manager?.connection.startVPNTunnel()
)我在 NEPacketTunnelProvider 网络扩展方法中收到回调(startTunnel(options: [String : NSObject]?,completionHandler: @escaping (Error?) -> Void))。
我已使用分配的 iPhone IP 地址在 startTunnel() 方法中创建了 NEPacketTunnelNetworkSettings。
调用方法后 self.setTunnelNetworkSettings(settings) { error in } 我正在内部获取网络数据回调 self.packetFlow.readPackets {(数据,数字)}方法
class PacketTunnelProvider: NEPacketTunnelProvider {
// MARK: - Constants
let logger: Logger = Logger(subsystem: "NetworkTrafficSubsystem", category: "NetworkTrafficCategory")
let proxyServerPort: Int = 8888
let proxyServerAddress = "192.168.43.185" // Device assigned ip address
// MARK: - NEPacketTunnelProvider
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: proxyServerAddress)
settings.tunnelOverheadBytes = 80
settings.mtu = 1400
settings.ipv4Settings = NEIPv4Settings(addresses: [proxyServerAddress], subnetMasks: ["255.255.255.255"])
settings.ipv4Settings?.includedRoutes = [NEIPv4Route.default()]
settings.ipv4Settings?.excludedRoutes = []
settings.dnsSettings = NEDNSSettings(servers: ["8.8.8.8", "8.8.4.4"])
settings.dnsSettings?.matchDomains = []
self.setTunnelNetworkSettings(settings) { error in
if let e = error {
self.logger.info("Settings error")
completionHandler(e)
} else {
self.logger.info("Settings set without error")
self.readPacketObjects()
completionHandler(nil)
}
}
}
private func readPacketObjects() {
self.packetFlow.readPackets { (data, numbers) in
self.logger.info("Inside readPackets completionHandler")
// Way to print the ip address from the received data array
self.packetFlow.writePackets(data, withProtocols: numbers)
self.readPacketObjects()
}
}
}
但是我无法从 } 方法中的 self.packetFlow.readPackets { (data,numbers) 解码数据对象。
所以我的问题是,为了读取所有访问的网络流量的 IP 地址,这是正确的方法还是我需要做其他事情。
如果这是正确的方法,请让我知道如何解码接收到的 Data 对象。 如果没有,请建议实现此功能的正确方法。
如有任何帮助,我们将不胜感激。
所以我的问题是,为了读取所有访问的网络流量的 IP 地址,这是正确的方法还是我需要做其他事情
您需要实施每应用VPN。
每应用 VPN 只能针对受监管设备实施。如果您想在测试模式下实现它,苹果提供了Testing Per App VPN(本页最后一段),无需 MDM 即可工作。