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
Code Block 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") } }) }) } } }