/
nonroot.xml
111 lines (94 loc) · 4.76 KB
/
nonroot.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<PAGE>
<INCLUDE file="inc/header.tmpl" />
<VAR match="VAR_SEL_FEATURES" replace="selected" />
<VAR match="VAR_SEL_FEATURE_NONROOT" replace="selected" />
<PARSE file="menu1.xml" />
<PARSE file="menu2-features.xml" />
<INCLUDE file="inc/content.tmpl" />
<h1>Running as non-root user</h1>
<p>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 <tt>tun</tt> network interface, you will see
an error such as:
<pre> Failed to bind (TUNSETIFF) tun device: Operation not permitted</pre>
or in older versions, "<tt>TUNSETIFF failed: Operation not permitted</tt>".
The path of least resistance is to run OpenConnect as root.
</p>
<p>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.</p>
<p>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.</p>
<h2>Pre-configured <tt>tun</tt> device</h2>
<p>On Linux, it's possible to create its <tt>tun</tt> device in advance.
For example:</p>
<pre>
# ip tuntap add vpn0 mode tun user dwmw2
</pre>
<p>This creates a device <tt>vpn0</tt> which can be opened by user <tt>dwmw2</tt>
who can pass traffic to/from it without needing any elevated privileges. You
can now tell OpenConnect to use that device by adding "<tt>-i vpn0</tt>" to
its command-line arguments. Note that the <tt>/dev/net/tun</tt> device node
should be readable and writeable by everyone, since only privileged users can
create or attach to tunnel devices anyway. <i>(Some distributions misconfigure
that, so if it isn't world-writeable then please file a bug against your
distribution.)</i></p>
<p>Of course, something does also need to <em>configure</em> the IP addresses
and routing. You could either add "<tt>-s /bin/true</tt>" 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
"<tt>-s 'sudo -E /etc/vpnc/vpnc-script'</tt>" so that OpenConnect itself
runs without elevated privileges but can still invoke <tt>vpnc-script</tt>
as root. Note the <tt>-E</tt> part which ensures the environment variables
with the configuration are actually passed through to <tt>vpnc-script</tt>.</p>
<p>NetworkManager usually has a dedicated unprivileged user <tt>nm-openconnect</tt>
and runs OpenConnect as that user, having pre-created the <tt>tun</tt> device for it.
OpenConnect then invokes a "vpnc-script" provided by NetworkManager which just
passes all the configuration back to NetworkManager over DBus.</p>
<h2>Authenticate separately as yourself</h2>
<p>A simpler option which works on non-Linux systems is just to run the
<em>authentication</em> stage as your own user, passing the resulting
authentication cookie to an <tt>openconnect</tt> process which runs as
root. You can use the <tt>--authenticate</tt> option to OpenConnect, with
a script such as the following:</p>
<table border="1"><tr><td>
<pre>
#!/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"} &lt;&lt;&lt; "$COOKIE"
</pre></td></tr></table>
<p>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.</p>
<p>The same trick can be used to allow for more flexible authentication from
the command line, while NetworkManager controls the actual connection:</p>
<pre>
nmcli con up 'My VPN Configuration' passwd-file /proc/self/fd/5 5&lt;&lt;EOF
vpn.secrets.cookie:$COOKIE
vpn.secrets.gwcert:$FINGERPRINT
vpn.secrets.gateway:$CONNECT_URL
vpn.secrets.resolve:$RESOLVE
EOF
</pre>
<h2>SOCKS / port-forwarding proxy</h2>
<p>An alternative option which doesn't require any root access
at all, is simply <em>not</em> to create the <tt>tun</tt> 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.</p>
<p>This option can be used in conjunction with a userspace TCP stack
such as <a href="https://savannah.nongnu.org/projects/lwip/">lwip</a>
to provide SOCKS access to the VPN, without requiring root privileges
at all.</p>
<p>SOCKS proxy implementions suitable for being used from OpenConnect
include:</p>
<ul>
<li><a href="https://github.com/cernekee/ocproxy">ocproxy</a></li>
<li><a href="https://github.com/russdill/tunsocks">tunsocks</a></li>
</ul>
<INCLUDE file="inc/footer.tmpl" />
</PAGE>