Skip to content

Latest commit

 

History

History
360 lines (283 loc) · 17.8 KB

dbus-overview.md

File metadata and controls

360 lines (283 loc) · 17.8 KB

OpenVPN 3 Linux Client - D-Bus overview

The OpenVPN 3 client for Linux will be very different from what most users know from OpenVPN 2. The design goals for the Linux client is to utilize the facilities modern Linux distributions builds upon. The reason for this is to have a better privilege separation between the various operations OpenVPN needs to do and the users starting VPN tunnels. In Linux, D-Bus have gained a lot of traction and being worked actively on, and there are works in the pipe to facilitate some of the message processing into kernel space as well (aka Bus1).

If you have no prior experience with D-Bus, it is recommended to first read D-Bus primer - Understanding the bus.

D-Bus policies and user groups

What might be surprising is that even the root user on D-Bus is unprivileged when it comes to do operations on a D-Bus service. So the whole OpenVPN 3 design considers this and aims to provide the bare minimum of privileges to the services the OpenVPN 3 services provides over the D-Bus. The current design splits users into three distinct groups for the D-Bus policies implemented

  • Default: That is the default policy for all users, root included. The operations allowed over D-Bus will typically be processing of VPN configuration profiles and starting and management of VPN tunnels on the system
  • openvpn: The OpenVPN user account will have some restricted privileges to manage the OpenVPN services (typically backend VPN client processes)
  • root: The network configuration service (openvpn3-service-netcfg) needs to be started as root, but it will drop root privileges as soon as the needed capabilities have been set up. This service will at least require CAP_NET_ADMIN but might add more depending on the DNS configuration backend it is configured to use.

The default OpenVPN 3 D-Bus policy will be installed in /etc/dbus-1/system.d/net.openvpn.v3.conf, which is a location the D-Bus daemon is configured to use by default.

It is also possible to define much more fine grained policies which is managed by polkit (former Policy Kit), this is currently not implemented but is planned to be used in the future. The default actions are defined in XML files and the more fine grained policy processing is written JavaScript. These files are located in /etc/polkit-1 and /usr/share/polkit-1.

OpenVPN 3 D-Bus services

The OpenVPN 3 Client is split into several individual processes, called services in the D-Bus terminology. These processes runs in the background as daemons and only provides a D-Bus interface. Most of them are automatically started by the D-Bus main daemon when a front-end tries to establish contact with a service. If any of these object run idle for a certain time and does not carry any non-persistent data, they will automatically shutdown

Service net.openvpn.v3.log
Running as openvpn
Process name openvpn3-service-log
Started by Front-end clients and backend processes
Log service which receives all Log events from all of the OpenVPN 3 Linux services and directs them to log files or console logging. See also the OpenVPN 3 Linux Client: Logging document for more details on the logging.
Service net.openvpn.v3.configuration
Running as openvpn
Process name openvpn3-service-configmgr
Started by Front-end clients and backend processes
Stores VPN configuration profiles in a format used by the OpenVPN 3 Core library, as well as providing an API to query and modify configuration options.
Service net.openvpn.v3.sessions
Running as openvpn
Process name openvpn3-service-sessionmgr
Started by front-end clients
This service manages all VPN profiles being set up and throughout the whole life cycle until the VPN tunnel is disconnected.
Service net.openvpn.v3.netcfg
Running as openvpn
Process name openvpn3-service-netcfg
Started by net.openvpn.v3.backends
This is the process which is responsible for setting up the priviliged network configuration for the openvpn session client. It allows the session client to run unpriviledges and also provides a generic interface to open a tun device and configure the VPN configuration of (IP, routes, DNS). This process must be started as root.
Service net.openvpn.v3.backends
Running as openvpn
Process name openvpn3-service-backendstart
Started by net.openvpn.v3.sessions (as the openvpn user)
This service provides an interface for the session manager to start a the backend VPN client process
Service net.openvpn.v3.backends.be${PID}
Running as openvpn
Process name openvpn3-service-client
Started by net.openvpn.v3.backends
This is the process which is responsible for a single VPN tunnel. This process implements the OpenVPN 3 Core client, connects to remote servers and allows itself to be managed via the session manager. Each process will use its own unique service name, where the PID of the process is included in the service name.

In addition to these services, there needs to be a front-end application which interacts with these services on behalf of a user.

D-Bus services and auto-start configuration

The OpenVPN 3 Linux client will auto-start the various D-Bus services it depends on; this is a feature provided by the D-Bus message daemon. This means that if no OpenVPN clients have been started, the OpenVPN 3 client is not consuming any resources. Once a connection is prepared and setup, the various backend processes are automatically started with the right properties and privileges. Those processes running idle without anything to do for a while will automatically shutdown again by itself. This way the Linux client's backend processes are a zero-footprint implementation when it is not being used.

