Unprivileged nested LXC containers


i would like to run unprivileged containers with nesting capabilities. By unprivileged, i mean not only that the root user of the container will not be the root user of the host system, but also that the user that will execute the lxc-unpriv-start command on the host system is an unprivileged user.

My understanding is that the config file of the containers should contain:

lxc.apparmor.profile = generated
lxc.apparmor.allow_nesting = 1

But then apparently only the root user of the host system can execute the lxc-unpriv-start command for such containers.

Is there a way to run unprivileged nested containers ? I am not sure about the meaning of generated in the configuration above, but i am OK with generating an apparmor profile as root and then execute lxc-unpriv-start as an unprivileged user.


You can’t use generated as you need root to generate profiles.

Instead you’d need to use lxc.apparmor.profile = lxc-container-default-with-nesting

Thanks for your answer.

I modified the lxc.apparmor.profile by replacing unconfined with lxc-container-default-with-nesting as you suggested.

However, if i install the podman package on the container (which runs Debian bookworm), then systemctl status podman shows the error:

[graphdriver] prior storage driver overlay failed: remount /var/lib/containers/storage/overlay, flags: 0x40000: permission denied

For further information, my config (which works well without nesting) is (the host runs Debian bookworm with lxc coming from the distro):

lxc.include = /usr/share/lxc/config/common.conf
lxc.include = /usr/share/lxc/config/userns.conf
lxc.arch = linux64

lxc.apparmor.allow_nesting = 1
lxc.idmap = u 0 231072 65536
lxc.idmap = g 0 231072 65536
# lxc.apparmor.profile = unconfined
lxc.apparmor.profile = lxc-container-default-with-nesting
lxc.mount.auto = proc:mixed sys:ro cgroup:mixed
lxc.start.auto = 1
lxc.start.delay = 5
lxc.init.cmd = /sbin/init systemd.unified_cgroup_hierarchy=1
lxc.rootfs.path = dir:/home/lxc2024/.local/share/lxc/nestest/rootfs
lxc.uts.name = nestest

lxc.net.0.type = veth
lxc.net.0.link = br60
lxc.net.0.flags = up
lxc.net.0.ipv6.address = 2001:***::12/80
lxc.net.0.ipv6.gateway = 2001:***::1

You may need to add your own policy to /etc/apparmor.d/lxc/.

Though note that most modern container managers will attempt to create and load apparmor policies of their own. The only way to really support that is by using apparmor namespacing which is what we do by default in Incus. But you need root privileges to create an apparmor namespace so you won’t be able to get that part working in your environment.

Now something you could do is just turn off apparmor with lxc.apparmor.profile=unconfined, since the container is already unprivileged and spawned by an unprivileged user, that shouldn’t really be a problem and may make podman happy.

Thanks for your advices. I will try to write an ad-hoc apparmor policy and have a look at what incus does with that respect (it makes me a bit nervous to let the containers apparmor-free).