]> git.sommitrealweird.co.uk Git - lxc-debian-unprivileged.git/blob - templates/lxc-debian-unprivileged
33116094095730ce833184ab5e0aecf443853e68
[lxc-debian-unprivileged.git] / templates / lxc-debian-unprivileged
1 #!/bin/bash
2
3 # lxc template for debootstrapping in userns
4
5 # Authors:
6 # Brett Parker <iDunno@sommitrealweird.co.uk>
7
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
12
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 # Lesser General Public License for more details.
17
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22 MAPPED=no
23
24 # Only support usage in userns.
25 for arg in "$@"; do
26     [ "$arg" = "--" ] && break
27     if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
28         MAPPED=yes
29     fi
30 done
31
32 if [ "$MAPPED" == "no" ]; then
33     echo "This template can only be used for unprivileged containers." 1>&2
34     echo "You might want the \"debian\" template instead." 1|&2
35 fi
36
37 # Make sure the usual locations are in PATH
38 export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
39 export GREP_OPTIONS=""
40
41 usage() {
42     cat <<EOF
43 LXC debootstrap in user namespace for unprivileged containers
44
45 Special arguments:
46 [ -h | --help ]: Print this help message and exit.
47
48 Required arguments:
49 [ -r | --release <release> ]: The debian release, e.g. jessie or stretch.
50
51 Optional arguments:
52 [ -m | --mirror <mirrorurl> ]: The debian mirror to user
53 EOF
54     return 0
55 }
56
57 options=$(getopt -o r:m:h -l release:,mirror:,help,mapped-uid:,mapped-gid:,name:,path:,rootfs: -- "$@")
58
59 if [ $? -ne 0 ]; then
60     usage
61     exit 1
62 fi
63
64 eval set -- "$options"
65
66 DEBIAN_MIRROR="http://mirror.mythic-beasts.com/debian/"
67 DEBIAN_RELEASE="jessie"
68
69 while :; do
70     case "$1" in
71         -h|--help)      usage && exit 1;;
72         -r|--release)   DEBIAN_RELEASE=$2; shift 2;;
73         -m|--mirror)    DEBIAN_MIRROR=$2; shift 2;;
74         --mapped-uid)   MAPPED_UID=$2; shift 2;;
75         --mapped-gid)   MAPPED_GID=$2; shift 2;;
76         --name)         LXC_NAME=$2; shift 2;;
77         --path)         LXC_PATH=$2; shift 2;;
78         --rootfs)       LXC_ROOTFS=$2; shift 2;;
79         *)              break;;
80     esac
81 done
82
83 echo "Mapped UID: $MAPPED_UID"
84 echo "Mapped GID: $MAPPED_GID"
85 echo "RootFS: $LXC_ROOTFS"
86 echo "Name: $LXC_NAME"
87 echo "Path: $LXC_PATH"
88
89 # rewrite the default config file
90
91 sed -i -e "/lxc./{w ${LXC_PATH}/config-auto" -e "d}" ${LXC_PATH}/config
92 sed -i -e '4,$d' ${LXC_PATH}/config
93
94 cat <<EOF >> ${LXC_PATH}/config
95
96 # Useful includes
97 lxc.include = /usr/share/lxc/config/debian.common.conf
98 lxc.include = /usr/share/lxc/config/debian.userns.conf
99
100 # Set our hostname
101 lxc.utsname = $LXC_NAME
102
103 # Automatic configuration
104 EOF
105
106 # add back in the auto foo
107 cat "${LXC_PATH}/config-auto" >> ${LXC_PATH}/config
108 rm ${LXC_PATH}/config-auto
109
110 mkdir ${LXC_PATH}/bin
111 cat <<EOF > ${LXC_PATH}/bin/mknod
112 #!/bin/sh
113
114 exec touch "\$1"
115 EOF
116
117 chmod 755 ${LXC_PATH}/bin/mknod
118
119 export PATH=${LXC_PATH}/bin:$PATH
120
121 debootstrap --foreign --include debian-archive-keyring,ifupdown,isc-dhcp-client,locales,openssh-server $DEBIAN_RELEASE ${LXC_ROOTFS} $DEBIAN_MIRROR
122
123 # now totally skip that check in the new root, because it sucks.
124 sed -i -e 's#check_sane_mount () {#check_sane_mount () {\n\treturn 0#;' ${LXC_ROOTFS}/debootstrap/functions
125
126 # and stop it from bothering to try to setup proc
127 sed -i -e 's#setup_proc () {#setup_proc () {\n\treturn 0#;' ${LXC_ROOTFS}/debootstrap/functions
128
129 keyring_dpkg=$(sed -ne "/^debian-archive-keyring/ { s#.* ##; p; }" ${LXC_ROOTFS}/debootstrap/debpaths)
130 # and unpack debian-archive-keyring, because we'll need that
131 (cd ${LXC_ROOTFS} && dpkg-deb -x .$keyring_dpkg .)
132
133 # replace the tar containing devices with something that doesn't contain any
134 (cd $LXC_ROOTFS/debootstrap && rm devices.tar.gz && tar czvf devices.tar.gz --files-from=/dev/null)
135
136 # and mount a shitload of things for fun and profit...
137 for file in /var/lib/lxcfs/proc/*; do
138     fname=$(basename $file)
139     touch ${LXC_ROOTFS}/proc/$fname
140     mount -n -o bind $file ${LXC_ROOTFS}/proc/$fname
141 done
142
143 for dev in random urandom; do
144     touch ${LXC_ROOTFS}/dev/$dev
145     mount -n -o bind /dev/$dev ${LXC_ROOTFS}/dev/$dev
146 done
147
148 # set /proc/cmdline to something silly
149 echo "debootstrapping - hahaha" > ${LXC_ROOTFS}/proc/cmdline
150
151 # and disable initscripts
152 cat <<EOF > ${LXC_ROOTFS}/usr/sbin/policy-rc.d
153 #!/bin/sh
154
155 exit 101
156 EOF
157
158 # and run the second stage
159 chroot ${LXC_ROOTFS} /debootstrap/debootstrap --second-stage
160
161 # configure locales
162 lang=en_GB.UTF-8
163 enc=UTF-8
164 if [ ! -z "$LANG" ]; then
165     lang=${LANG}
166     enc=${LANG#*.}
167 fi
168
169 cat >> ${LXC_ROOTFS}/etc/locale.gen <<EOF
170 $lang $enc
171 EOF
172
173 chroot ${LXC_ROOTFS} /usr/sbin/locale-gen $lang $enc
174 chroot ${LXC_ROOTFS} /usr/sbin/update-locale LANG=$LANG
175
176 # configure timezone
177 if [ -f /etc/timezone ]; then
178     cat /etc/timezone > ${LXC_ROOTFS}/etc/timezone
179 elif [ -f /etc/sysconfig/clock ]; then
180     . /etc/sysconfig/clock
181     echo $ZONE > ${LXC_ROOTFS}/etc/timezone
182 fi
183 chroot ${LXC_ROOTFS} dpkg-reconfigure -f noninteractive tzdata
184
185 # "setup" networking
186 NETWORK_FILE=/etc/network/interfaces
187 if [ -e ${LXC_ROOTFS}/etc/network/interfaces.d ]; then
188     NETWORK_FILE=/etc/network/interfaces.d/eth0
189 fi
190
191 # remove some interesting breakages in pam for unpriv foo
192 sed -i -e 's#^\(session.*required.*pam_loginuid.so\)#\#\1#;' ${LXC_ROOTFS}/etc/pam.d/*
193
194 # set the hostname
195 echo $LXC_NAME > ${LXC_ROOTFS}/etc/hostname
196
197 # setup sources.list
198 cat <<EOF > ${LXC_ROOTFS}/etc/apt/sources.list
199 deb $DEBIAN_MIRROR $DEBIAN_RELEASE main
200 deb http://security.debian.org/ $DEBIAN_RELEASE/updates main
201 EOF
202
203 # disable bits of systemd that we hates
204 chroot $LXC_ROOTFS /usr/sbin/update-rc.d -f checkroot.sh disable > /dev/null 2>&1
205 chroot $LXC_ROOTFS /usr/sbin/update-rc.d -f umountfs disable > /dev/null 2>&1
206 chroot $LXC_ROOTFS /usr/sbin/update-rc.d -f hwclock.sh disable > /dev/null 2>&1
207 chroot $LXC_ROOTFS /usr/sbin/update-rc.d -f hwclockfirst.sh disable > /dev/null 2>&1
208
209 if [ -e ${LXC_ROOTFS}/etc/systemd/system/ ]; then
210     touch ${LXC_ROOTFS}/etc/systemd/system/systemd-setup-dgram-qlen.service
211     touch ${LXC_ROOTFS}/etc/systemd/system/dev-hugepages.mount
212     touch ${LXC_ROOTFS}/etc/systemd/system/udev.service
213     touch ${LXC_ROOTFS}/etc/systemd/system/systemd-udevd.service
214     chroot ${LXC_ROOTFS} systemctl set-default multi-user.target
215     chroot ${LXC_ROOTFS} ln -s /lib/systemd/system/halt.target /etc/systemd/system/sigpwr.target
216 fi
217
218 cat <<EOF >> ${LXC_ROOTFS}${NETWORK_FILE}
219 auto eth0
220 iface eth0 inet dhcp
221 EOF
222
223 # and update to the latest security
224 chroot ${LXC_ROOTFS} apt-get update
225 chroot ${LXC_ROOTFS} apt-get -y upgrade
226
227 # if we're all good here, unmount things and clean up
228 [ -e ${LXC_ROOTFS}/usr/sbin/policy-rc.d ] && rm ${LXC_ROOTFS}/usr/sbin/policy-rc.d
229 rm ${LXC_ROOTFS}/proc/cmdline
230
231 for dev in random urandom; do
232     umount ${LXC_ROOTFS}/dev/$dev
233     rm ${LXC_ROOTFS}/dev/$dev
234 done
235
236 for file in /var/lib/lxcfs/proc/*; do
237     fname=$(basename $file)
238     umount ${LXC_ROOTFS}/proc/$fname
239     rm ${LXC_ROOTFS}/proc/$fname
240 done
241
242 exit 0