Skip to content

Instantly share code, notes, and snippets.

@seebk
Last active July 23, 2024 22:43
Show Gist options
  • Save seebk/bb94a7fd70d4cc454aaa to your computer and use it in GitHub Desktop.
Save seebk/bb94a7fd70d4cc454aaa to your computer and use it in GitHub Desktop.
Extract embedded certificates and keys from OpenVPN config files

This python script is intended to automate the extraction of embedded certificates and keys from OpenVPN config files.

Unfortunately the GNOME Network-Manager is not able to automatically import OpenVPN config files with embedded certificates and keys. A workaround is to manually extract these and store them in separate files (e.g. see https://naveensnayak.wordpress.com/2013/03/04/ubuntu-openvpn-with-ovpn-file/).

Instructions:

  • Make shure all the required packages are installed. For example on Ubuntu and Debian run:

    $ sudo apt-get install python3 network-manager-openvpn-gnome

  • Extract the certs and keys using the python script

    $ python3 extract_ovpn_cert.py path/to/VPNCONFIG.ovpn

  • Import the created file path/to/VPNCONFIG_nocert.ovpn with the GNOME network config tool


References:

#!/usr/bin/python3
#
# Extract certificates and keys from an OpenVPN config file (*.ovpn)
# The config file is rewritten to use the extracted certificates.
#
# Usage: >$ extract_ovpn_cert.py VPNCONFIG.ovpn
#
import os
import re
import sys
# open input ovpn config file
ovpn_file_path = os.path.dirname(os.path.abspath(sys.argv[1]))
ovpn_file = open(sys.argv[1], 'r')
ovpn_config = ovpn_file.read()
ovpn_file.close()
# open output config file
ovpn_file = open(os.path.splitext(sys.argv[1])[0]+"_nocert.ovpn", 'w')
# prepare regex
regex_tls = re.compile("<tls-auth>(.*)</tls-auth>", re.IGNORECASE|re.DOTALL)
regex_ca = re.compile("<ca>(.*)</ca>", re.IGNORECASE|re.DOTALL)
regex_cert = re.compile("<cert>(.*)</cert>", re.IGNORECASE|re.DOTALL)
regex_key = re.compile("<key>(.*)</key>", re.IGNORECASE|re.DOTALL)
# extract keys
match_string = regex_tls.search(ovpn_config)
if match_string is not None:
cert_file = open(os.path.join(ovpn_file_path, 'tls-auth.key'), 'w')
cert_file.write(match_string.group(1))
cert_file.close()
ovpn_config = regex_tls.sub("",ovpn_config)
# get key direction setting
regex_tls = re.compile("key-direction ([01])", re.IGNORECASE)
match_string = regex_tls.search(ovpn_config)
if match_string is not None:
key_direction = match_string.group(1)
else:
key_direction = ""
ovpn_file.write("tls-auth tls-auth.key " + key_direction + "\n")
match_string = regex_ca.search(ovpn_config)
if match_string is not None:
cert_file = open(os.path.join(ovpn_file_path, 'ca.crt'), 'w')
cert_file.write(match_string.group(1))
cert_file.close()
ovpn_config = regex_ca.sub("",ovpn_config)
ovpn_file.write("ca ca.crt\n")
match_string = regex_cert.search(ovpn_config)
if match_string is not None:
cert_file = open(os.path.join(ovpn_file_path, 'client.crt'), 'w')
cert_file.write(match_string.group(1))
cert_file.close()
ovpn_config = regex_cert.sub("",ovpn_config)
ovpn_file.write("cert client.crt\n")
match_string = regex_key.search(ovpn_config)
if match_string is not None:
cert_file = open(os.path.join(ovpn_file_path, 'client.key'), 'w')
cert_file.write(match_string.group(1))
cert_file.close()
ovpn_config = regex_key.sub("",ovpn_config)
ovpn_file.write("key client.key\n")
# copy and append previous config
ovpn_file.write(ovpn_config)
ovpn_file.close()
@seebk
Copy link
Author

seebk commented Nov 16, 2015

Fixed it now.

@mjaliz
Copy link

mjaliz commented Jun 3, 2023

Thanks for your share, This really helped me to config OpenVPN client on MikroTik.

@josuehenrique
Copy link

it is not working for me :/

@josuehenrique
Copy link

image

@steph-ben
Copy link

Same issue as @josuehenrique :-(

@santarinto
Copy link

Key file contains line "tls-auth tls-auth.key 1" which is not a key-value pair group, or comment

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