Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurations using --pkcs12 for key/cert/ca are not working #25

Open
rjbruin opened this issue Oct 2, 2020 · 29 comments
Open

Configurations using --pkcs12 for key/cert/ca are not working #25

rjbruin opened this issue Oct 2, 2020 · 29 comments
Labels

Comments

@rjbruin
Copy link

rjbruin commented Oct 2, 2020

READ THIS CAREFULLY BEFORE ADDING A NEW COMMENT

  1. Does your configuration file use the pkcs12 option? If yes, continue. If not, this issue ticket is not your problem - look up another issue or file a new one.

  2. Can you try starting the session using the openvpn2 command line front-end? If that does not work, this issue ticket is not your problem - look up another issue or file a new one.

  3. If you still do not know if your issue is related to the pkcs12 option, search for pkcs12 in the configuration you have?
    a) Have you imported your configuration using openvpn3 config-import or do you use openvpn3-autoload? Run this command:

      $ openvpn3 config-dump --config $CONFIG_NAME | grep pkcs12
    

    If this returns nothing, this issue ticket is not your problem - look up another issue or file a new one.

    If you do not know your $CONFIG_NAME, run openvpn3 configs-list and see if you find it there.

    b) If you have your OpenVPN client configuration file saved as a file, run this command:

     $ grep pkcs12 $CONFIG_FILE
    

    If this returns nothing, this issue ticket is not your problem - look up another issue or file a new one.

If you have discovered that your configuration file does make use of the pkcs12 option, then you can continue reading. Otherwise, this issue ticket is not your problem - look up another issue or file a new one.


I set up a clean install of OpenVPN 3 client on my Ubuntu 18.04 machine. When I run:

sudo openvpn3 session-start --config FILENAME.ovpn

I get the following error:

session-start: ** ERROR ** Failed to start new session: Failed calling D-Bus method Ready: GDBus.Error:net.openvpn.v3.sessions.error: Backend VPN process have died.  Session is no longer valid.

This configuration file contains a PKCS#12 file with valid client/ca certs and private key.

Can anyone help figure out what is going wrong here?

@dsommers
Copy link
Member

dsommers commented Oct 2, 2020

Can you first try to start this configuration using the openvpn2 command using --verb 6? Also, you do not need to start VPN sessions as root (even via sudo) with OpenVPN 3 Linux. Unless you really want root to own the VPN session.

Just try this first:

user@host ~ $  openvpn2 --config FILENAME.ovpn --verb 6

The openvpn2 command is emulating the old OpenVPN 2.x command line, only supporting most of the client options.

@rjbruin
Copy link
Author

rjbruin commented Oct 2, 2020

Thanks for the quick reply!

When I use openvpn2 I get a different, also confusing, error: pyOpenSSL library is not installed. Cannot parse PKCS#12 files.

I've checked (using pip, also using python then import OpenSSL), but I do have pyOpenSSL installed in my Python environment (both python2 and python).

@dsommers
Copy link
Member

dsommers commented Oct 2, 2020

You need the Python 3 packaging for these dependencies. python is just pointing at your python2 environment. python3 is "independent" of the Python 2.x installation.

So check for python3 packages and use pip3 if you don't find it via apt. I believe you might need python3-openssl on Ubuntu 18.04.

@dsommers dsommers changed the title Failed calling D-Bus method session-start: Failed calling D-Bus method Oct 2, 2020
@dsommers
Copy link
Member

dsommers commented Oct 2, 2020

Btw, are you installing OpenVPN 3 Linux from the apt repositories, or have you done a build yourself?

Details here: https://community.openvpn.net/openvpn/wiki/OpenVPN3Linux

@rjbruin
Copy link
Author

rjbruin commented Oct 2, 2020

Btw, are you installing OpenVPN 3 Linux from the apt repositories, or have you done a build yourself?

From the APT repositories. I followed the instructions from that page, under "Pre-built packages" -> "Debian, Ubuntu".

You need the Python 3 packaging for these dependencies. python is just pointing at your python2 environment. python3 is "independent" of the Python 2.x installation.

I actually mapped python to python3. My bad, should have mentioned. But this did actually get me further, because I realized I installed PyOpenSSL for Python 2, not for Python 3.

