[lxc-users] unprivileged container with overlayfs
Jan Kowalsky
jankow at datenkollektiv.net
Wed Sep 20 09:20:13 UTC 2017
Hi all,
I'm experimenting with unprivileged containers based on overlayfs
snapshots. The goal is to have semi-unprivileged (running as root but
with mapped uids/gids) containers based on a template image.
What I found out: with a unpatched Kernel <= 4,9 there is no possibility
to use overlayfs for unprivileged containes out of the box. While Ubuntu
14.4 seems to have a patched kernel:
https://github.com/lxc/lxc/issues/1370 for making this possible it has
some security implications: https://lwn.net/Articles/671641/.
Instead of using the built in functionality in lxc for creating and
starting overlayfs containers it's possible to just create the overlay
mount before starting the container.
So my approach is:
* creating a base-template-container with "dir" storage
* cloning it as a overlayfs snapshot and create a pre-start hook,
mounting the base-template rootfs and the delta0 to a newly created
rootfs directory inside the new overlay snapshot
* editing the config and adjust the lxc.rootfs and the
lxc.rootfs.backend
The latter we can automate with a lxc.hook.clone.
My question to you: are there any problematic implications for this
approach? Why we should risk a kernel patch with possible security
implications while achieving the same with mounting the overlayfs on
pre-start?
My Configs:
# cat /var/lib/lxc# cat stretch-overlay-unpriv/config
lxc.include = /usr/share/lxc/config/debian.common.conf
# Container specific configuration
lxc.tty = 4
lxc.arch = amd64
# network
lxc.network.type = veth
lxc.network.link = lxc-bridge-nat
# unpriv
lxc.id_map = u 0 296608 65536
lxc.id_map = g 0 296608 65536
lxc.rootfs = /var/lib/lxc/stretch-overlay-unpriv/rootfs
lxc.rootfs.backend = dir
lxc.utsname = stretch-overlay-unpriv
# clone hook for unprivileged overlayfs container
lxc.hook.clone = /var/lib/lxc/overlay-clone.hook
# cat overlay-clone.hook
#!/bin/bash
touch $LXC_CONFIG_FILE.test
cat <<EOF>> $LXC_CONFIG_FILE
# hook for unprivileged overlayfs container
# the overlayfs will be mounted before starting container
lxc.hook.pre-start=/var/lib/lxc/mount_overlay.hook mount
lxc.hook.post-stop=/var/lib/lxc/mount_overlay.hook umount
EOF
# since the new overlay container starts as a normal container with
"dir" storage
# we have to change it:
sed -i -e 's|^lxc.rootfs.backend.*|lxc.rootfs.backend = dir|' -e
's|^lxc.rootfs = .*|lxc.rootfs = /var/lib/lxc/'$LXC_NAME'/rootfs|'
$LXC_CONFIG_FILE
# for unprivileged containers the directory have to be readable for non-root
chmod 755 /var/lib/lxc/$LXC_NAME
# cat mount_overlay.hook
#!/bin/bash
case $1 in
mount)
mount -t overlay overlay -o
lowerdir=/var/lib/lxc/stretch-overlay-unpriv/rootfs,upperdir=$LXC_ROOTFS_PATH/../delta0/,workdir=$LXC_ROOTFS_PATH/../olwork/
$LXC_ROOTFS_PATH
;;
umount)
umount $LXC_ROOTFS_PATH
;;
esac
And a new config after cloning a container with
lxc-copy -n stretch-overlay-unpriv -N overlay-u3 -s
looks:
# cat overlay-u3/config
# Common configuration
lxc.include = /usr/share/lxc/config/debian.common.conf
# Container specific configuration
lxc.tty = 4
lxc.arch = amd64
# network
lxc.network.type = veth
lxc.network.link = lxc-bridge-nat
# unpriv
# 296608
lxc.id_map = u 0 296608 65536
lxc.id_map = g 0 296608 65536
# clone hook for unprivileged overlayfs container
lxc.hook.clone = /var/lib/lxc/overlay-clone.hook
lxc.rootfs = /var/lib/lxc/overlay-u3/rootfs
lxc.rootfs.backend = dir
lxc.utsname = overlay-u3
# hook for unprivileged overlayfs container
# the overlayfs will be mounted before starting container
lxc.hook.pre-start=/var/lib/lxc/mount_overlay.hook mount
lxc.hook.post-stop=/var/lib/lxc/mount_overlay.hook umount
Best Regards
Jan
More information about the lxc-users
mailing list