Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@pmakholm
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmakholm/1358682fbfb575374ff1 to your computer and use it in GitHub Desktop.
Save pmakholm/1358682fbfb575374ff1 to your computer and use it in GitHub Desktop.
Unpriviledged LXC application container with bind mounted system
# Set up a new LXC container:
lxc-create -n sandbox -t $(pwd)/lxc-sandbox.template -f $(pwd)/lxc-sandbox.conf --dir $( mktemp -d -p $(pwd)/ lxc-XXXXXX )
# Run a single process in the container:
lxc-execute -n sandbox -q -- bash
lxc.network.type = empty
# These should match the settings in /etc/subuid and /etc/subgid
lxc.id_map = u 0 100000 65536
lxc.id_map = g 0 100000 65536
#!/bin/bash
# Make sure the usual locations are in PATH
export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
configure_rootfs()
{
rootfs=$1
for dir in etc home root var dev dev/shm proc sys ; do
mkdir $rootfs/$dir || return 1
done
cat <<EOF > $rootfs/etc/passwd
root:x:0:0:root:/root:/bin/bash
nobody:x:65534:65534:nogroup:/root:/bin/bash
EOF
cat <<EOF > $rootfs/etc/group
root:x:0:root
nogroup:x:65534:nobody
EOF
return 0
}
copy_configuration()
{
path=$1
rootfs=$2
name=$3
echo "lxc.rootfs = $rootfs" >> $path/config
grep -q "^lxc.id_map" $path/config 2>/dev/null >> $path/config
cat <<EOF >> $path/config
lxc.utsname = $name
lxc.pts = 1024
lxc.kmsg = 0
lxc.cap.drop = sys_module mac_admin mac_override sys_time
lxc.aa_allow_incomplete = 1
lxc.aa_profile = unconfined
lxc.mount.entry = /lib lib lib bind,remount,ro,create=dir 0 0
lxc.mount.entry = /lib64 lib64 lib64 bind,remount,ro,create=dir 0 0
lxc.mount.entry = /bin bin bin bind,remount,ro,create=dir 0 0
lxc.mount.entry = /usr usr usr bind,remount,ro,create=dir 0 0
lxc.mount.entry = /sbin sbin sbin bind,remount,ro,create=dir 0 0
lxc.mount.entry = /tmp tmp tmpfs rw,create=dir 0 0
lxc.mount.auto = proc sys cgroup
lxc.include = /usr/share/lxc/config/common.conf
lxc.include = /usr/share/lxc/config/userns.conf
EOF
grep -q "^lxc.network" $path/config 2>/dev/null >> $path/config
}
usage()
{
cat <<EOF
$1 -h|--help -p|--path=<path> [--rootfs=<path>]
EOF
return 0
}
options=$(getopt -o hp:n:S: -l help,rootfs:,path:,name:,mapped-uid,mapped-gid: -- "$@")
if [ $? -ne 0 ]; then
usage $(basename $0)
exit 1
fi
eval set -- "$options"
while true
do
case "$1" in
-h|--help) usage $0 && exit 0;;
-p|--path) path=$2; shift 2;;
--rootfs) rootfs=$2; shift 2;;
-n|--name) name=$2; shift 2;;
--mapped-uid) LXC_MAPPED_UID=$2; shift 2;;
--mapped-gid) LXC_MAPPED_GID=$2; shift 2;;
--) shift 1; break ;;
*) break ;;
esac
done
if [ -z "$path" ]; then
echo "'path' parameter is required"
exit 1
fi
# detect rootfs
config="$path/config"
if [ -z "$rootfs" ]; then
if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config)
else
rootfs=$path/rootfs
fi
fi
configure_rootfs $rootfs
if [ $? -ne 0 ]; then
echo "failed to install rootfs"
exit 1
fi
copy_configuration $path $rootfs $name
if [ $? -ne 0 ]; then
echo "failed to write configuration file"
exit 1
fi
if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then
chown -R $LXC_MAPPED_UID $LXC_PATH/config $LXC_PATH/fstab >/dev/null 2>&1 || true
fi
configure_rootfs $rootfs
if [ $? -ne 0 ]; then
echo "failed to install rootfs"
exit 1
fi
copy_configuration $path $rootfs $name
if [ $? -ne 0 ]; then
echo "failed to write configuration file"
exit 1
fi
if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then
chown -R $LXC_MAPPED_UID $LXC_PATH/config $LXC_PATH/fstab >/dev/null 2>&1 || true
fi
if [ -n "$LXC_MAPPED_GID" ] && [ "$LXC_MAPPED_GID" != "-1" ]; then
chgrp -R $LXC_MAPPED_GID $LXC_PATH/config $LXC_PATH/fstab >/dev/null 2>&1 || true
fi
chown 0:0 $rootfs
# This is both in /etc/subuid and /etc/subgid
pmakholm:100000:65536
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment