From: Christian Hesse <m...@eworm.de>

sd_notify() uses a socket to communicate with systemd. Communication
fails if the socket is not available within the chroot. So bind mount
the socket into the chroot when startet from systemd.

Unsharing namespace and mounting requires extra capability CAP_SYS_ADMIN.

Signed-off-by: Christian Hesse <m...@eworm.de>
---
 distro/systemd/openvpn-client@.service |  2 +-
 distro/systemd/openvpn-server@.service |  2 +-
 src/openvpn/init.c                     | 37 +++++++++++++++++++---------------
 3 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/distro/systemd/openvpn-client@.service 
b/distro/systemd/openvpn-client@.service
index 5618af3..3ebd1da 100644
--- a/distro/systemd/openvpn-client@.service
+++ b/distro/systemd/openvpn-client@.service
@@ -13,7 +13,7 @@ RuntimeDirectory=openvpn-client
 RuntimeDirectoryMode=0710
 WorkingDirectory=/etc/openvpn/client
 ExecStart=/usr/sbin/openvpn --suppress-timestamps --nobind --config %i.conf
-CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_RAW CAP_SETGID 
CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE
+CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_RAW CAP_SETGID 
CAP_SETUID CAP_SYS_ADMIN CAP_SYS_CHROOT CAP_DAC_OVERRIDE
 LimitNPROC=10
 DeviceAllow=/dev/null rw
 DeviceAllow=/dev/net/tun rw
diff --git a/distro/systemd/openvpn-server@.service 
b/distro/systemd/openvpn-server@.service
index b9b4dba..bcf1bcf 100644
--- a/distro/systemd/openvpn-server@.service
+++ b/distro/systemd/openvpn-server@.service
@@ -13,7 +13,7 @@ RuntimeDirectory=openvpn-server
 RuntimeDirectoryMode=0710
 WorkingDirectory=/etc/openvpn/server
 ExecStart=/usr/sbin/openvpn --status %t/openvpn-server/status-%i.log 
--status-version 2 --suppress-timestamps --config %i.conf
-CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE 
CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE
+CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE 
CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_ADMIN CAP_SYS_CHROOT CAP_DAC_OVERRIDE
 LimitNPROC=10
 DeviceAllow=/dev/null rw
 DeviceAllow=/dev/net/tun rw
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 26b236d..81bf9ab 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -31,6 +31,9 @@
 #include "syshead.h"
 
 #ifdef ENABLE_SYSTEMD
+#include <string.h>
+#include <sched.h>
+#include <sys/mount.h>
 #include <systemd/sd-daemon.h>
 #endif
 
@@ -969,22 +972,24 @@ do_uid_gid_chroot (struct context *c, bool no_delay)
          if (no_delay)
             {
 #ifdef ENABLE_SYSTEMD
-              /* If OpenVPN is started by systemd, the OpenVPN process needs
-               * to provide a preliminary status report to systemd.  This is
-               * needed as $NOTIFY_SOCKET will not be available inside the
-               * chroot, which sd_notify()/sd_notifyf() depends on.
-               *
-               * This approach is the simplest and the most non-intrusive
-               * solution right before the 2.4_rc2 release.
-               *
-               * TODO: Consider altnernative solutions - bind mount?
-               * systemd does not grok OpenVPN configuration files, thus cannot
-               * have a sane way to know if OpenVPN will chroot or not and to
-               * which subdirectory it will chroot into.
-               */
-              sd_notifyf(0, "READY=1\n"
-                "STATUS=Entering chroot, most of the init completed 
successfully\n"
-                "MAINPID=%lu", (unsigned long) getpid());
+              int fd;
+              char * chroot_notify = NULL;
+
+              if (sd_notify(0, "READY=0") > 0)
+                {
+                  asprintf(&chroot_notify, "%s/notify", c->options.chroot_dir);
+
+                  if (unshare(CLONE_NEWNS) != 0)
+                    msg (M_ERR, "unshare failed");
+                  if ((fd = open(chroot_notify, O_WRONLY | O_CREAT | O_TRUNC, 
0644)) < 0)
+                    msg (M_ERR, "touch failed");
+                  close(fd);
+                  if (mount(getenv("NOTIFY_SOCKET"), chroot_notify, NULL, 
MS_BIND, NULL) != 0)
+                    msg (M_ERR, "bind mounting notification socket failed");
+
+                  setenv("NOTIFY_SOCKET", "/notify", 1);
+                  free(chroot_notify);
+                }
 #endif
               platform_chroot (c->options.chroot_dir);
             }
-- 
2.10.2


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today.http://sdm.link/xeonphi
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to