Now there seems to be an incompatibility of some sort in my config file. The new error message is:

/usr/bin/openvpn2: error: unrecognized arguments: --ncp-ciphers AES-256-GCM:AES-128-GCM`

@dsommers
Copy link
Member

dsommers commented Oct 2, 2020

I actually mapped python to python3. My bad, should have mentioned. But this did actually get me further, because I realized I installed PyOpenSSL for Python 2, not for Python 3.

In regards to openvpn2 that shouldn't change anything, as it should be hard-coded to use python3.

Now there seems to be an incompatibility of some sort in my config file. The new error message is:

/usr/bin/openvpn2: error: unrecognized arguments: --ncp-ciphers AES-256-GCM:AES-128-GCM`

Ouch! That's not your fault. That's actually something missing in the config parser in the openvpn3 python module. Okay, so this approach didn't work as smooth as it usually does. Lets go to plan B.

Have two terminals handy. In the first one, we will start a process watching for logs:

 user@host: ~ $ openvpn3 log --log-level 6 --config FILENAME.ovpn

In the second terminal, run this:

   user@host: ~ $ openvpn3 session-start --config FILENAME.ovpn

(the openvpn2 approach would result in the same, but with a single command)

@rjbruin
Copy link
Author

rjbruin commented Oct 3, 2020

Output of session-start:

Using configuration profile from file: FILENAME.ovpn
Session path: /net/openvpn/v3/sessions/8de70a1bse232s46a5sac7csf08a030b7ddf
session-start: ** ERROR ** Failed to start new session: Failed calling D-Bus method Ready: GDBus.Error:net.openvpn.v3.sessions.error: Backend VPN process have died.  Session is no longer valid.

Output of log:

Waiting for session to start ... Done
Attaching to session /net/openvpn/v3/sessions/8de70a1bse232s46a5sac7csf08a030b7ddf
** ERROR ** Failed setting new property value on 'receive_log_events': Failed to retrieve unique bus ID for bus name 'net.openvpn.v3.backends.be7541': Failed calling D-Bus method GetNameOwner: Could not get owner of name 'net.openvpn.v3.backends.be7541': no such name

@dsommers
Copy link
Member

dsommers commented Oct 3, 2020

Okay, this makes it a bit clearer. It's the openvpn3-service-client crashing. The challenge now is to figure out why. I'll get back to you over the weekend with some approaches to debug this better.

If you feel adventurous doing some debugging on your own in the meantime, have a look here: https://github.com/OpenVPN/openvpn3-linux/blob/master/docs/debugging.md ... The best is if you are able to enable and track down some coredumps or a backtrace of the crash, but I don't quite remember how that works on Ubuntu.

@rjbruin
Copy link
Author

rjbruin commented Oct 6, 2020

I've managed to install openvpn with the debugging options enabled, but I'm kind of lost with the debugging instructions.

@dsommers
Copy link
Member

dsommers commented Oct 6, 2020

Good! So I've put together a pretty simple debug helper script in Python. First, you need to import the configuration profile you want to test with. This debug script does not support configurations requiring username/passwords. If your config requires that, let me know and I'll expand this script to provide this information as well.

First, import the configuration profile:

  [user@host ~]$ openvpn3 config-import --config FILENAME.ovpn --name CONFIGNAME

Then save the script below:

#!/usr/bin/python3

import sys
import os
import time
import dbus
import openvpn3

if len(sys.argv) != 2:
    print("Usage: %s <pre-imported config name>" % sys.argv[0])
    sys.exit(1)

# Get a connection to the D-Bus System Bus
sysbus = dbus.SystemBus()

# Get a connection to the Config Manager and retrieve
# a configuration object representing this config
cfgmgr = openvpn3.ConfigurationManager(sysbus)
cfgpaths = cfgmgr.LookupConfigName(sys.argv[1])
if len(cfgpaths) == 0:
    print("No configuration profile found")
    sys.exit(1)
elif len(cfgpaths) > 1:
    print("More than one configuration profile found using the first match")

print("Retrieving configuration profile from %s" % cfgpaths[0])
cfg = cfgmgr.Retrieve(cfgpaths[0])


