11

This question is similar to No tun device in lxc guest for openvpn . The LXC has evolved and the unprivileged LXC containers were introduced recently that offer another layer of security against breaking the jail.

I need to create an OpenVPN server inside one of the unprivileged container. I don't know how to let the container create a private tun network device.

I did append lxc.cgroup.devices.allow = c 10:200 rwm to the ~/.local/share/lxc/mylxc/config.

After starting the container, mknod /dev/net/tun c 10 200 returns mknod: '/dev/net/tun': Operation not permitted inside the container.

I use a vanilla Ubuntu 14.04 64bit as host and a container created with

lxc-create -t download -n mylxc  -- -d ubuntu -r trusty -a amd64

Did anyone managed to get /dev/tun device running under unprivileged LXC?

1
  • For information, to make openvpn work in an unprivileged LXC container, I had to add lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file to the container config file, like described here: superuser.com/a/1205662/130915 Then, I ran openvpn as root with sudo inside of the container.
    – baptx
    Jan 28 '19 at 19:38
3

You need to explicitly add the CAP_MKNOD capability to your container.

  lxc.cap.keep
          Specify the capability to be kept in the container. All other
          capabilities will be dropped. When a special value of "none"
          is encountered, lxc will clear any keep capabilities specified
          up to this point. A value of "none" alone can be used to drop
          all capabilities.

You could also try to automate this (if you happen to use systemd inside the container) using:

  lxc.hook.autodev
          A hook to be run in the container's namespace after mounting
          has been done and after any mount hooks have run, but before
          the pivot_root, if lxc.autodev == 1.  The purpose of this hook
          is to assist in populating the /dev directory of the container
          when using the autodev option for systemd based containers.
          The container's /dev directory is relative to the
          ${LXC_ROOTFS_MOUNT} environment variable available when the
          hook is run.

which can point to a script running mknod.

Using docker this is very easy to accomplish. By default, containers are unprivileged.

In this example, I'm pulling a trusty container from the registry:

sudo -r sysadm_r docker pull corbinu/docker-trusty
Pulling repository corbinu/docker-trusty
...
Status: Downloaded newer image for corbinu/docker-trusty:latest

And I'm starting it in interactive mode informing about the capability I need inside:

sudo -r sysadm_r docker run --cap-drop ALL --cap-add MKNOD \
  -i -t corbinu/docker-trusty bash
root@46bbb43095ec:/# ls /dev/
console  fd/      full     fuse     kcore    mqueue/  null     ptmx     pts/     random   shm/     stderr   stdin    stdout   tty      urandom  zero
root@46bbb43095ec:/# mkdir /dev/net
root@46bbb43095ec:/# mknod /dev/net/tun c 10 200
root@46bbb43095ec:/# ls -lrt /dev/net/tun
crw-r--r--. 1 root root 10, 200 Apr  6 16:52 /dev/net/tun

As opposed to:

sudo -r sysadm_r docker run --cap-drop ALL \
  -i -t corbinu/docker-trusty bash
root@9a4cdc75a5ec:/# mkdir /dev/net
root@9a4cdc75a5ec:/# mknod /dev/net/tun c 10 200
mknod: ‘/dev/net/tun’: Operation not permitted
5
  • 1
    I believe, what docker calls "unprivileged" is quite different from what it means in LXC parlance: github.com/docker/docker/issues/7906 . It seems that Docker still don't support the unprivileged containers. It doesn't necessarily invalidate your answer - I'll check CAP_MKNOD after work. Apr 7 '15 at 14:47
  • 1
    Can you give me please a little pointer on how to change the capability of the unprivileged container? At least a correct phrase to Google? Apr 26 '15 at 8:31
  • 3
    Adding the lxc.cap.keep = CAP_MKNOD to config makes error Simultaneously requested dropping and keeping caps. I checked all recursively added configs (ubuntu.userns.conf, ubuntu.common.conf and common.conf) and found only one line with lxc.cap.drop: lxc.cap.drop = mac_admin mac_override sys_time sys_module. But that is irrelevant isn't it? Apr 26 '15 at 8:44
  • You need to explicitly add the CAP_MKNOD capability to your container. How to do that for an existing LXC Container? Nov 15 '21 at 13:46
  • @PhilippLudwig stackoverflow.com/a/1422879/2248946
    – dawud
    Nov 15 '21 at 21:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.