LXC using unprivileged containers

Unprivileged containers are a upstream LXC feature that currently works on the latest versions of Ubuntu. They depend on user namespace support in the Linux kernel and allow non-root users to run containers.

Unprivileged containers provide an additional layer of isolation and security. The root user in the container is NOT the root user on the system. Apart from security benefits this also begins to pave the way for multi-tenant workloads.

Unfortunately like a lot of new LXC features they work properly only on the latest versions of Ubuntu due to dependencies. Unprivileged containers have a number of requirements, which are currently available only in Ubuntu 14.04, so users of other distributions are out of luck for now. Here is what you need.

  • Kernel 3.13 +
  • LXC 1.0 but 1.0.5 + preferred
  • Per user cgroups support so cgmanager package required
  • systemd-libs
  • pam with loginuid patch
  • uidmap

Ubuntu 14.04 supports all the above out of the box. This won't work on most distributions without the above. Some advanced users may have got it to work in other distributions after going through a lot of hoops, but its not trivial to get it working.

We are presuming you already have a working LXC installation in Ubuntu, if you don't please refer to the LXC installation guide. Once your LXC installation is working properly and you can create and use containers, you can move to the next step.

Install systemd-services and uidmap

sudo apt-get install systemd-services uidmap

Next you need to create LXC configuration files for your user. This is how the system LXC config files match to the user config files.

/etc/lxc/lxc.conf => ~/.config/lxc/lxc.conf
/etc/lxc/default.conf => ~/.config/lxc/default.conf
/var/lib/lxc => ~/.local/share/lxc
/var/lib/lxcsnaps => ~/.local/share/lxcsnaps
/var/cache/lxc => ~/.cache/lxc

At a minimum create the .config/lxc/default.conf, .local/share/lxc to store containers and .cache/lxc for the downloaded container templates cache in your user's home directory.

mkdir .config/lxc .local/share/lxc .cache/lxc

Now in .config/lxc create a default.conf file with the config below.

nano default.conf

lxc.network.type = veth
lxc.network.link = lxcbr0
lxc.network.flags = up
lxc.network.hwaddr = 00:16:3e:xx:xx:xx
lxc.id_map = u 0 100000 65536
lxc.id_map = g 0 100000 65536

Notice the lxc.id_map entries. Now you need to allocate allocate additional uids & gids to your username.

sudo usermod --add-subuids 100000-165536 username
sudo usermod --add-subgids 100000-165536 username

You also need to create a lxc-usernet file for unprivileged containers in /etc/lxc/lxc-usernet

sudo nano /etc/lxc/lxc-usernet

Add this bit into the lxc-usernet file. Change the username to your username.

username veth lxcbr0 10

This allows the user specified to create 10 veth interfaces

To create unprivileged containers you need to use the 'download' template type. These container OS templates are designed to support unprivileged containers. Its important to clarify at this point containers created without the download template type will not work in unprivileged mode as those container OS templates are not designed to. So let's create our first unprivileged container.

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

This should create the p1 container in your user's .local/share/lxc folder. Now start the container.

lxc-start -n p1 -d

This should start the container. You can use lxc-console to enter the container. The newer lxc container OS templates do not have openssh installed by default and you need to setup openssh-server to log in to the container over ssh.

There have been some reports using lxc-ls -f to get container information or using lxc-attach to enter the container around user namespaces doesn't work. 1.0.5 + versions of the lxc packages should fix this and both these tools should work.

So now you have a container that can be deployed by users, providing all the security advantages of not running as root. Hopefully this functionality will become more easily available to users of other distributions.

Ubuntu's extension of LXC with the recent announcement of the LXD project to provide container management across LXC hosts uses unprivileged containers by default. There is a lot of focus and impetus by Ubuntu on container deployment infrastructure and making this more widely available so exciting days ahead.

Run unprivileged containers as root
Normally containers launched by root run as privileged, with this you can run unprivileged containers as root. You only need a subset of the steps above.

First allocate additional uids & gids to root

sudo usermod --add-subuids 100000-165536 root
sudo usermod --add-subgids 100000-165536 root

Then edit /etc/lxc/default and append lxc.uidmap entry like below

lxc.id_map = u 0 100000 65536
lxc.id_map = g 0 100000 65536

That's it! Now any container you create as root will be an unprivileged container.

Tip: If you want to use it as a one off simply add the 2 lxc.id.map lines to the container config in /var/lib/lxc, and not /etc/lxc/default.

You may get a permission error when starting the container. In this case change the permissions on the /var/lib/lxc folder.

chmod o+x /var/lib/lxc

Remember you need to use the 'download' template when creating unprivileged containers.

Recommended Posts

Leave a Comment


Register | Lost your password?