# Connecting to the Session Manager and starting a new tunnel session
sesmgr = openvpn3.SessionManager(sysbus)
session = sesmgr.NewTunnel(cfg)
time.sleep(1)  # Simplistic method to ensure the backend client settles

print("New VPN session initiated: %s" % session.GetPath())
pid = int(session.GetProperty("backend_pid"))
host = os.uname().nodename.split('.')[0]
print("Backend client PID: %i\n" % pid)
print("In a different terminal, run the following command as root:\n")
print("     [root@%s ~]# gdb --pid %i\n" % (host, pid))
print("Inside this debugger command prompt, type: 'continue'\n")
print("     (gdb) continue\n")
input("When this is done, hit [ENTER] in this terminal ... ")

print("\nStarting VPN session ...")
session.Ready()
session.Connect()
print("Connecting, session status: %s" % str(session.GetStatus()))
time.sleep(5)
print("Session status: %s" % str(session.GetStatus()))

input("Hit [ENTER] to disconnect and shutdown session ... ")
session.Disconnect()

To use this script, let's say you named it ovpn3-debug.py:

 [user@host ~]$ python3 ovpn3-debug.py CONFIGNAME
 Retrieving configuration profile from /net/openvpn/v3/configuration/4a779694x7a84x402fxad2exdf348d99c303
 New VPN session initiated: /net/openvpn/v3/sessions/96ef5bb7sa909s4c9dsb568sb4b66df5295b
 Backend client PID: 19304

 In a different terminal, run the following command as root:

      [root@optimus ~] # gdb --pid 19304

 Inside this debugger command prompt, type: 'continue'

      (gdb) continue

 When this is done, hit [ENTER] in this terminal ... 

Do what this script instructs you to do, and hit [ENTER]. It is important that you run gdb with root privleges, otherwise you cannot attach a debugger to the openvpn3-service-client process. I do expect your gdb terminal to bail out with a crash. When that happens, type: thread apply all bt and copy-paste everything you see from the beginning of the gdb command to this ticket.

@rjbruin
Copy link
Author

rjbruin commented Oct 6, 2020

Thanks for the very extensive instructions! The connection does indeed require username & password however...

@dsommers
Copy link
Member

dsommers commented Oct 6, 2020

No worries, here's an updated debug script which will expect user credentials to be provided:

#!/usr/bin/python3

import sys
import os
import time
import getpass
import dbus
import openvpn3

if len(sys.argv) != 2:
    print("Usage: %s <pre-imported config name>" % sys.argv[0])
    sys.exit(1)

# Get a connection to the D-Bus System Bus
sysbus = dbus.SystemBus()

# Get a connection to the Config Manager and retrieve
# a configuration object representing this config
cfgmgr = openvpn3.ConfigurationManager(sysbus)
cfgpaths = cfgmgr.LookupConfigName(sys.argv[1])
if len(cfgpaths) == 0:
    print("No configuration profile found")
    sys.exit(1)
elif len(cfgpaths) > 1:
    print("More than one configuration profile found using the first match")

print("Retrieving configuration profile from %s" % cfgpaths[0])
cfg = cfgmgr.Retrieve(cfgpaths[0])


# Connecting to the Session Manager and starting a new tunnel session
sesmgr = openvpn3.SessionManager(sysbus)
session = sesmgr.NewTunnel(cfg)
time.sleep(1)  # Simplistic method to ensure the backend client settles

# Provide user credentials
for uislot in session.FetchUserInputSlots():
    if uislot.GetInputMask():
        val = getpass.getpass("%s: " % uislot.GetLabel())
    else:
        val = input("%s: " % uislot.GetLabel())
    uislot.ProvideInput(val)

print("\nNew VPN session initiated: %s" % session.GetPath())
pid = int(session.GetProperty("backend_pid"))
host = os.uname().nodename.split('.')[0]
print("Backend client PID: %i\n" % pid)
print("In a different terminal, run the following command as root:\n")
print("     [root@%s ~]# gdb --pid %i\n" % (host, pid))
print("Inside this debugger command prompt, type: 'continue'\n")
print("     (gdb) continue\n")
input("When this is done, hit [ENTER] in this terminal ... ")
print("\nStarting VPN session ...")
session.Ready()
session.Connect()
print("Connecting, session status: %s" % str(session.GetStatus()))
time.sleep(5)
print("Session status: %s" % str(session.GetStatus()))
input("Hit [ENTER] to disconnect and shutdown session ... ")
session.Disconnect()

