Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
This is how you can take an openvpn .ovpn config file and extract the certificates/key required to import the profile into NetworkManager.

OpenVPN .ovpn manipulation.

This is how you can take an OpenVPN .ovpn config file and extract the certificates/keys required to import the profile into NetworkManager.

  • Download the .ovpn file. Save it somewhere you can store it permanently (I use ~/.vpn).
  • Copy from between <ca> tags into ca.crt, remove <ca> tags.
  • Copy from between <cert> tags into client.crt, remove <cert> tags.
  • Copy from between <key> tags into client.key, remove <key> tags.
  • Copy from between <tls-auth> tags into ta.key, remove <tls-auth> tags.
  • Remove the line "key-direction 1"
  • Above "# -----BEGIN RSA SIGNATURE-----" insert the following lines.
    • ca ca.crt
    • cert client.crt
    • key client.key
    • tls-auth ta.key 1
  • Import the .ovpn file into NetworkManager and save the profile.
@chb0github

This comment has been minimized.

Copy link

@chb0github chb0github commented May 22, 2016

I actually tracked down the openssl code to find out exactly how it likes these files:

    if ((strncmp(buf, "-----END ", 9) != 0) ||
        (strncmp(nameB->data, &(buf[9]), i) != 0) ||
        (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) {
        PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_END_LINE);
        goto err;
    }

the last line MUST meet these rules:

  1. first 9 characters: "-----END " (5 dashes, "END" and a single space)
  2. The part of the line must have the exact same header name as the "START". So like, "START CERTIFICATE"
  3. The final part of the line must be, exactly 5 dashes and a single "\n" which would be hex byte 0x0A which is default newline for unix

The problem: I was missing 1 single '-' at the end of the file!!

@NickoMas

This comment has been minimized.

Copy link

@NickoMas NickoMas commented Oct 26, 2017

Thank you, good sir, you saved my sanity after sleepless night with your solution.

@alexandervlpl

This comment has been minimized.

Copy link

@alexandervlpl alexandervlpl commented May 6, 2018

Yeah, thanks man! Just what I needed. 👍

@mcuprojects

This comment has been minimized.

Copy link

@mcuprojects mcuprojects commented Jun 26, 2018

thanks man, that's helpful

@lucaszanella

This comment has been minimized.

@yabbes

This comment has been minimized.

Copy link

@yabbes yabbes commented Nov 15, 2019

I had the same idea but wasn't sure it would work like this so I ended up here :)
In my case it's just <tls-crypt> brackets instead of <tls-auth> but will work the same way.
Starred this gist 👍

@raOne-007

This comment has been minimized.

Copy link

@raOne-007 raOne-007 commented Jan 2, 2020

Hello Guys ,
I have able to save VPN configuration.
Please tell me how to make the server address variable or get server address and what is the remote identifier for?
Please tell me if anyone worked on VPN Configuration
Here is my code:

    func connectVPN(){
        do {
                 if let file = URL(string: "example.com") {
                let data = try Data(contentsOf: file)
                let json = try JSONSerialization.jsonObject(with: data, options: [])
                if let object = json as? [String: String] {
                // json is a dictionary
                var data_VPN = object["VPN_data"]!
                //print("data:\(data_VPN)")
                let certificate = data_VPN
                let nsdata = certificate.data(using: .utf8)

                let base64EncodedData = nsdata!.base64EncodedData()

                print("base64StoreData:\(nsdata!)")
                print("base64StoreNewData:\(base64EncodedData)")

                var vpnManager = NEVPNManager.shared()

                                    vpnManager.loadFromPreferences { error in

                                        if vpnManager.`protocol` == nil{
                                            let newIPSec = NEVPNProtocolIPSec()

                                            newIPSec.serverAddress = ""
                                            newIPSec.localIdentifier = ""
                                            newIPSec.remoteIdentifier = ""
                                            newIPSec.useExtendedAuthentication = true
                                            newIPSec.identityData = base64EncodedData as! Data
                                            newIPSec.authenticationMethod = NEVPNIKEAuthenticationMethod.certificate
                                            print("VPNDATA:\(newIPSec)")

                                            if #available(iOS 9, *) {
                                            vpnManager.protocolConfiguration = newIPSec
                                            } else {
                                            vpnManager.`protocol` = newIPSec
                                            }

                                            vpnManager.isEnabled = true
                                            vpnManager.saveToPreferences(completionHandler: { (error) -> Void in
                                                if ((error) != nil) {
                                                    print("VPN Preferences error: 2")
                                                }
                                                else {
                                                    vpnManager.loadFromPreferences(completionHandler: { (error) in
                                                        if ((error) != nil) {
                                                            print("VPN Preferences error: 2")
                                                        }
                                                        else {
                                                            var startError: NSError?
                                                            do {
                                                                try vpnManager.connection.startVPNTunnel()
                                                            }
                                                            catch let error as NSError {
                                                                startError = error
                                                                print(startError)
                                                            }
                                                            catch {
                                                                print("Fatal Error")
                                                                fatalError()
                                                            }
                                                            if ((startError) != nil) {
                                                                print("VPN Preferences error: 3")
                                                                let alertController = UIAlertController( title: "Oops..", message: "Something went wrong while connecting to the VPN. Please try again.", preferredStyle: UIAlertControllerStyle.alert)
                                                                alertController.addAction( UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default,handler: nil))
                                                                self.present(alertController, animated: true, completion: nil)
                                                                print(startError)
                                                            }
                                                            else {
                                                                //VPNStatusDidChange(nil)
                                                                print("Start VPN")
                                                            }
                                                        }
                                                    })
                                                }
                                            })
                }

            } else if let object = json as? [Any] {
                // json is an array
                for anItem in object as! [Dictionary<String, AnyObject>] {
                    let industryName = anItem["VPN_data"] as! String                                               
                }
            } else {
                print("JSON is invalid")
            }
        } else {
            print("no file")
        }
    } catch {
        print(error.localizedDescription)
    }

}

}

@labbots

This comment has been minimized.

Copy link

@labbots labbots commented May 6, 2020

I have written a bash script that could split or merge OVPN config file. The code can be found at https://github.com/labbots/OVPN-Config-Manipulator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment