Skip to content

Instantly share code, notes, and snippets.

@penguinpowernz
Last active March 8, 2022 20:19
Show Gist options
  • Save penguinpowernz/36883ba5c8bf51bdb5d1 to your computer and use it in GitHub Desktop.
Save penguinpowernz/36883ba5c8bf51bdb5d1 to your computer and use it in GitHub Desktop.
OVPN Splitter

OVPN File Splitter

Have an OpenVPN config file with inline certificates that you need to split up because the Ubuntu team haven't fixed that 2+ year old bug in Network Manger?

You've come to the right place!

This script will split the file out into it's respective certs/keys and output a replacement .ovpn file with cert/key paths.

Usage

First of all make yourself a secure home folder for you VPN suff:

mkdir ~/.ovpn
chmod 700 ~/.ovpn # keep it secret
cd .ovpn
cp ~/Downloads/my.ovpn ./my.inline.ovpn

Then run it like this:

ruby ~/Downloads/ovpnsplit.rb my.inline.ovpn > my.ovpn

Now if you have a look in that folder you should have the following files:

$ ls ~/.ovpn
ca.crt
client.crt
client.key
my.ovpn
my.inline.ovpn
ta.key

And when you look in the my.ovpn file you will see the inline certs have been replaced with paths:

remote vpn.example.com 1194
proto udp
ns-cert-type server

client
dev tun
resolv-retry infinite
keepalive 10 120
nobind
comp-lzo
verb 3

;user nobody
;group nogroup

key-direction 1

ca ca.crt
key client.key
cert client.crt
tls-auth ta.key 1

Now you can import that file into Network Manager.

Todo

  • make this a gem for ease of use
  • verify the generated file contents against the original file
  • handle file without tls-auth sections
#!/usr/bin/env ruby
# The MIT License (MIT)
#
# Copyright (c) 2014 Robert McLeod
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
ovpn = File.read(ARGV[0])
def extract(part, contents, file)
# try to match a section
pattern = /\<#{part}\>(.*)\<\/#{part}\>/m
m = contents.match pattern
return contents if m.nil?
# write the file out
File.open(file, "w") {|f| f.write m[1].strip }
# return the contents with this section stripped out
return contents.sub(m[0], "")
end
# extract all the things into their respective files
ovpn = extract("ca", ovpn, "ca.crt")
ovpn = extract("key", ovpn, "client.key")
ovpn = extract("cert", ovpn, "client.crt")
ovpn = extract("tls-auth", ovpn, "ta.key")
# Try to extract the key direction for TLS Auth
direction = ""
match = ovpn.match /key-direction (\d)/
unless match.nil?
direction = match[1]
end
# Add the file paths now that the inline certs are gone
ovpn.concat("\nca ca.crt")
ovpn.concat("\nkey client.key")
ovpn.concat("\ncert client.crt")
ovpn.concat("\ntls-auth ta.key #{direction}")
# Dump the new ovpn file
puts ovpn
@Sandy-Garrido
Copy link

This worked perfectly! Thank you for saving me a job!

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