On 10/12/16 13:29, Gert Doering wrote:
> Hi,
> 
> On Sat, Dec 10, 2016 at 12:19:07AM +0100, Christian Hesse wrote:
>> +              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");
>> +
> 
> This is WAY over the top of what should go into OpenVPN code.  Really.
> 
> NAK on approach, NAK on code.
> 
> 
> Is there a way make sd_notify() behave like syslog()?  That is, you call
> something like "openlog()" which will acquire the necessary file descriptor
> and then you can afterwards chroot() to your heart's content and do not
> need access to the actual socket file anymore (because openlog() will
> keep it around for syslog() to use).

First of all, bind mounts are fairly common in Linux these days -
especially when you start to try to chroot/containerize (including
docker)/"jail" and otherwise isolate applications.  Chroots in general
are considered a bit too easy to escape from, unless privileges are
dropped at the right point.  Namespaces and other container techniques
are often somewhat better, but still does not yet provide the full
isolation many expects.  In this context bind mounts are often
considered simpler and to some degree safer than a full mount of /dev,
/proc, /sys, /run and so on.

Unfortunately, there exists no "openlog()" equivalent to my knowledge
for sd_notify() and other functions depending on the /run/systemd
directory.  But it's a good idea, and in fact such a "prepare for
chroot" in libsystemd could probably do such a bind mount for the
caller.  I have a good contact with one of the upstream systemd
developers and will discuss this with him ... so with time, we might
have something better.

Well, there is one feature systemd guys might throw at us instantly when
we open this topic ... PrivateNetwork=true in the unit file.  But that
is useless for OpenVPN as then we will only have access to the lo
network device, all other network devices are unavailable.

> If sd_notify() cannot be taught to do that, either do what David proposed
> (disable chroot if running under systemd), or at least move that code 
> out of init.c into something like platform.c.

That's a fair argument.  As long as thelibsystemd shipped in RHEL7 does
not, to our knowledge, carry such a feature which we need; implementing
this functionality inside platform.c is reasonable.

What I am wondering then is if we should implement platform_chroot()
which is called from init.c.  Where it will just call chroot() on
non-systemd and non-Windows systems.  When systemd is enabled and
detected detected it will prepare the bind mount, drop capabilities and
then call chroot().

Is that a reasonable approach?  Or would you prefer to have just the
bind mount stuff isolated into platform.c?


-- 
kind regards,

David Sommerseth
OpenVPN Technologies, Inc


Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
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