If run under network manager, OpenVPN starts with uid=0 and
'--user nm-openvpn', but is lacking the CAP_SETPCAP capabilities
to retain CAP_NET_ADMIN after dropping root privileges.
In DCO mode, OpenVPN must have CAP_NET_ADMIN today, always, otherwise
TLS renegotiation / key rotation will not be possible.
So, check at startup, if --user is specified, if CAP_NET_ADMIN is
permitted and CAP_SETPCAP is available. If either of the capabilities
is missing, disable DCO. Traditional tun/tap works with "uid=0 on
tun open, and setuid() afterwards".
Long-Term, get NM to enable OpenVPN to run with CAP_NET_ADMIN.
Debian bug report: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=
1017379
Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
Tested-By: Bernhard Schmidt <berni@birkenwald.de>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <
20220817131817.467-1-timo@rothenpieler.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24952.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
#include "ssl_ncp.h"
#include "tun.h"
+#ifdef HAVE_LIBCAPNG
+#include <cap-ng.h>
+#endif
+
static int
dco_install_key(struct tls_multi *multi, struct key_state *ks,
const uint8_t *encrypt_key, const uint8_t *encrypt_iv,
}
}
#endif /* if defined(TARGET_LINUX) */
+
+#if defined(HAVE_LIBCAPNG)
+ /* DCO can't operate without CAP_NET_ADMIN. To retain it when switching user
+ * we need CAP_SETPCAP. CAP_NET_ADMIN also needs to be part of the permitted set
+ * of capabilities in order to retain it.
+ */
+ if (o->username)
+ {
+ if (!capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP))
+ {
+ msg(msglevel, "--user specified but lacking CAP_SETPCAP. "
+ "Cannot retain CAP_NET_ADMIN. Disabling data channel offload");
+ return false;
+ }
+ if (!capng_have_capability(CAPNG_PERMITTED, CAP_NET_ADMIN))
+ {
+ msg(msglevel, "--user specified but not permitted to retain CAP_NET_ADMIN. "
+ "Disabling data channel offload");
+ return false;
+ }
+ }
+#endif /* if defined(HAVE_LIBCAPNG) */
return true;
}