Network Extension

RSS for tag

Customize and extend the core networking features of iOS, iPad OS, and macOS using Network Extension.

Network Extension Documentation

Pinned Posts

Posts under Network Extension tag

399 Posts
Sort by:
Post not yet marked as solved
19 Replies
6.6k Views
We're looking to create a packet tunnel provider network extension. Inside this extension we will have some custom client code that runs to check a few things on the device prior to allowing the VPN to connect per enterprise policy. This code will be inside of the startTunnelWithOptions:completionHandler: block and execute prior to fully completing the connection, if something is wrong the connection will not be completed. The initial VPN profile and such will be installed during the first execution of the container app. My question is around how we can relay to the user why the VPN connection was not allowed. This is an enterprise application where specific artifacts must be present prior to the VPN connection completing (OS version, WiFi vs. Celluar, etc). Our code inside startTunnelWithOptions:completionHandler: determines this. The VPN will be initiated on-demand or per-app, (it could be started from inside the container app but unlikely), therefore our container app may not be running at all when the VPN comes up but the extension will clearly be called when appropriate. This rule's out the use of handleAppMessage:completionHandler: to send some kind of message back to the user if the container app is closed (I thought this was the intention of the handleAppMessage API but maybe not). If the container app is not running this API will not work, correct? Even if it did work, it won't flip the user back to the container app, correct?Our issues is that the container app provides a dashboard and we need to tell the user why the VPN connection was disallowed. The way I see it we could do this in two ways:1) If it's allowed for an extension to show a UI elemetn (e.g., deprecated alertView, etc) initiated by the code inside startTunnelWithOptions, but it's unclear to me if we are able to do that as an extension. Idealy we would display a UIAlert window stating that the connection was disallowed and the user needs to open our app to see why.2) We could call back to our container app via openURL, it would be launched if not running, and we could then have it display the dashboard along with the reason why the VPN connection was disallowed (sent in the openURL payload). The problem with this is that only Today extensions can do this per documentation "Each extension point determines whether to support this method, or under which conditions to support this method." "A Today widget (and no other app extension type) can ask the system to open its containing app by calling theopenURL:completionHandler: method of the NSExtensionContext class. ". Obviously, there may be work arounds to launch the app still but its clearly not supported to do so as a Network Extension. Any idea's how a network extension can display a simple message to the user in response to the VPN not starting? This would need to be displayed in any scenario that the VPN starts, via general->settings->VPN, ondemand, etc.Thanks
Posted
by
Post not yet marked as solved
12 Replies
1.9k Views
Hi guys,I'm developing a custom VPN client with NEPacketTunnelProvider which tunnels all device traffic. All is going well so far but I've noticed that iOS battery statistics (Settings -> Battery) is claiming that our client has consumed a significant amount of energy (10%~30%). I though it was true for a while, but then I conducted some basic testing which suggested this is more likely a statistical issue.I set up my device (rebooted with clean battery cosumption statistics) with ~80% battery capacity and started to watch "NASA Live" channel in Youtube app with 1080p60 quality, for 3 hours, and taking notes every hour. I cross referenced the data of the same scenario (same device as well) collected with our custom VPN provider enabled and disabled. I made sure when the VPN client is enabled, I can actually see the Youtube traffic tunneled. Actually the video feed can generate ~1GiB traffic per hour pretty stably. I can provide detailed numbers if necessary, but generally, after 3 hours, both scenarios showed an overal of ~50% battery consumption (from the battery indicator on the status bar on top of the phone screen), there was no significant difference in the battery consumption. However when I looked at the statistics in Settings -> Battery, the scenario without our VPN client was showing 100% battery consumption from Youtube app (which is expected), and the scenario with VPN was showing 68% for Youtube, and 32% for our VPN client app!32% battery consumption in statistics is scaring. But what confuses me is that the actual device battery consumption didn't increase. My theory is that without the VPN client, individual apps are sending out their traffic on their own so the battery consumption are calculated on their head. But now with our VPN client, we are actually sending out traffic for every applications so iOS will blame us for that part of energy consumption. I'm not sure if the theory is true but it certainly explains the behavior.I'm wondering if Apple can look at the issue at if proved to be a statistical issue then fix it. Because 10%+ battery consumption on our app would be enough to scare away our customers. We can explain to them there is no actual extra energy consumption but customers will be suspicious. Whenever they feel their phone's having a shortened battery life they'll come to see the list and they will blame us.Thanks in advance!
Posted
by
Post not yet marked as solved
9 Replies
14k Views
Hi,I create application "Connecting to WiFi in iOS"Code to connecting:Swiftlet configuration = NEHotspotConfiguration.init(ssid: "SSIDname", passphrase: "Password", isWEP: false)configuration.joinOnce = trueNEHotspotConfigurationManager.shared.apply(configuration) { (error) in if error != nil { if error?.localizedDescription == "already associated." { print("Connected") } else{ print("No Connected") } } else { print("Connected") }}and Xamarin[assembly: Dependency(typeof(WifiConnector))]namespace WiFiManager.iOS{ public class WifiConnector : IWifiConnector { public void ConnectToWifi(string ssid, string password) { var wifiManager = new NEHotspotConfigurationManager(); var wifiConfig = new NEHotspotConfiguration(ssid, password, false); wifiManager.ApplyConfiguration(wifiConfig, (error) => { if (error != null) { Console.WriteLine($"Error while connecting to WiFi network {ssid}: {error}"); } }); } }}Everything works fine but iOS always asks a question "Wants to Join Wi-Fi Network".Is there any possibility that it would not ask? For my application, this popup is a problem. Maybe list of preferred network?Thank you in advance!
Post not yet marked as solved
5 Replies
2.2k Views
I am trying to disable onDemanRules from within the NEPacketTunnelProvider extension, but when I try to load the NETunnelProviderManager I get this message in the logs:NETunnelProviderManager objects cannot be instantiated from NEProvider processesDoes anyone know if there's a way I can disable onDemanRules from within the NEPacketTunnelProvider extension?It seems odd that we can cancel the tunnel from the extension using cancelTunnelWithError(_:) but can't stop the system from trying to reconnect due to onDemandRules. Especially that in the documentation it says:The Packet Tunnel Provider should call this method when an unrecoverable error occurs, such as the tunnel server going down or the VPN authentication session expiring.^ How is it even useful to call this method when an unrecoverable error occurs, but cannot stop it from reconnecting. If the tunnel server is down, why would it even keep trying to reconnect forever? That would just block the internet connection from the phone, and for the user to gain access to the internet again they have to go to Settings > VPN > VPN Profile > Disable "Connect on Demand", which is a terrible user experience, we should just be able to disable it from the extension.
Posted
by
Post not yet marked as solved
6 Replies
1.2k Views
Hello,Is there a way to allow multiple apps to register the usage of the Content Filtering Extension? Or is there a way for an app to just monitor and not block network traffic while another app is used for actual filtering?Thank youLeo
Posted
by
Post marked as solved
12 Replies
2.2k Views
Hi,I downloaded FilteringNetworkTraffic and added a FilterPacketProvider to intercept network packet with following info.plist:<key>NEProviderClasses</key> <dict> <key>com.apple.networkextension.filter-packet</key> <string>$(PRODUCT_MODULE_NAME).FilterPacketProvider</string> </dict>but the callback function and packetHandler closure do not work at all? thanks!
Posted
by
Post not yet marked as solved
6 Replies
2.6k Views
I need to develop an extension that gets the current connected Wi-Fi signal strength, the app will be registered as a Hotspot Helper, but first, we need to do some testing.I don't see too much documentation about this and I don't know how to use the object.
Posted
by
Post not yet marked as solved
11 Replies
5.7k Views
seeing this error when I am trying to install my network extension: _macvnodechecksignature: /Applications/abc.app/Contents/MacOS/abc: code signature validation failed fatally: When validating /Applications/abc.app/Contents/MacOS/abc:   Code has restricted entitlements, but the validation of its code signature failed. Unsatisfied Entitlements:__ I have set the right entitlements as far as I know . is this error about entitlements or signature that is not obvious from the message . this is sseen on Catalina 10.15.6 the macOS Network extension is Developer ID signed . still facing this error . any idea what will fix this error ??
Posted
by
Post not yet marked as solved
8 Replies
1k Views
At my app I have a SecKey which I want to sign some Data with it, and at my sever I need to do the verification process, but this time with openSSL. I didn't find any common key or any steps to achieve this between Apple Security framework and OpenSSL. For example, I've tried the following: Signing (Apple Security): let signedStrCFData = SecKeyCreateSignature(key, .rsaSignatureRaw, plaintextData, &error) Verifying (OpenSSL): ret = RSAverify(NIDrsaSignature, (const unsigned char *)challenge, (unsigned int)strlen(challenge), challengeenc, challengeenc_size, rsa); Which key to choose is not really important to me (as long as it's a reasonable signing key), so I tried multiple types of keys, but I wasn't able to do it. Any idea what I'm missing here?
Posted
by
Post not yet marked as solved
13 Replies
1.7k Views
Looking over the SimpleTunnel code example, how is the subclassed NEPacketTunnelProvider being used and the startTunnel() function being called? I've looked over the documentation and watched the "What's New in Network Extension and VPN" WWDC15 video and I'm not sure how it's actually started. When I do a search for "PacketTunnelProvider" I don't see any references outside the file itself aside from the NSExtensionPrincipalClass entry in the associated Info.plist. Is creating this file and having it present in a system extension enough to "activate" the PacketTunnelProvider class and call startTunnel()? What else must be done? The SimpleTunnel example uses an App Extension since it's targeting iOS. Am I correct in thinking that for the macOS it should be a System Extension?
Posted
by
Post marked as solved
12 Replies
1.4k Views
Hi, I am trying to create an app that filters network events - whether to collect statistics, or to even block some specific flows. I see that using NEFilterDataProvider I am able to only filter UDP or TCP protocols (when filtering by .any, I see I only receive UDP/TCP). For example, I wish to see the flow of a simple ping 1.1.1.1. This of course makes the statistics partial (without ICMP packet/raw socket packets), or the flow block being bypass-able (even if with some effort), by using Raw sockets. Is there a way to add to the filtering also ICMP and RAW flows? Should I use a different provider for those?
Posted
by
Post not yet marked as solved
1 Replies
991 Views
Recently I experienced some weird issues with iOS VPN including personal VPN(IPsec VPN) and enterprise VPN(custom ssl VPN) when running some applications on both mac and iOS. I coded a network extension program which can run on both mac and iOS. In the network extension it intercepts the packets from the NEPacketTunnelFlow and encap them with a self defined header which is 16 bytes and send them via a UDP session to the remote server. test env: Xcode 12.0.1 / iOS 14.0 SDK / iPhone iOS 12.4.8 Here are some test results as following. IPSec VPN(personal VPN) which is supported natively by iOS: when running Speedtest from OOKLA it failed to test on mobile network(in my case it's 4G). The message shows ERROR Test failed to complete. Check your internet connection and try again OK There is no such issue on WIFI network. custom ssl VPN(enterprise VPN) created by using NETunnelProviderManager: On WIFI network run Roblox application on iPhone it failed when joining the server with error message Disconnected Failed to connect to the Game.(ID=17:Connection attempt failed.)(Error Code: 279) Leave I suspect it's related to the mtu setting so I tried with different tunnelOverheadBytes or mtu values:  on wifi network(my router's mtu is 1480):     work: -100/-16/20 (<=20)     not work: 21 (> 20)  on mobile network:     work:0/-16/-100(very slow)     not work: 1/2/5/10/20/21/28 (> 0)    It's weird that negative numbers work for overhead setting. And it seems on WIFI network the range of x <= 20 work for the Roblox game application( can join the server and play some games without any problems) and on mobile network the range is x <=0. Or set mtu instead of tunnelOverheadBytes:   on wifi network:     work:1480/1485/1490/1500     not work:1464/1479/1600     on mobile network:     work:1480/1485/1490/1500     not work:1464/1479/1600/2000 It seems the working value range is [1480, 1500] for both WIFI and mobile network. And also, Speedtest works on WIFI network but not on mobile network. To my understanding in the network extension we only need to set the tunnelOverheadBytes and the iOS will compute the mtu size and we don't need to care about the difference between different type of network. But actually there are differences. Now I'm totally confused. Apparently the value of tunnelOverheadBytes or mtu is quite critical for the network traffic. How to correctly set the tunnelOverheadBytes in the network extension for both WIFI and mobile network?
Posted
by
Post not yet marked as solved
2 Replies
1.6k Views
NEFilterDataProvider seemed to perfectly meet our needs to monitor and control a Mac's network traffic, in total and by process. But: we found out that traffic from about 50 Apple processes is excluded from being seen and controlled by NEFilterDataProvider, due to an undocumented Apple exclusion list. This is a regression from what was possible with NKEs. We believe it has a high number of drawbacks, and we already know this is negatively affecting our end users. I've covered all of the above in detail in FB8808172, also why other ways to monitor and control traffic are not alternatives we could consider for this scenario. I'd appreciate if someone at Apple could have a look as soon as possible.
Posted
by
dok
Post not yet marked as solved
12 Replies
2.1k Views
Hi, I have a problem with my OpenVPN connection on my app with iOS 14.4. I perform my VPN configuration from an oven file, with a NETunnelProviderManager protocol, but when I perform the startVPNTunnel, it starts connecting and immediately disconnects. The error I see in the logs is the following: NESMVPNSession[Primary Tunnel:OpenVPN Client: -----(null)]: status changed to disconnected, last stop reason Plugin was disabled This happens to me when running my app on a physical iPad. Regards import NetworkExtension import OpenVPNAdapter class VPNConnection {          var connectionStatus = "Disconnected"              var myProviderManager: NETunnelProviderManager?          func manageConnectionChanges( manager:NETunnelProviderManager ) - String {         NSLog("Waiting for changes");         var status = "Disconnected"                  NotificationCenter.default.addObserver(forName: NSNotification.Name.NEVPNStatusDidChange, object: manager.connection, queue: OperationQueue.main, using: { notification in                          let baseText = "VPN Status is "                          switch manager.connection.status {             case .connected:                 status = "Connected"             case .connecting:                 status = "Connecting"             case .disconnected:                 status = "Disconnected"             case .disconnecting:                 status = "Disconnecting"             case .invalid:                 status = "Invalid"             case .reasserting:                 status = "Reasserting"             default:                 status = "Connected"             }                          self.connectionStatus = status                          NSLog(baseText+status)                      });         return status     }          func createProtocolConfiguration() - NETunnelProviderProtocol {         guard             let configurationFileURL = Bundle.main.url(forResource: "app-vpn", withExtension: "ovpn"),             let configurationFileContent = try? Data(contentsOf: configurationFileURL)         else {             fatalError()         }                  let tunnelProtocol = NETunnelProviderProtocol()         tunnelProtocol.serverAddress = ""         tunnelProtocol.providerBundleIdentifier = "com.app.ios"                  tunnelProtocol.providerConfiguration = ["ovpn": String(data: configurationFileContent, encoding: .utf8)! as Any]         tunnelProtocol.disconnectOnSleep = false                  return tunnelProtocol     }          func startConnection(completion:@escaping () - Void){         self.myProviderManager?.loadFromPreferences(completionHandler: { (error) in             guard error == nil else {                 // Handle an occurred error                 return             }                          do {                 try self.myProviderManager?.connection.startVPNTunnel()                 print("Tunnel started")             } catch {                 fatalError()             }         })     }          func loadProviderManager(completion:@escaping () - Void) {                           NETunnelProviderManager.loadAllFromPreferences { (managers, error) in             guard error == nil else {                 fatalError()                 return             }                          self.myProviderManager = managers?.first ?? NETunnelProviderManager()             self.manageConnectionChanges(manager: self.myProviderManager!)                          self.myProviderManager?.loadFromPreferences(completionHandler: { (error) in                 guard error == nil else {                     fatalError()                     return                 }                                  let tunnelProtocol = self.createProtocolConfiguration()                                  self.myProviderManager?.protocolConfiguration = tunnelProtocol                 self.myProviderManager?.localizedDescription = "OpenVPN Client Ubic"                                  self.myProviderManager?.isEnabled = true                                  self.myProviderManager?.isOnDemandEnabled = false                                  self.myProviderManager?.saveToPreferences(completionHandler: { (error) in                     if error != nil  {                         // Handle an occurred error                         fatalError()                     }                     self.startConnection {                         print("VPN loaded")                     }                 })             })         }     } }
Posted
by
Post not yet marked as solved
5 Replies
1.3k Views
Here is how I set up the network for Packet Tunnel Provider swift let networkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "240.240.240.240")     networkSettings.ipv4Settings = NEIPv4Settings(addresses: ["240.0.0.1"], subnetMasks: ["255.0.0.0"])     networkSettings.ipv4Settings?.includedRoutes = [NEIPv4Route(destinationAddress: "0.0.0.0", subnetMask: "0.0.0.0")]     networkSettings.ipv4Settings?.excludedRoutes = [       NEIPv4Route(destinationAddress: "240.0.0.0", subnetMask: "255.0.0.0"),       NEIPv4Route(destinationAddress: "1.1.1.1", subnetMask: "255.255.255.255"),       NEIPv4Route(destinationAddress: "1.0.0.1", subnetMask: "255.255.255.255")     ]           networkSettings.dnsSettings = NEDNSSettings(servers: ["1.1.1.1", "1.0.0.1"]) The DNS servers are set to 1.1.1.1 and 1.0.0.1 which technically should be excluded from the tunnel. But when I'm debugging, I can still see the IP packets whose destination address is 1.1.1.1/1.0.0.1 and protocol is 17(UDP) are captured by the tunnel thus DNS queries fail. Does anybody know if I'm setting up the DNS the wrong way? Why are DNS server addresses not excluded from tunnel despite being set so?
Posted
by
Post not yet marked as solved
9 Replies
1.6k Views
Hello, I initially started the discussion over at Swift Forums - https://forums.swift.org/t/issue-with-connect-proxy-some-connections-dont-work-probably-sockets/45575 because I am using SwiftNIO but it appears that it makes more sense here. I have an app with NetworkExtension of the packet tunnel provider type. So I am using the NEPacketTunnelProvider. As part of the extension, I have SwiftNIO server with connect proxy which is used to route the traffic. This works great in almost all cases, but apps like Signal or WhatsApp don't work. They don't display any kind of "no connection" indicator but the messages aren't send or received. Over at Swift Forums I got an answer from Quinn “The Eskimo!” that I think points to the actual problem: My experience is that a lot of these ‘chat’ apps explicitly bind their connections to the WWAN interface, which means they don’t use the default route and thus aren’t seen by the packet tunnel provider. My packet tunnel provider is configured to use the default routes for IP4 and IP6. So my concern is how to configure it, that it works also for the chat apps? There are couple of apps from the App Store that I tried which use this same approach and while they are active, Signal works fine. Yes, I know this solution is not ideal and not the main intended usecase for packet tunnel, but it is the only option available on iOS.. Thanks for help! Happy to clarify further.
Posted
by
Post not yet marked as solved
5 Replies
1.7k Views
Hi All, I am trying to do a small POC using network extension's content filter capability. It is just a simple application for listening to all inbound connections on a particular port. I am able to build the application using Xcode. Through the main application i am able to install the network extension as system extension and I am able to view the installed extension in systemextensionctl list. The problem is the I am not able to do anything after that , I don't think the extension is actually running. I am not able to see any logs in system.log. Few logs were present from devices log which indicate that the extension is running. The last log was Request to activate com.sample.xyz.NetworkExtension succeeded (0). Adding event subscription 930 for provider com.sample.xyz.NetworkExtension with extension point com.apple.networkextension.filter-data I gave some debug logs and none of them were printed. I have all entitlements in my provisional profile and if there was any code signing issue I guess it would have been present in system.log (atleast I assume) Thanks in advance.
Posted
by
Post not yet marked as solved
7 Replies
2.3k Views
While trying to add a new VPN configuration , the ios Network Extension fails for a particular device with my App with the following error default 23:34: 34.140388-0400 Adding 918D08B1-2814-47C0-AAA9-0A0A8C92049C to the loaded configurations  error 23:34:41.386023-0400 nehelper : Cannot save configuration , the total size of the NetworkExtension configuration is to large (2643248 bytes)  default 23:34:41.510241-0400 kernel memorystatus: set assertion priority(10) error The same behaviour is seen with other VPN Providers like Tunnel Bear. Question: As this issue is seen only on a particular device. Has anyone seen this issue/able to mitigate , and also shed more details why this issue happens.
Posted
by
Post marked as solved
6 Replies
2.2k Views
Hi, how could I get the command line arguments of a process given its audit token. My app is a Content Filter Network Extension written in swift. I can obtain the audit token from NEFilterFlow but I can't figure out how to get the process arguments, I was able to get the pid from the audit token using audit_token_to_pid.
Posted
by
Post not yet marked as solved
3 Replies
1.5k Views
I am working on OpenVPN application for Mac OS. I use openVPNAdapter to do this. Version for Mac OS store with apex works well. But we need a Developer ID signing version. To do this I created NE system extension (appex was removed from the project), changed packet-tunnel-provider with packet-tunnel-provider-systemextension, reuse the same PacketTunnelProvider code and the same openVPNAdapter (framework was embedded into the extension). Run system extension via OSSystemExtensionRequest (copied logic from SempleFirewall apple example), makes a build, and notarized it. When I run the app, I see that SeystemExtension is running (activity monitor), PacketTunnelProvider successfully connects to the VPN server (logs and “connected” status in the macOS SystemPreferences), but traffic is locked. I can’t open any websites. First I thought that the problem with DNS, but I can't open any sites via IP too. So I think Mac OS locks socket traffic. Maybe somebody has such an issue and knows how to resolve it. MacOS: 11.4
Posted
by