Since all of the backend processes of the OpenVPN 3 Linux client is started automatically by D-Bus (through the auto-start service), it gets harder to debug what is happening straight out-of-the-box. But several tweaks have been added to ease this.
First, the OpenVPN 3 Linux client must be compiled with debug options.
This is done by running ./configure
with the --enable-debug-options
argument. It is also advisable to ensure the various tools under
src/tests/dbus
have been built as well.
There are six backend services to beware of.
openvpn3-service-configmgr
openvpn3-service-sessionmgr
openvpn3-service-backendstart
openvpn3-service-client
openvpn3-service-netcfg
openvpn3-service-log
All of these, with the exception of 4. openvpn3-service-client
can be
started from the command line. They will all have an idle time-out
mechanism, which means it will exit after some idle time if the service is
not in use. This can be disabled by adding --idle-exit 0
to the command
line.
All of these services can be started as the openvpn
user with the default
D-Bus policy, with the exception of openvpn3-service-netcfg
which must be
started as root - but it will fairly quickly drop all but the needed
capabilities and switch to the openvpn
user as well. If the other
services are being started as root
, they will also switch to openvpn
automatically.
All services except the openvpn3-service-log
has a --log-file
argument which can be set to stdout:
. This will print all log lines to
the console. The openvpn3-service-log
service will by default send
log events to the console.
The log verbosity can be controlled via the --log-level
argument.
Setting the log level to 6
will give the most verbose log data.
These backend services can be run via external debug tools directly on the
command line. However, the openvpn3-service-client
is different, as that
is started via openvpn3-service-backendstart
.
It is possible to attach a debugger to openvpn3-service-client
as well,
by running openvpn3-service-backendstart
on the command line together with
a few extra arguments. Just remember, this service must be started and
run as openvpn
for everything to function correctly.
# openvpn3-service-backendstart --idle-exit 0 \
--run-via $DEBUGGER \
--debugger-arg $DBG_ARG1 \
--debugger-arg $DBG_ARG2 \
--debugger-arg $DBG_ARG3
In some situations, it might not be wanted to have the
openvpn3-service-client
to daemonize and start a new process session id
(setsid(3P)
). This can be avoided by also adding --client-no-fork
and
--client-no-setsid
to the command line above.
To run openvpn3-service-client
via valgrind
, you could do like this:
# openvpn3-service-backendstart --idle-exit 0 \
--run-via /usr/bin/valgrind \
--debugger-arg "--leak-check=full"
To run openvpn3-service-client
via GDB, a different approach needs to be
taken - by using the remote debugging feature of GDB.
# openvpn3-service-backendstart --idle-exit 0 \
--client-no-fork \
--client-no-setsid \
--run-via /usr/bin/gdbserver \
--debugger-arg localhost:9944
In a different terminal, start gdb
like this:
# gdb openvpn3-service-client
[...snip...]
(gdb) target remote localhost:9944
When the session manager (openvpn3-service-sessionmgr
) starts a new
tunnel, the terminal with gdb
running will come back with a prompt where
you can continue the execution.
D-Bus is very sensitive to time-outs. These time-outs are normally
reasonable but you might hit several time-outs when using this way of
debugging. Further, by using --client-no-fork
it may also happen that
various openvpn3 front-ends will not respond as expected. In these cases,
using the openvpn3
Python module might be of help, where it is possible
to step through each of the various steps in a more controlled manner; see
below for details.
Ensure you have done a build using --enable-debug-options
when running
./configure
. This ensures the most crucial debug options are available.
By defining the G_DBUS_DEBUG
environment variable, it is possible to
inspect the various D-Bus messages being passed to/from a glib2 based D-Bus
service or client. The most verbose debug logging is gained with using
G_DBUS_DEBUG=all
. For more details see the upstream Glib2
Running GIO applications: GIO Reference Manual documentation.
To pass the G_DBUS_DEBUG
variable to the openvpn3-service-client
process, the openvpn3-service-backendstart
need to be started with
--client-setenv G_DBUS_DEBUG=all
, which will dump all D-Bus operations
the openvpn3-service-client
process handles to the console.
It is fully possible to get a more fine grained control of starting tunnels.
The easiest way is by using Python and the openvpn3 module. It is advisable
to first import the OpenVPN configuration profile via
openvpn3 config-import
. This will give you a configuration D-Bus path
which can be easily used further.
#!/usr/bin/python3
import dbus
import openvpn3
# Shared D-Bus System Bus connection
sysbus = dbus.SystemBus()
# Get access to the configuration manager
cfgmgr = openvpn3.ConfigurationManager(sysbus)
# Retrieve access to the configuration profile
cfg = cfgmgr.Retrieve('/net/openvpn/v3/configuration/some-path')
# Get access to the session manager
sessmgr = openvpn3.SessionManager(sysbus)
# Create a new VPN session, based on the retrieved configuration
sess = sessmgr.NewTunnel(cfg)
print("Session path: %s" % sess.GetPath())
# Various actions to do on the session object
sess.Ready() # Ready for connection?
sess.Connect() # Start a connection
sess.Pause() # Pause the connection
sess.Resume() # Resume the connection
sess.Disconnect() # Disconnect and close the session. The session
# object is invalid after this call.
The methods available in the configuration manager object (cfgmgr
),
configuration object (cfg
), session manager object (sessmgr
) and the
session object (sess
) mostly works in the same way and with the same
names as the D-Bus raw API for these objects. The most noticeable
difference is the Retrieve(path)
and GetPath()
methods as well as the
interface for providing username/password credentials to a session object.
See src/tests/python
for more examples.
D-Bus by design is quite strict when it comes to services using the system
bus. This means it can quite often happen that D-Bus calls or signals are
being rejected by the D-Bus daemon. The best way to detect these issues,
is to look into the D-Bus logs. On systems with systemd, this is easily
done via journalctl --since today -u dbus
. All log events processed by
openvpn3-service-log
will typically also be present here.
Almost all log events happens exclusively over D-Bus. Some of these log
events are targeted to either the session manager or the
openvpn3-service-log
service. To retrieve logs it is therefore needed
to run openvpn3-service-log
with the --service
argument as the
openvpn
user. This ensures that the services will fetch log entries
directly.
Most of the time it is possible to use
$ openvpn3 log --log-level 6 --session-path ${SESSION_DBUS_PATH}`
This will give real-time logging for a specific running VPN session. Just
remember that the general log level must also be set to 6
. This is done
by running the command below as root:
# openvpn3-admin log-service --log-level 6
To retrieve prior log events on systems with systemd-journald
active,
you can run this command as root:
# openvpn3-admin journal
See the openvpn3-admin-journal\(8)
man-page for more details.
If no log events happens with openvpn3-service-log
, the
openvpn3-service-backendstart
can be run with
--client-signal-broadcast
. Enabling this will send all backend client
signals as system wide D-Bus broadcast signals.
When compiling from source, there are more debug tools under
./src/tests/dbus
:
-
signal-listener
: Dumps almost all D-Bus signals broadcasts on the system. This is quite low-level and will not show any "targeted" signals towards a specific recipient. It will also decode some of the OpenVPN 3 specific D-Bus signals. -
log-listener
,log-listener2
: Variants ofsignal-listener
which only listens forLog
signals. -
logservice1
andopenvpn3 log-service
: Can be used to query and modify properties in theopenvpn3-service-log
service. Thelogservice1
can also be used to generate some log events.