# Running as non-root user

In the simplest case, OpenConnect needs to be run as the root user in order to make changes to the system networking configuration. If it cannot create the local `tun` network interface, you will see an error such as:

      Failed to bind (TUNSETIFF) tun device: Operation not permitted

or in older versions, "`TUNSETIFF failed: Operation not permitted`". The path of least resistance is to run OpenConnect as root.

However, in some cases authentication needs to run as the unprivileged user — to access crypto tokens, password managers, for SAML authentication to spawn the user's browser, etc.

Even with plain password authentication it is better for security reasons if network-facing code can run without root privileges — so there are a few options which allow OpenConnect to run without root privileges.

## Pre-configured `tun` device

On Linux, it's possible to create its `tun` device in advance. For example:

    # ip tuntap add vpn0 mode tun user dwmw2

This creates a device `vpn0` which can be opened by user `dwmw2` who can pass traffic to/from it without needing any elevated privileges. You can now tell OpenConnect to use that device by adding "`-i vpn0`" to its command-line arguments. Note that the `/dev/net/tun` device node should be readable and writeable by everyone, since only privileged users can create or attach to tunnel devices anyway. (Some distributions misconfigure that, so if it isn't world-writeable then please file a bug against your distribution.)

Of course, something does also need to configure the IP addresses and routing. You could either add "`-s /bin/true`" to OpenConnect's command line to stop it trying to run vpnc-script for itself, and manually configure the network as root too. Or you could use "`-s 'sudo -E /etc/vpnc/vpnc-script'`" so that OpenConnect itself runs without elevated privileges but can still invoke `vpnc-script` as root. Note the `-E` part which ensures the environment variables with the configuration are actually passed through to `vpnc-script`.

NetworkManager usually has a dedicated unprivileged user `nm-openconnect` and runs OpenConnect as that user, having pre-created the `tun` device for it. OpenConnect then invokes a "vpnc-script" provided by NetworkManager which just passes all the configuration back to NetworkManager over DBus.

## Authenticate separately as yourself

A simpler option which works on non-Linux systems is just to run the authentication stage as your own user, passing the resulting authentication cookie to an `openconnect` process which runs as root. You can use the `--authenticate` option to OpenConnect, with a script such as the following:

    #!/bin/bash

    COOKIE=
    eval `openconnect --authenticate "$@"`
    if [ -z "$COOKIE" ]; then
        exit 1
    fi

    sudo openconnect --servercert "$FINGERPRINT" "$CONNECT_URL" --cookie-on-stdin ${RESOLVE:+--resolve "$RESOLVE"} <<< "$COOKIE"

Care must be taken to ensure that the second stage openconnect connects directly to the same server that the authentication ended at, after any any redirections, etc.

The same trick can be used to allow for more flexible authentication from the command line, while NetworkManager controls the actual connection:

      nmcli con up 'My VPN Configuration' passwd-file /proc/self/fd/5 5<<EOF
    vpn.secrets.cookie:$COOKIE
    vpn.secrets.gwcert:$FINGERPRINT
    vpn.secrets.gateway:$CONNECT_URL
    vpn.secrets.resolve:$RESOLVE
    EOF

## SOCKS / port-forwarding proxy

An alternative option which doesn't require any root access at all, is simply not to create the `tun` device and modify the system's network configuration. Instead, OpenConnect can spawn a user-supplied program, passing all data traffic through a UNIX socket to that program.

This option can be used in conjunction with a userspace TCP stack such as lwip to provide SOCKS access to the VPN, without requiring root privileges at all.

SOCKS proxy implementions suitable for being used from OpenConnect include:

- ocproxy
- tunsocks