Reputation: 1
Hello I am working on an application which can intercept the visited network traffic ip address list from iPhone (similar to Charles Proxy).
Currently I have written code to create a VPN profile using NETunnelProviderManager class.
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
}
Once I start the vpn tunnel (self.manager?.connection.startVPNTunnel()) from the created NETunnelProviderManager object
I get a callback in NEPacketTunnelProvider network extension method (startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void)).
I have created the NEPacketTunnelNetworkSettings inside startTunnel() method using the assigned IP address of the iPhone.
After calling the method self.setTunnelNetworkSettings(settings) { error in } I am getting network data callback inside self.packetFlow.readPackets { (data, numbers) } method
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()
}
}
}
But I am unable to decode the data object from self.packetFlow.readPackets { (data, numbers) in } method.
So my question is that in order to read the IP address of all the visited network traffic is this the correct approach or I need to do something else.
If this is correct approach then let me know how to decode the received Data object. If not then please suggest the correct way to achieve this functionality.
Any help would be appreciated thanks.
Upvotes: 0
Views: 421
Reputation: 1151
So my question is that in order to read the IP address of all the visited network traffic is this the correct approach or I need to do something else
You need to implement Per App VPN.
Per App VPN can be implemented for Supervised Devices only. if you want to implement it in test mode apple provides Testing Per App VPN (last paragraph of this page) which works without MDM.
Upvotes: 0