Hi all,

Here are some ideas how the VPN functionality in ConnMan
could look like in the future. This mail is more like
base for brainstorming and not a concrete plan.

Currently VPN functionality is implemented via VPN plugin in
ConnMan. The master VPN plugin uses individual VPN plugins
like OpenVPN, OpenConnect, vpnc etc. to launch the VPN client
programs that then connect to VPN servers.

The VPN client programs are run as root user because they need
to open the tunneling device. If the client VPN programs could
access the tun device as normal user, then we could avoid
running VPN client as root user which can be a security risk.

In order to run VPN stuff as normal user, it is necessary to
move the VPN functionality into separate daemon that can start
the VPN clients with lowered privileges. Some VPN clients already
support privilege dropping (like Openconnect and Openvpn), in this
case the setup is quite simple.

If we have VPN functionality handled by separate daemon, then the
memory consumption of connmand could be made lower if the user
does not need VPN connectivity.

Some VPN technologies do not use tun device (L2TP/PPTP and IPSec).
They would continue to be run as root user as they need access
to privileged host resources.

I called this VPN daemon as vpnrunner (and not vpnd because are
existing vpnd daemons already). The name can be changed of course
if necessary. The vpnrunner would be started via dbus activation.
It would typically started by ConnMan when ConnMan would need
VPN connection.

The system could look like this:

         ConnectProvider()
    +------+                +----------+
    | user |--------------->| connmand |<-------+
    +------+                +----------+        |
                               |    |           |
                       Start() |    | Stop()    | Stopped()
                               |    |           |
                               |    |           |
                               V    V           |
                     +------------------+       |
                     |     vpnrunner    |-------+
                     +------------------+
                        |   |     ^   ^
                 fork/  | fd|    w|   |
                 exec   |   |    a|   | Password() dbus call
                        |   |    i|   |
                        V   V    t|   |
                     +-------------------+
                     |    VPN client     |
                     +-------------------+

When user initiates ConnMan Manager.ConnectProvider() method call,
connmand then starts vpnrunner which would then create necessary
tun devices (if needed). The tun device creation is done in vpnrunner
because it knows if the tun device is needed by VPN client or not.

The main idea is that VPN functionality is moved from ConnMan to
vpnrunner and if ConnMan needs VPN, it just uses simple dbus API
to ask VPN service. The same dbus API could be used by other network
managers also.
One open issue is the route handling so ConnMan would
need to know which routes belong to VPN service so that ConnMan
can set the default route properly.

The vpnrunner is then started (if not already running). It first
checks if the desired VPN technology supports running as a normal
user (this information is set by VPN plugin in vpnrunner).
If VPN only supports running as root (like xl2tpd), the vpnrunner
does not change its identity but stays as root, otherwise the
identity is changed to "nobody" user.

If the VPN technology supports running as a normal user, then a Unix
domain socket is created and its name is set as a parameter when
starting the VPN client. The tun device file descriptor is passed to
VPN daemon via the Unix domain socket. This fd passing requires
changes to the VPN client software. Of course this fd passing is not
needed if the VPN client can lower the privileges itself.

The vpnrunner then forks and execs the desired VPN client.
If the VPN client is killed, the exit status is received in wait()
call in vpnrunner.

If VPN client needs tunnel password (at least l2tp usually needs it),
the password is asked from vpnrunner via a separate dbus call (named
Password in above diagram). This is similar how the password is
passed to VPN client in existing ConnMan 1.0.

If VPN service is disconnected by connmand, then connmand will call
vpnrunner.Manager.Stop() method. Vpnrunner will then kill VPN client.
When the client is killed and before vpnrunner exists, the
vpnrunner.Manager.Stopped() signal is sent to connmand. The Stopped()
signal is also sent if there is some error and VPN client cannot be
started.

The steps to separating VPN could be like this:
- Create a separate daemon and move VPN functionality from
  ConnMan to it. There needs to be dbus API defined between
  ConnMan and vpnrunner.
- When the separation works, start to experiment with privilege
  dropping.
- The time frame for this change would be more like ConnMan 2.0
  than ConnMan 1.3


Comments?



Cheers,
Jukka

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to