@rjbruin
Copy link
Author

rjbruin commented Oct 6, 2020

Here we go. The output of the debug script:

Starting VPN session ...
Traceback (most recent call last):
  File "./magicscript.py", line 47, in <module>
    session.Connect()
  File "/usr/lib/python3.6/site-packages/openvpn3/SessionManager.py", line 138, in __delete_checker
    return func(self, *args, **kwargs)
  File "/usr/lib/python3.6/site-packages/openvpn3/SessionManager.py", line 188, in Connect
    self.__session_intf.Connect()
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException: org.gtk.GDBus.UnmappedGError.Quark._g_2dio_2derror_2dquark.Code36: GDBus.Error:net.openvpn.v3.sessions.error: Failed communicating with VPN backend: Failed calling D-Bus method Connect: GDBus.Error:net.openvpn.v3.backend.error.standard: Failed executing D-Bus call 'Connect': Configuration pre-parsing failed: option_error: option <pkcs12> was not properly closed out

The gdb terminal did actually not crash. It stays at Continuing.

@dsommers
Copy link
Member

dsommers commented Oct 6, 2020

Wow! That's interesting! But at least now we have an error which makes some sense. And there more issues being triggered in parallel. The trigger point is here:

 Configuration pre-parsing failed: option_error: option <pkcs12> was not properly closed out

The --pkcs12 feature has not been thoroughly tested, so it is definitely related to this.

Could you try to run this config against the classic OpenVPN 2.x and see if that behaves as expected?

@rjbruin
Copy link
Author

rjbruin commented Oct 6, 2020

I believe I did this, before we went through the debugging route: #25 (comment)

I got this error then, and the same now:

