Unprivilegedl lxc containers potentially provide higher security levels than privileged ones. But they also have some limitations, like it is not easy to start them on boot, or give them a public IP address. These instructions teach how to achieve these goals.
These instructions have been developed taking as base Ubuntu 14.04 and its packages. They can be adapted to other recent Linux distributions.
-
Be sure you have installed lxc, bridge-utils, cgmanager-utils and cgroup-bin packages:
apt-get install apt-get install lxc bridge-utils cgmanager-utils cgroup-bin
-
Protect access to host dmesg, so in case of a compromised container it does not give clues about the host.
sysctl -w kernel.dmesg_restrict=1 grep -qF kernel.dmesg_restrict /etc/systctl.conf || echo "kernel.dmesg_restrict=1" >> /etc/sysctl.conf
-
Create one or more users which will manage the unprivileged containers:
useradd -b /vserver -c 'Unprivileged LXC user' -s /bin/bash -m -U lxc-unpriv
-
Change host network configuration in order to use a bridge. For instance, if the original network setup in /etc/network/interfaces contained:
auto eth0 iface eth0 inet dhcp
then it has to be translated into
auto eth0 iface eth0 inet manual auto br0 iface br0 inet dhcp bridge_ports eth0 bridge_stp off bridge_fd 0 bridge_maxwait 0
-
At this point, you should reboot the host, in order to be sure the network setup is still working.
-
Enable for the created users the bridge usage from lxc:
echo "lxc-unpriv veth br0 2" >> /etc/lxc/lxc-usernet
-
Copy files lxc-unprivileged.conf and lxc-unprivileged-instance.conf (included below) into /etc/init.
-
Declare your unprivileged users in /etc/default/lxc-unprivileged, with a line like this:
USERS="lxc-unpriv"
-
For the next steps, become each one of the unprivileged users:
sudo -iH -u lxc-unpriv /bin/bash
-
Setup the default lxc containers profile:
mkdir -p ~/.config/lxc/ echo "lxc.id_map = u 0 $(grep "^$USER:" /etc/subuid | cut -d ':' -f 2,3 --output-delimiter=' ')" > ~/.config/lxc/default.conf echo "lxc.id_map = g 0 $(grep "^$USER:" /etc/subgid | cut -d ':' -f 2,3 --output-delimiter=' ')" >> ~/.config/lxc/default.conf echo "lxc.network.type = veth" >> ~/.config/lxc/default.conf echo "lxc.network.link = br0" >> ~/.config/lxc/default.conf
-
Create one or more containers, for instance based on the same ubuntu release installed in the host:
lxc-create -t download -n u1 -B dir --dir ~/containers/u1 -- -d ubuntu -r $(lsb_release -c | cut -f 2) -a amd64
If the host is behind a firewall, you could have to add
--keyserver hkp://pool.sks-keyservers.net:443
(or--keyserver hkp://pool.sks-keyservers.net:80
) parameter to the previous line -
Label created containers as auto-startable:
echo "lxc.start.auto = 1" >> ~/.local/share/lxc/u1/config
-
Start the containers for the first time, and set them up as you need. Remember to setup network properly, as the containers are reachable at the same level as the host. Next time you reboot the host they will be started.
(PS: The idea of using a bridge was taken from (http://www.flockport.com/lxc-networking-guide/))