From: Brett Parker Date: Sat, 21 May 2016 22:04:49 +0000 (+0100) Subject: First draft (ish) X-Git-Url: https://git.sommitrealweird.co.uk/lxc-debian-unprivileged.git/commitdiff_plain/0b6c3fd3611a11798ccdbc2f2e39f38132bc67d4?ds=sidebyside First draft (ish) --- 0b6c3fd3611a11798ccdbc2f2e39f38132bc67d4 diff --git a/templates/lxc-debian-unprivileged b/templates/lxc-debian-unprivileged new file mode 100755 index 0000000..30d4912 --- /dev/null +++ b/templates/lxc-debian-unprivileged @@ -0,0 +1,236 @@ +#!/bin/bash + +# lxc template for debootstrapping in userns + +# Authors: +# Brett Parker + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +MAPPED=no + +# Only support usage in userns. +for arg in "$@"; do + [ "$arg" = "--" ] && break + if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then + MAPPED=yes + fi +done + +if [ "$MAPPED" == "no" ]; then + echo "This template can only be used for unprivileged containers." 1>&2 + echo "You might want the \"debian\" template instead." 1|&2 +fi + +# Make sure the usual locations are in PATH +export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin +export GREP_OPTIONS="" + +usage() { + cat < ]: The debian release, e.g. jessie or stretch. + +Optional arguments: +[ -m | --mirror ]: The debian mirror to user +EOF + return 0 +} + +options=$(getopt -o r:m:h -l release:,mirror:,help,mapped-uid:,mapped-gid:,name:,path:,rootfs: -- "$@") + +if [ $? -ne 0 ]; then + usage + exit 1 +fi + +eval set -- "$options" + +DEBIAN_MIRROR="http://mirror.mythic-beasts.com/debian/" +DEBIAN_RELEASE="jessie" + +while :; do + case "$1" in + -h|--help) usage && exit 1;; + -r|--release) DEBIAN_RELEASE=$2; shift 2;; + -m|--mirror) DEBIAN_MIRROR=$2; shift 2;; + --mapped-uid) MAPPED_UID=$2; shift 2;; + --mapped-gid) MAPPED_GID=$2; shift 2;; + --name) LXC_NAME=$2; shift 2;; + --path) LXC_PATH=$2; shift 2;; + --rootfs) LXC_ROOTFS=$2; shift 2;; + *) break;; + esac +done + +echo "Mapped UID: $MAPPED_UID" +echo "Mapped GID: $MAPPED_GID" +echo "RootFS: $LXC_ROOTFS" +echo "Name: $LXC_NAME" +echo "Path: $LXC_PATH" + +# rewrite the default config file + +sed -i -e "/lxc./{w ${LXC_PATH}/config-auto" -e "d}" ${LXC_PATH}/config +sed -i -e '4,$d' ${LXC_PATH}/config + +cat <> ${LXC_PATH}/config + +# Useful includes +lxc.include = /usr/share/lxc/config/debian.common.conf +lxc.include = /usr/share/lxc/config/debian.userns.conf + +# Set our hostname +lxc.utsname = $LXC_NAME + +# Automatic configuration +EOF + +# add back in the auto foo +cat "${LXC_PATH}/config-auto" >> ${LXC_PATH}/config +rm ${LXC_PATH}/config-auto + +mkdir ${LXC_PATH}/bin +cat < ${LXC_PATH}/bin/mknod +#!/bin/sh + +exec touch "\$1" +EOF + +chmod 755 ${LXC_PATH}/bin/mknod + +export PATH=${LXC_PATH}/bin:$PATH + +debootstrap --foreign --include debian-archive-keyring,ifupdown,isc-dhcp-client,locales $DEBIAN_RELEASE ${LXC_ROOTFS} $DEBIAN_MIRROR + +# now totally skip that check in the new root, because it sucks. +sed -i -e 's#check_sane_mount () {#check_sane_mount () {\n\treturn 0#;' ${LXC_ROOTFS}/debootstrap/functions + +# and stop it from bothering to try to setup proc +sed -i -e 's#setup_proc () {#setup_proc () {\n\treturn 0#;' ${LXC_ROOTFS}/debootstrap/functions + +keyring_dpkg=$(sed -ne "/^debian-archive-keyring/ { s#.* ##; p; }" ${LXC_ROOTFS}/debootstrap/debpaths) +# and unpack debian-archive-keyring, because we'll need that +(cd ${LXC_ROOTFS} && dpkg-deb -x .$keyring_dpkg .) + +# replace the tar containing devices with something that doesn't contain any +(cd $LXC_ROOTFS/debootstrap && rm devices.tar.gz && tar czvf devices.tar.gz --files-from=/dev/null) + +# and mount a shitload of things for fun and profit... +for file in /var/lib/lxcfs/proc/*; do + fname=$(basename $file) + touch ${LXC_ROOTFS}/proc/$fname + mount -n -o bind $file ${LXC_ROOTFS}/proc/$fname +done + +for dev in random urandom; do + touch ${LXC_ROOTFS}/dev/$dev + mount -n -o bind /dev/$dev ${LXC_ROOTFS}/dev/$dev +done + +# set /proc/cmdline to something silly +echo "debootstrapping - hahaha" > ${LXC_ROOTFS}/proc/cmdline + +# and disable initscripts +cat < ${LXC_ROOTFS}/usr/sbin/policy-rc.d +#!/bin/sh + +exit 101 +EOF + +# and run the second stage +chroot ${LXC_ROOTFS} /debootstrap/debootstrap --second-stage + +# configure locales +lang=en_GB.UTF-8 +enc=UTF-8 +if [ ! -z "$LANG" ]; then + lang=${LANG} + enc=${LANG#*.} +fi + +cat >> ${LXC_ROOTFS}/etc/locale.gen < ${LXC_ROOTFS}/etc/timezone +elif [ -f /etc/sysconfig/clock ]; then + . /etc/sysconfig/clock + echo $ZONE > ${LXC_ROOTFS}/etc/timezone +fi +chroot ${LXC_ROOTFS} dpkg-reconfigure -f noninteractive tzdata + +# "setup" networking +NETWORK_FILE=/etc/network/interfaces +if [ -e ${LXC_ROOTFS}/etc/network/interfaces.d ]; then + NETWORK_FILE=/etc/network/interfaces.d/eth0 +fi + +# setup sources.list +cat < ${LXC_ROOTFS}/etc/apt/sources.list +deb $DEBIAN_MIRROR $DEBIAN_RELEASE main +deb http://security.debian.org/ $DEBIAN_RELEASE/update main +EOF + +# disable bits of systemd that we hates +chroot $LXC_ROOTFS /usr/sbin/update-rc.d -f checkroot.sh disable > /dev/null 2>&1 +chroot $LXC_ROOTFS /usr/sbin/update-rc.d -f umountfs disable > /dev/null 2>&1 +chroot $LXC_ROOTFS /usr/sbin/update-rc.d -f hwclock.sh disable > /dev/null 2>&1 +chroot $LXC_ROOTFS /usr/sbin/update-rc.d -f hwclockfirst.sh disable > /dev/null 2>&1 + +if [ -e ${LXC_ROOTFS}/etc/systemd/system/ ]; then + touch ${LXC_ROOTFS}/etc/systemd/system/systemd-setup-dgram-qlen.service + touch ${LXC_ROOTFS}/etc/systemd/system/dev-hugepages.mount + touch ${LXC_ROOTFS}/etc/systemd/system/udev.service + touch ${LXC_ROOTFS}/etc/systemd/system/systemd-udevd.service + chroot ${LXC_ROOTFS} systemctl set-default multi-user.target + chroot ${LXC_ROOTFS} ln -s /lib/systemd/system/halt.target /etc/systemd/system/sigpwr.target +fi + +cat <> ${LXC_ROOTFS}${NETWORK_FILE} +auto eth0 +iface eth0 inet dhcp +EOF + +# and update to the latest security +chroot ${LXC_ROOTFS} apt-get update +chroot ${LXC_ROOTFS} apt-get upgrade + +# if we're all good here, unmount things and clean up +[ -e ${LXC_ROOTFS}/usr/sbin/policy-rc.d ] && rm ${LXC_ROOTFS}/usr/sbin/policy-rc.d +rm ${LXC_ROOTFS}/proc/cmdline + +for dev in random urandom; do + umount ${LXC_ROOTFS}/dev/$dev + rm ${LXC_ROOTFS}/dev/$dev +done + +for file in /var/lib/lxcfs/proc/*; do + fname=$(basename $file) + umount ${LXC_ROOTFS}/proc/$fname + rm ${LXC_ROOTFS}/proc/$fname +done + +exit 0