Ubuntu 14.04 LXC Setup with Unprivileged Containers

Ubuntu 14.04 LXC Setup with Unprivileged Containers

I have been spending a lot of time searching for alternatives to virtual machines. I do love my VMs but I hate the idea of dedicating resources (such as RAM) that never get used. There is memory ballooning but it is a trade off for the usage of other resources. Also I am crazy and obsessive about efficiency. VMs still have their place but we now have a new, awesome tool available to us: LXC.


The LXC team offers us a PPA making this setup super easy. This will also handle future updates for us.

Install the software…
sudo apt-add-repository -y ppa:ubuntu-lxc/stable
sudo apt-get update
sudo apt-get install lxc


You could skip this step but then you would only be able to access your containers on the same host on which they are run. There is also port forwarding (say, via iptables) but that is overly complicated for anything other than simple TCP/UDP stuff (and boring). We are going to do a bridge so that all containers can access the network and all remote hosts can access the containers as if they were physical machines on the network.

This should have been installed with LXC but just to be safe…
sudo apt-get install bridge-utils

Fire up your favorite text editor and open /etc/network/interfaces. In it add
auto lxcbr0
iface lxcbr0 inet static
 address [primary IP address]
 netmask [primary netmask]
 gateway [primary gateway]
 dns-nameservers [primary DNS server(s)]
 bridge_ports [primary network interface]

replacing everything above within and including the brackets.

Next we need to replace all lines for the primary network interface with
iface eth0 inet manual

You may have multiple network segments. Configuring this is left as an exercise for the user.

Unprivileged Containers

We could just start creating containers now. However a potential problem may arise as they will all be run as root. Theoretically this is fine because you should never be able to break out of a container but bugs happen. So we are not making ourselves more vulnerable than we need to be we will be setting up unprivileged containers to be run as our unprivileged user.

Allow our user account to use the bridge…
echo "$USER veth lxcbr0 1024" | sudo tee -a /etc/lxc/lxc-usernet

Create Upstart script…
In /etc/init/lxc-unprivileged.conf add…
description "LXC Unprivileged Containers"
author "Mike Bernson <mike@mlb.org>"

start on started lxc


 for u in $USERS; do
  cgm create all lxc$u
  cgm chown all lxc$u $(id -u $u) $(id -g $u)
  lxc-autostart -L -P /home/$u/.local/share/lxc | while read line;
   set -- $line
   /usr/local/bin/startunprivlxc lxc$u $u $1
   sleep $2
end script

Make sure to replace [user] with your user account.

Create the container start script…
In /usr/local/bin/startunprivlxc add…

cgm movepid all $1 $$
sudo -iH -u $2 -- lxc-start -n $3 -d

… and make it executable…
sudo chmod +x /usr/local/bin/startunprivlxc

Create our mappings and settings for our containers to use…
mkdir -p ~/.config/lxc/
echo "lxc.id_map = u 0 100000 65536" > ~/.config/lxc/default.conf
echo "lxc.id_map = g 0 100000 65536" >> ~/.config/lxc/default.conf
echo "lxc.network.type = veth" >> ~/.config/lxc/default.conf
echo "lxc.network.link = lxcbr0" >> ~/.config/lxc/default.conf

Create Contaiers

Here is where the magic happens.

lxc-create --name [name] --template download

Again with the text editor open ~/.local/share/lxc/[name]/config. In it add
lxc.start.auto = 1

Make sure to replace [name] with your container name in both commands.

These two steps will allow you to create new, unprivileged containers which autostart on boot running the distribution, release, and architecture of your choice.

Attach to Contaiers

In order to get into the console you only need a single command…
lxc-attach --name [name]

If you like you can use this to install an SSH server (do not forget to setup a new user so you are not logging in as root). You could also just log into the host and lxc-attach each time. Up to you.


There are many more things you can do. For example, create separate networks (say, one for public communications and another for container-to-host-to-container communications) or limit resources so one rouge container does not ruin it for the others and the host itself. A dedup‘ing filesystem (such as ZFS) would also probably get great ratios.

Research, experiment, and play with this very cool bit of engineering.




Mike Bernson


Leave a Reply

Your email address will not be published. Required fields are marked *