I am making an app that activates a VPN connection based on OpenVPN, retrieves a certificate from the database, and opens a tunnel using NEPacketTunnelProvider and NetworkExtension.
I used the following repository following repository, and now my VPN is working fine.
But the problem is that I want to allow only one app to use this VPN when enabled (WhatsApp precisely), and I want to restrict all other apps of using it.
On Android it's possible by giving the bundle identifier of the allowed apps to the PackageManager.
Can you please help me?
This is my PacketTunnelProvider class:
This is the function used in my VPN View Model to start a tunnel:
I used the following repository following repository, and now my VPN is working fine.
But the problem is that I want to allow only one app to use this VPN when enabled (WhatsApp precisely), and I want to restrict all other apps of using it.
On Android it's possible by giving the bundle identifier of the allowed apps to the PackageManager.
Can you please help me?
This is my PacketTunnelProvider class:
This is the function used in my VPN View Model to start a tunnel:
I am not sure about OpenVPN, but with NEPacketTunnelProvider on macOS (as of 10.15.4) you can set this up yourself with NEAppRule. A very generic example of setting up Safari to trigger the VPN would be:Does it work with NEPacketTunnelProvider and OpenVPN?
Code Block swift var perAppManager = NETunnelProviderManager.forPerAppVPN() /* ... */ NETunnelProviderManager.forPerAppVPN().loadFromPreferences(completionHandler: { error in precondition(Thread.isMainThread) /* ... */ let proto = (perAppManager.protocolConfiguration as? NETunnelProviderProtocol) ?? NETunnelProviderProtocol() proto.serverAddress = "server.vpn.com" proto.providerBundleIdentifier = "com.perapp-vpn.macOSPacketTunnel.PacketTunnelTest" var appRules = [NEAppRule]() let appRule = NEAppRule(signingIdentifier: "com.apple.Safari", designatedRequirement: "identifier \"com.apple.Safari\" and anchor apple") appRule.matchDomains = ["example.com"] appRules.append(appRule) perAppManager.appRules = appRules perAppManager.isOnDemandEnabled = true perAppManager.protocolConfiguration = proto perAppManager.isEnabled = true perAppManager.localizedDescription = "Testing Per-App VPN" self.perAppManager.saveToPreferences { saveError in /* Proceed to connect */ } })
That was a very generic case and forPerAppVPN() is only available on macOS. A more real-world case world case for iOS would be to create this process through MDM. That entire flow is explained in the documentation I mentioned previously. I would start by just creating a configuration profile in Configurator 2 and testing it out.
Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com