The auto-start profiles can be found in the /usr/share/dbus-1/system-services/net.openvpn.v3.*.service files.

Typical process of starting a VPN tunnel

The steps needed to establish a tunnel needs to do the following steps.

Initialize / provide configuration file

Step Import configuration file
D-Bus destination net.openvpn.v3.configuration
D-Bus path /net/openvpn/v3/configuration
D-Bus method net.openvpn.v3.configuration.Import
Returns Unique path to a new configuration object

This step imports a standard OpenVPN configuration file into the configuration manager. The configuration file must include all external files embedded into the data being imported.

Prepare tunnel

Step Create a VPN session object and prepare for connecting
D-Bus destination net.openvpn.v3.sessions
D-Bus path /net/openvpn/v3/sessions
D-Bus method net.openvpn.v3.sessions.NewTunnel
Returns Unique path to a new session object

This D-Bus method call needs to provide the unique path to a configuration object, provided by the Import call in the previous step. This call will return a unique object path to this particular VPN session.

If information from the user is required, the session manager will issue a AttentionRequired signal which describes what it requires. It is the front-end application's responsibility to act upon these signals. Alternatively, calling the net.openvpn.v3.sessions.Ready method can be used; see below for more details

Step Check if tunnel is ready to connect
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.Ready
Returns (nothing)

This method call must be called to ensure the backend VPN process is ready to connect. It will not return anything if it is ready to connect. Otherwise it will return an exception with more details.

Provide user credentials

If the Ready call results in an exception requiring user credentials or the front-end receives an AttentionRequired signal, it is needed to retrieve information about what the backend requires. All requirements are put into a User Input Queue.

Step Check what kind of credentials are requested
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.UserInputQueueGetTypeGroup
Returns An array of ClientAttentionType and ClientAttentionGroup tuples

Calling UserInputQueueGetTypeGroup will return an array of types (ClientAttentionType) and group (ClientAttentionGroup) references which have requirements the front-end needs to satisfy.

Step Check what kind of credentials are requested
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.UserInputQueueCheck
Returns

The UserInputQueueCheck needs to be called with the ClientAttentionType and ClientAttentionTypeGroup, this returns a list of IDs which needs to be fulfilled.

Step Retrieve information about a requirement
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.UserInputQueueFetch
Returns (nothing)

For each of these IDs, the front-end is required to call UserInputQueueFetch to get the needed information to provide to the front-end application. This application will then need to consider if the end-user will be presented with some prompts, or if it has direct access to the needed information through other channels.

Step Provide requested information to the backend
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.UserInputProvide
Returns (nothing)

This method needs the ClientAttentionType, ClientAttentionGroup, ID and a string containing the information the backend requested.

Step Check if tunnel is ready to connect
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.Ready`
Returns (nothing)

AttentionRequired signal vs UserInputQueueCheck

The AttentionRequired signal only provides a signal that some interaction is needed by the front-end process; think of it as a PUSH notification. The UserInputQueueGetTypeGroup and UserInputQueueCheck methods can be called at any time to check if some information is missing; think of it as a POLL operation.

Activate a VPN tunnel

Step Start connecting to the remote server
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.Connect`
Returns (nothing)

This starts the VPN tunnel and it will try to connect to the remote server. The call will return immediately and the front-end user application needs to watch the StatusChange and AttentionRequired signals to follow the real-time situation of the VPN connection. As with the tunnel preparation, the front-end application must respond to any AttentionRequired signal by calling the net.openvpn.v3.sessions.``UserInputProvide method.

In situations where the server requires more authentication credentials (dynamic challenge), the backend client will disconnect from the server and issue the AttentionRequired signal. By calling the Ready method, it will also throw an approriate exception if the authentication was not satisfied.

Pause, resume and restart an existing VPN tunnel

Step Temporarily suspend an active connection
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.Pause`
Returns (nothing)
Step Resume an already suspend an connection
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.Resume`
Returns (nothing)
Step Restart an active connection
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.Restart`
Returns (nothing)

This makes the VPN connection disconnect and then reconnect instantly.

Disconnect and stop the tunnel

Step Stops and disconnects a session
D-Bus destination net.openvpn.v3.sessions
D-Bus path Unique path to a specific session
D-Bus method net.openvpn.v3.sessions.Disconnect`
Returns (nothing)

This disconnects the VPN client from the server and shuts down the background VPN client process. This will also remove the D-Bus session object and the unique path to this session object will no longer be valid.

This is also used to shutdown the VPN client process, regardless if the VPN tunnel is active or not.