Skip to content

Non-root execution of monitor

To enhance security, urunc supports running the monitor process (VMM or seccomp monitor) as a non-root user. In this tutorial, we will walk through the necessary steps to set up the environment and successfully execute the monitor as a non-root user.

Requirements

The vast majority of supported monitors use KVM and therefore require access to /dev/kvm. This includes monitors like Solo5-hvt, Qemu, and Firecracker. In contrast, Solo5-spt does not require access to /dev/kvm. As such, when spawning the monitor process, we must ensure that it has the necessary permissions to access /dev/kvm.

Usually /dev/kvm has the following filesystem permissions:

$ ls -l /dev/kvm
crw-rw---- 1 root kvm 10, 232 Apr  3 08:10 /dev/kvm

In case the above permissions are different in your system, we strongly recommend to perform the following steps:

$ sudo groupadd kvm -r
$ sudo chown root:kvm /dev/kvm
$ sudo chmod 660 /dev/kvm

An important information we need to obtain is the group ID of kvm group:

$ getent group kvm
kvm:x:108:ubuntu

Running the monitor as non-root user

By default urunc will execute the monitor setting up the uid, gid and additionalGids from the container's OCI configuration. As a result, we simply need to instruct urunc to run a container as the desired user. However, since most monitors require access to /dev/kvm, we must ensure that the container is a member of the kvm group to grant the necessary permissions.

Docker and Nerdctl

In the case of docker and nerdctl, we can set the user and the groups of the container with the --user <uid>:<gid> option and the additional groups using --group-add <gid> for each additional group. Therefore, to run a KVM-enabled monitor with urunc as nobody, we use the following command:

$ sudo nerdctl run  --user 65534:65534 --group-add 108 --runtime "io.containerd.urunc.v2" --rm -it harbor.nbfc.io/nubificus/urunc/nginx-firecracker-unikraft-initrd:latest

Pay attention to the --group-add 108 option which instructs urunc to add the group with id 108 as an additional group for the container. The 108 id is the group id of kvm that we found previously.

On the other hand, if we are using a monitor that does not require access to /dev/kvm, such as Solo5-spt, then we can omit the --group-add command. As a result, the command will transform to:

$ sudo nerdctl run  --user 65534:65534 --runtime "io.containerd.urunc.v2" --rm -it harbor.nbfc.io/nubificus/urunc/net-spt-mirage:latest

Note The commands are the same for docker.

In a k8s deployment

Similarly, in the case of Kubernetes, we can specify the monitor's process user and groups by defining the container's user and groups. We can do that in the securityContext field of the deployment yaml:

securityContext:
  runAsUser: 65534
  runAsGroup: 65534
  supplementalGroups: [108]

As previously mentioned, if we want to run a monitor that requires access to /dev/kvm, we need to add the kvm's groupid in the supplementalGroups. Otherwise, we do not have to specify any supplementary group.

For more information regarding the Security Context of a Pod / Container take a look at Kubernetes's documentation.

Caveats

For monitors that require access to /dev/kvm, we need to ensure that the container (and, by extension, the monitor) is a member of the kvm group. This is unavoidable. Additionally, it is essential that the kvm group has the same ID across all nodes to make sure that all containers, regardless of the node, can access /dev/kvm.

Another caveat of this setup is access to the device mapper snapshot. In some cases, urunc uses the device mapper snapshot as a block device for the unikernel. However, the snapshot is typically created by root and belongs to the disk group. As a result, to use this feature of urunc, we will also need to add the container to the disk group, similar to how we handle the kvm group. Fortunately, there are options we can explore to address this issue, and we are actively working towards a solution.