This project presents how to explore the OpenVPN component to develop a particular solution app to connect in a VPN from iOS environment. Its aims to show the development process, the drawbacks and finally the benefits to do it. The prototype must grant the connection, regardless of the server configuration, and allow to make customizations as needed.
1. Introduction and Motivation
Due to the recent growth in demand for work in the home office format, it has become popular for the use of VPN (Virtual Private Network) connections to ensure, securely, the integration of users to closed corporate networks. Between the connections of this type, one of the most popular is the one based on the OpenVPN protocol. However, not all platforms have full support for connecting to servers that implement this protocol. This is the case of the iOS mobile platform, which only has in its catalog a single tool to establish such a connection. AND, depending on the level of customization of the server settings, the connection becomes impossible with this application. It was this deficiency, added to the popularity of the iOS platform, which motivated the development of a tool with customization inexistent in the few existing solutions on the market today.
2. Objective and Methodology
The objective of this work is to make a new tool available to users of the iOS platform, which need to establish VPN connections between your device and private networks. To create this application, Apple's IDE Xcode was used. The software was built on a variation of the MVVM (Model View ViewModel) design pattern and debugged on an iPhone 7. For testing, a virtual cloud server (VPS) was created using the Google Cloud Platform environment. The server has the Debian 10 system distribution Linux operating system. And in it, the OpenVPN network was installed and configured. To complement the tests, a second server was created, connected to the same intranet as the first one, but without external access. This second VPS runs a web server that provides only an illustrative page.
3. Development Process
3.1 Specification and Design
For coding the prototype, the Swift programming language was used in its version 5.0. The design pattern used to organize the code was the MVVM, with some adaptations. And to create the graphical interface, the framework used was SwiftUI. To simulate a real use case, a virtual network was set up on the platform Google Cloud Platform, containing two servers. Being a web server and a OpenVPN server. Both running Debian operating system (Linux) and communicable with each other. The following support tools were used in application development and creation of the test environment:
- Xcode: IDE (Integrated Development Environment) for developing applications in an Apple environment
- OpenVPNAdapter: Framework in Objective-C, based on the library OpenVPN3, originally written in C++, used to configure a OpenVPN protocol connection
- CocoaPods: Dependency manager for Swift and Objective-C projects
- Visual Studio Code: Text editor used to edit markdowns, pod files and other files not managed by Xcode
- Google Cloud Console: Interface for managing platform services Google Cloud
- GitHub: Platform for hosting source code, based on the system of Git version control
- LucidChart: Platform used to create the UML use case diagram
Initially, a survey of the possible frameworks and libraries available to work with OpenVPN connections on the iOS operating system was made. After the survey, it was concluded that the safest thing would be to use the official library of the protocol, written in C++, as it has reliable documentation. But due to the language barrier, was needed help from the OpenVPNAdapter
framework (code snippet 1), which adapts the official library for the Objective-C language. Making it possible to incorporate to the project, since the Xcode IDE manages Objective-C combined with Swift language for iOS projects development.
Code snippet 1 - OpenVPNAdapter managed by CocoaPods
def shared_pods
use_frameworks!
pod 'OpenVPNAdapter', :git => 'https://github.com/deneraraujo/OpenVPNAdapter.git'
end
target 'VPNClient' do
shared_pods
end
target 'TunnelProvider' do
shared_pods
end
The following step was to understand how the operating system handles interfaces of virtual network. Unlike other systems such as Windows and Android, iOS does not work with individual network interfaces for each VPN connection. Instead, configuration profiles are defined for the main connection. Therefore, the project was built to create a network configuration profile, based on the information provided by the library.
Once the necessary elements to develop the client have been established, the next step would be to create an environment that simulates a network, containing a OpenVPN server. A virtual network was then set up on the Google Cloud Platform, containing two servers. One of them being a web server, which returns a HTML (HyperText Markup Language) page to prove access, and a OpenVPN server. The first represents any server within a corporate network, which has the ports blocked for external access. The second is the VPN server which the application will connect to access the first one, as well as other possible servers within the network.
After successfully establishing a connection between the client and the server, a graphical interface was developed using the SwiftUI framework, able to create a layout that adapts to many Apple devices. The interface works the same as the existing OpenVPN clients in other operating systems: the application loads the predefined settings from a “.opvn” extension file and then provides customization options for the user. As a prototype, the app is limited to a single user profile, and enables customization of DNS (Domain Name System) servers used in connection as well as different forms of authentication.
Figure 1 shows the user's interaction with the interface in a UML use case diagram.
Figure 1 - Use Case Diagram
The next diagram (Figure 2) shows the process performed by the component designed to connect through the adapter. From this sequence diagram, it is possible to see the concern in bringing a single and flexible activity necessary to configure and start the process of obtaining the connection.
The first technical task of this class (OpenVPNClient
Prototype) is to import the OpenVPNAdapter
and from this collaboration to invoke the set provider and connect, using the received credentials. If a problem occurs, the process tries again from the reconnect command.
Figure 2 - Connection process through the developed component
At the PacketTunnelProvider
class, there is the startTunnel
method. At this point, the application has already gathered all the information coming from the interface and that's when it calls the library, passing this information. It's actually the implementation (code snippet 2) of an abstract
method that already exists in the iOS framework But in this implementation, it ends by calling the OpenVPNAdapter
library.
Code snippet 2 - PacketTunnelProvider Class to get and control the Network Connection
override func startTunnel(options: [String : NSObject]?, completionHandler:
@escaping (Error?) -> Void) {
guard
let protocolConfiguration = protocolConfiguration as? NETunnelProviderProtocol,
let providerConfiguration = protocolConfiguration.providerConfiguration
else {
fatalError()
}
guard let ovpnFileContent: Data = providerConfiguration["ovpn"]
as ? Data else { return }
configuration = OpenVPNConfiguration()
configuration.fileContent = ovpnFileContent
configuration.privateKeyPassword = profile?.privateKeyPassword
applyConfiguration(completionHandler: completionHandler)
if !evaluation.autologin {
if let username: String = providerConfiguration["username"]
as ? String, let password: String = providerConfiguration["password"]
as ? String {
let credentials = OpenVPNCredentials()
credentials.username = username
credentials.password = password
do {
try vpnAdapter.provide(credentials: credentials)
} catch {
completionHandler(error)
return
}
}
}
vpnReachability.startTracking { [weak self] status in
guard status != .notReachable else { return }
self?.vpnAdapter.reconnect(afterTimeInterval: 5)
}
startHandler = completionHandler
vpnAdapter.connect(using: packetFlow)
}
3.2 Results
The following step was to understand how the operating system handles interfaces of virtual network. Unlike other systems such as Windows and Android, iOS does not work with individual network interfaces for each VPN connection. Instead, configuration profiles are defined for the main connection. Therefore, the project was built to create a network configuration profile, based on the information provided by the library.
Figure 3 - Connection States, "to connect", "connectiong" and "connected ok"
For this project, the file was generated on the cloud test server. Once the file is loaded, it is validated. If the file is OK, the OpenVPN server address is displayed. If not, the user is alerted.
The OpenVPN server allows the configuration files that will be distributed to the users to be protected with a private security key. So if that's the case of the file the user is loading, a required field called “Private Key” is shown. Then, the user must choose how to authenticate to the server: anonymously or with username and password. The anonymous authentication possibility is necessary, as the network administrator may choose only the private key file as a security method, and does not require authentication by user and password.
The output log information is presented on the main view, from a single operation to access the step-by-step of the connect proccess (Figure 5).
With the file loaded and authentication data entered, the next step for the user is to choose whether to enter extra DNS server addresses for use with the connection. It is common for internal networks to have dedicated DNS servers, mainly in a corporate environment. In these cases, any addresses will be provided to the user.
With the fields filled in, the user simply clicks the “Connect” button. The required fields are validated and in case there is any irregularity, the user is alerted before continuing.
Then a ping is done to check the server availability. Once the server is accessible, the credentials are validated, and if they are irregular, the user is alerted and the connection attempt is interrupted. Otherwise, the connection contract starts.
Finally, Figure 4 demonstrates the navigability of a previously inaccessible internal network address.
Figure 4 - Browser Accessing Internal Network Address
The entire negotiation process between the client and the server is displayed in a log (Figure 5), which is populated at runtime and displayed on the screen. Any connection failures will be highlighted in red in the log and will result in a failure message for the user.
Figure 5 - Log Output
Upon successful connection, the user will be able to access the addresses both Internet and the intranet now available.
3.3 Sourcecode and Dependencies Links
4. Conclusion
With the studies and information gathered for the development of the project, it was possible to understand more broadly the functioning of virtual private networks in some operating systems. Knowledge acquired in progress, such as software engineering and requirements gathering were indispensable in this project development, as well as some notions of how networks work.
The use of design patterns was also significantly improved, as well as the use of modern mobile application languages and technologies. Better notions of version control and task management were acquired too, once GitHub was instrumental in managing the application development.
In addition to the knowledge range acquired, the intention is that this project will contribute to the mobile development community, with focus on for the iOS operating system, since iOS has a smaller content when compared to other platforms.
The knowledge and results obtained so far were satisfactory and opened up precedent for improving the prototype in order to develop a complete application, that in the near future it can be useful for real users, that find it difficult to connect to private networks through their mobile devices.
5. References
- Apple (2020); The Swift Programming Language. Swift Language Official Documentation [online] available at: https://swift.org documentation/#the-swift-programming-language, accessed in Dec. 2020.
- Hoffman, J. (2019); “Mastering Swift 5”, 5th Edition, Packt Publishing. 2019. Apple (2020); framework SwiftUI Official Documentation [online] available at: https://developer.apple.com/documentation/swiftui/, accessed in Dec. 2020.
- OpenVPNAdapter (2020); "Framework em Objective-C, baseado na biblioteca OpenVPN3, para configuração de conexões de protocolo OpenVPN" [online] available at: https://github.com/ss-abramchuk/OpenVPNAdapter, accessed in Sep. 2020.
- OpenVPN3 (2020); "Biblioteca em C++, utilizada para configuração de conexões de protocolo OpenVPN" [online] available at: https://github.com/OpenVPN/openvpn3, accessed on Sep. 2020.
- Ankit Sinhal (2020); “MVC, MVP and MVVM Design Pattern”. Published Tech Article [online] available at: https://medium.com/@ankit.sinhal/mvc-mvp-and-mvvm-design-pattern- 6e169567bbad, accessed on Sep. 2020.
- Kouraklis, J. (2016); “MVVM in Delphi”, Apress. 2016. Jan Just Keijser, J. J. (2017); “OpenVPN Cookbook”, Second Edition, Packt Publishing. 2017.
- Google (2021); "Google Cloud Official Documentation" [online] available at: https://cloud.google.com/docs, accessed on Feb. 2021.
History
- 11th June, 2021 - Document creation
- 13th June, 2021 - Textual revision, initial version
- 15th June, 2021 - Revision and validation
- 16th June, 2021 - Document submission
- 24th June, 2021 - Document revision, bug fixing and improvement
- 25th June, 2021 - Document submission
- 25th June, 2021 - Improvement of image detail
- 26th June, 2021 - Minor text corrections
- 27th June, 2021 - Images updated
agile and devops enthusiast; master in computer science and professor in technology courses; I have worked with projects and development for the telecommunication area
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.