The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/1593
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Hi everyone, **TL;DR: proposing a new hook named "privileged-start" that I use to start systemd without `CAP_SYS_ADMIN` on a kernel with cgroup namespaces.** My original goal was to start a LXC container with systemd but without `CAP_SYS_ADMIN` on a recent kernel (which have cgroup namespaces). It's quite difficult as you have to pre-mount everything for systemd. I found a very detailed article named [LXC containers without CAP_SYS_ADMIN under Debian Jessie ](https://blog.iwakd.de/lxc-cap_sys_admin-jessie). Unfortunately, the way cgroup are managed doesn't work if your kernel support cgroup namespaces. (In other words, `lxc.mount.auto = cgroup` doesn't work as it does nothing if it detects cgroup ns support). When you have cgroup namespaces, it appears that you have to mount cgroup AFTER unsharing the cgroup namespace but BEFORE the capability drop, as `CAP_SYS_ADMIN` is required to mount them. So my PR is about this hook that I added just before the capability drop. So, now, I'm able to start a container with the following configuration: ```ini # path of the file on the host: /var/lib/lxc/test/config # ... (the default configuration) lxc.mount.auto = proc:rw sys:rw lxc.mount.entry = tmpfs dev/shm tmpfs rw,nosuid,nodev,create=dir 0 0 lxc.mount.entry = tmpfs run tmpfs rw,nosuid,nodev,mode=755,create=dir 0 0 lxc.mount.entry = tmpfs run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k,create=dir 0 0 lxc.mount.entry = tmpfs run/user tmpfs rw,nosuid,nodev,mode=755,size=50m,create=dir 0 0 lxc.hook.priv-start = /bin/mountall lxc.cap.drop = sys_admin ``` And with this hook: ```bash #!/bin/bash # path of the file on the host: /var/lib/lxc/test/rootfs/bin/mountall mount -t tmpfs tmpfs /sys/fs/cgroup mkdir -p /sys/fs/cgroup/systemd mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,xattr,name=systemd cgroup /sys/fs/cgroup/systemd ``` *I don't want to keep `CAP_SYS_ADMIN` as this capability is often considered as [the new root](https://lwn.net/Articles/486306/) by authorizing [too many things](http://man7.org/linux/man-pages/man7/capabilities.7.html).*
From 8614a1fc421176168e966791672e5401a3df03c4 Mon Sep 17 00:00:00 2001 From: Quentin Dufour <[email protected]> Date: Sun, 28 May 2017 23:11:24 +0200 Subject: [PATCH] Add a new hook named privileged-start --- src/lxc/conf.c | 9 ++++++++- src/lxc/conf.h | 3 ++- src/lxc/confile.c | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 85805f975..038a6c213 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -239,7 +239,7 @@ extern int memfd_create(const char *name, unsigned int flags); #endif char *lxchook_names[NUM_LXC_HOOKS] = { - "pre-start", "pre-mount", "mount", "autodev", "start", "stop", "post-stop", "clone", "destroy" }; + "pre-start", "pre-mount", "mount", "autodev", "priv-start", "start", "stop", "post-stop", "clone", "destroy" }; typedef int (*instantiate_cb)(struct lxc_handler *, struct lxc_netdev *); @@ -4227,6 +4227,11 @@ int lxc_setup(struct lxc_handler *handler) return -1; } + if (run_lxc_hooks(name, "priv-start", lxc_conf, lxcpath, NULL)) { + ERROR("failed to run privileged-start hooks for container '%s'.", name); + return -1; + } + if (!lxc_list_empty(&lxc_conf->keepcaps)) { if (!lxc_list_empty(&lxc_conf->caps)) { ERROR("Container requests lxc.cap.drop and lxc.cap.keep: either use lxc.cap.drop or lxc.cap.keep, not both."); @@ -4260,6 +4265,8 @@ int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf, which = LXCHOOK_MOUNT; else if (strcmp(hook, "autodev") == 0) which = LXCHOOK_AUTODEV; + else if (strcmp(hook, "priv-start") == 0) + which = LXCHOOK_PRIVSTART; else if (strcmp(hook, "start") == 0) which = LXCHOOK_START; else if (strcmp(hook, "stop") == 0) diff --git a/src/lxc/conf.h b/src/lxc/conf.h index a0bb05b0a..f98596656 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -301,7 +301,8 @@ enum { */ enum lxchooks { LXCHOOK_PRESTART, LXCHOOK_PREMOUNT, LXCHOOK_MOUNT, LXCHOOK_AUTODEV, - LXCHOOK_START, LXCHOOK_STOP, LXCHOOK_POSTSTOP, LXCHOOK_CLONE, LXCHOOK_DESTROY, + LXCHOOK_PRIVSTART, LXCHOOK_START, LXCHOOK_STOP, LXCHOOK_POSTSTOP, + LXCHOOK_CLONE, LXCHOOK_DESTROY, NUM_LXC_HOOKS}; extern char *lxchook_names[NUM_LXC_HOOKS]; diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 4114e9fff..771589814 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -152,6 +152,7 @@ static struct lxc_config_t config[] = { { "lxc.hook.pre-mount", config_hook }, { "lxc.hook.mount", config_hook }, { "lxc.hook.autodev", config_hook }, + { "lxc.hook.priv-start", config_hook }, { "lxc.hook.start", config_hook }, { "lxc.hook.stop", config_hook }, { "lxc.hook.post-stop", config_hook }, @@ -1196,6 +1197,8 @@ static int config_hook(const char *key, const char *value, return add_hook(lxc_conf, LXCHOOK_AUTODEV, copy); else if (strcmp(key, "lxc.hook.mount") == 0) return add_hook(lxc_conf, LXCHOOK_MOUNT, copy); + else if (strcmp(key, "lxc.hook.priv-start") == 0) + return add_hook(lxc_conf, LXCHOOK_PRIVSTART, copy); else if (strcmp(key, "lxc.hook.start") == 0) return add_hook(lxc_conf, LXCHOOK_START, copy); else if (strcmp(key, "lxc.hook.stop") == 0)
_______________________________________________ lxc-devel mailing list [email protected] http://lists.linuxcontainers.org/listinfo/lxc-devel