/usr/bin/openvpn2: error: unrecognized arguments: --ncp-ciphers AES-256-GCM:AES-128-GCM`

I don't think I can run openvpn2 with the debugging tools, right? Since your script initiates the session, instead of using the command-line API.

@dsommers
Copy link
Member

dsommers commented Oct 6, 2020

Ahh, the openvpn2 command is not the same as the classic OpenVPN 2.x version. The openvpn2 command is provided by openvpn3-linux. You need the one provided by apt install openvpn and use the openvpn command.

@rjbruin
Copy link
Author

rjbruin commented Oct 6, 2020

I wasn't aware. My apologies!

With openvpn, I can connect to the server. :)

@dsommers
Copy link
Member

dsommers commented Oct 6, 2020

Alright, so the configuration file is not corrupt. I'll run some more testing with --pkcs12.

@dsommers dsommers changed the title session-start: Failed calling D-Bus method session-start: --pkcs12 not working Oct 6, 2020
@dsommers dsommers added the bug label Nov 4, 2020
@adboyarshinov

This comment has been minimized.

@dsommers
Copy link
Member

Hello, I faced the same problem when trying to run openvpn3 inside docker.

With openvpn, I can connect to the server. :)

But when I use openvpn --config config_file.ovpn --verb 6
It fails with Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)

This is confusing. This issue is not about running OpenVPN 3 Linux in Docker. In addition, you talk about openvpn which is the OpenVPN 2.x version, not OpenVPN 3 Linux. And running OpenVPN (any version) inside a Docker container is a questionable use case to start with. But that is not something we will discuss in this ticket.

This issue is about PKCS12 files not being handled correctly in the OpenVPN 3 Python module. Please stay on topic within in the issue tickets.

@dsommers
Copy link
Member

dsommers commented Jul 9, 2021

PLEASE STAY ON TOPIC - THIS IS ABOUT PKCS12 CERTIFICATE/PRIVATE KEY BUNDLES

@OpenVPN OpenVPN deleted a comment from arcilli Jul 13, 2021
@OpenVPN OpenVPN deleted a comment from matheo Jul 13, 2021
@OpenVPN OpenVPN deleted a comment from weisdd Jul 13, 2021
@OpenVPN OpenVPN deleted a comment from lfluvisotto Jul 13, 2021
@benfreefly
Copy link

benfreefly commented Aug 24, 2021

Was there ever any progress on this? I'm having the exact same issues and identical errors when trying the debug steps in previous comments. I can also connect using openvpn but not openvpn3. It may be coincidence, but I had a router failure and this issue started after I replaced it -- however I tried purging/reinstalling both openvpn and openvpn3 (via apt) as well as removing and re-adding my configs after fixing the router and neither had any effect. I am on Ubuntu 20.04.

@dsommers
Copy link
Member

@benfreefly Does your configuration profile contain --pkcs12 ? If yes, then this is not properly solved yet.

@coolgoel18

This comment has been minimized.

@dsommers

This comment has been minimized.

@dsommers dsommers changed the title session-start: --pkcs12 not working session-start: configurations using --pkcs12 for key/cert/ca are not working Jan 11, 2022
@coolgoel18

This comment has been minimized.

@dsommers
Copy link
Member

To the next commenter

Have you read carefully the initial issue comment? Have you verified your configuration does contain pkcs12? If no, do that first.

@dsommers dsommers changed the title session-start: configurations using --pkcs12 for key/cert/ca are not working Configurations using --pkcs12 for key/cert/ca are not working Jan 28, 2022
@waggyman
Copy link

From @dsommers comment.

@coolgoel18 This doesn't make sense. --pkcs12 option support has never been properly supported in OpenVPN 3 Linux, due to lack of support of it in the OpenVPN 3 Core library. Using the openvpn2 command line wrapper from the OpenVPN 3 Linux project is able to handle this, because it uses the Python OpenSSL implementation to split up the .pkcs12 file into separate .pem files for certificates, keys and CA certificate.

using openvpn2 command line wrapper for OpenVPN3 solved my problem of CA Not Defined when using .p12 file.

Thanks 👍

@dsommers
Copy link
Member

I wrapped together a quick Python script now, which can import configuration profiles (a variant of openvpn3 config-import --persistent). I'll add that to the source repo in the nearer future as well; but here's a copy of it - only lightly tested.

#!/usr/bin/python3
#
#  OpenVPN 3 Linux client -- Next generation OpenVPN client
#
#  SPDX-License-Identifier: AGPL-3.0-only
#
#  Copyright (C) 2017 - 2023  OpenVPN Inc <[email protected]>
#  Copyright (C) 2017 - 2023  David Sommerseth <[email protected]>
#
#
#  Another Python implementation of importing a configuration profile.
#  This approach uses the openvpn3 Python to get a real configuration
#  profile to use for the import (via the openvpn3.ConfigParser) and
#  imports it using the openvpn3.ConfigurationManager.
#
#  Use this as: ./configimport2.py CONFIG_NAME <openvpn 2 options>
#  Example: ./configimport2.py my-config --config /path/to/config.ovpn --verb 6
#

import dbus
import openvpn3
import sys

# Simple argument pre-checks
if sys.argv[1] in ['--help','-h']:
    openvpn3.ConfigParser(sys.argv, 'Imports a configuration profile')
    sys.exit(0)
    
if len(sys.argv) < 3:
    print('** ERROR ** Too few arguments')
    print('Usage: %s CONFIG_NAME <openvpn options....>')
    sys.exit(1)

# Parse the configuration
config_name = sys.argv[1]
parser_args = [sys.argv[0],] + sys.argv[2:]
cfgparser = openvpn3.ConfigParser(parser_args, 'Imports a configuration profile')
cfgparser.SanityCheck()
config_profile = cfgparser.GenerateConfig()

# Get a connection to the system bus
bus = dbus.SystemBus()

# Get a connection to the OpenVPN 3 Configuration Manager
config_mgr = openvpn3.ConfigurationManager(bus)

# Import the configuration as a multi-use, persistent configuration profile
config = config_mgr.Import(config_name, config_profile, False, True)
print('Configuration "%s" imported' % config_name)
print('Configuration path: ' + config.GetPath())

This will appear as src/tests/python/configimport2.py once committed and pushed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants