From 2da9d8c440cfb2097a05f6eb9edcc98bba6fca7d Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Thu, 21 Feb 2019 02:31:43 +0100 Subject: Add scripts to generate virtual images with Debian The script make-base downloads and installs Debian Buster in a backing image which is then used by make-arbiter and make-student to create derived images with specific configurations. --- kpov_judge/scripts/make-arbiter.sh | 95 ++++++++++++++++++++++++++++++++++++++ kpov_judge/scripts/make-base.sh | 51 ++++++++++++++++++++ kpov_judge/scripts/make-student.sh | 42 +++++++++++++++++ kpov_judge/scripts/preseed.cfg | 91 ++++++++++++++++++++++++++++++++++++ 4 files changed, 279 insertions(+) create mode 100755 kpov_judge/scripts/make-arbiter.sh create mode 100755 kpov_judge/scripts/make-base.sh create mode 100755 kpov_judge/scripts/make-student.sh create mode 100644 kpov_judge/scripts/preseed.cfg diff --git a/kpov_judge/scripts/make-arbiter.sh b/kpov_judge/scripts/make-arbiter.sh new file mode 100755 index 0000000..b08944c --- /dev/null +++ b/kpov_judge/scripts/make-arbiter.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +# Create the disk image for arbiter: a gateway with NAT, dnsmasq and +# sshd. The user account test / test is set up to run the test_task +# script for evaluating the given task. The account is also given sudo +# rights to reboot, poweroff, ifconfig, ip and mount. + +set -e + +if [ $# -lt 1 ]; then + echo "usage: ${0} base" + exit 1 +fi + +base="${1}" +name="arbiter" +format="qcow2" + +# WAN on first interface, LAN on second +file_interfaces=\ +'# see interfaces(5) +source /etc/network/interfaces.d/* + +# loopback interface +auto lo +iface lo inet loopback + +# first interface +allow-hotplug ens3 +iface ens3 inet dhcp +allow-hotplug enp0s3 +iface enp0s3 inet dhcp + +# second interface +allow-hotplug ens4 +iface ens4 inet static + address 10.94.94.1/24 +allow-hotplug enp0s8 +iface enp0s8 inet static + address 10.94.94.1/24 +' + +# NAT rules +file_nftables=\ +'table ip nat { + chain prerouting { + type nat hook prerouting priority 0; policy accept; + } + + chain postrouting { + type nat hook postrouting priority 100; policy accept; + oifname "ens3" masquerade + oifname "enp0s3" masquerade + } +} +' + +file_dnsmasq=\ +'interface=ens4 +interface=enp0s8 + +dhcp-range=10.94.94.16,10.94.94.250,12h +' + +file_sudoers=\ +'test ALL = /sbin/reboot +test ALL = /sbin/poweroff +test ALL = NOPASSWD: /bin/ip +test ALL = NOPASSWD: /bin/mount +test ALL = NOPASSWD: /sbin/ifconfig +' + +qemu-img create -f qcow2 -b "${base}" "${name}.${format}" + +virt-customize -a "${name}.${format}" \ + --hostname "${name}" \ + --update \ + --install fortune-mod,fortunes,fortunes-bofh-excuses,python3-pexpect,python3-paramiko,python3-snimpy,python3-yaml \ + --install dnsmasq \ + --install openssh-server \ + --run-command "apt clean" \ + --write /etc/network/interfaces:"${file_interfaces}" \ + --write /etc/nftables.conf:"${file_nftables}" \ + --write /etc/sysctl.d/gateway.conf:"net.ipv4.ip_forward = 1" \ + --run-command "systemctl enable nftables.service" \ + --write /etc/dnsmasq.d/kpov-gw:"${file_dnsmasq}" \ + --run-command "useradd -m -s /bin/bash -p '\$6\$VdV5y2gl\$YxpYuwcVZHSXiv0N4yzmF8PspBeIK8QLdGJZzYFuKRjkfc82DhaS5fQeuOt0q9APDPLeSMTzt8BtxI2Bwo/hH.' test" \ + --write /etc/sudoers.d/kpov-test:"${file_sudoers}" + +## make a sparse diff +#virt-sparsify "${name}.${format}" "${name}x.${format}" +#qemu-img create -f "${format}" -b "${name}x.${format}" "${name}-diff.${format}" +#qemu-img rebase -b "${base}" "${name}-diff.${format}" + +#rm -f "./${name}-install.${format}" diff --git a/kpov_judge/scripts/make-base.sh b/kpov_judge/scripts/make-base.sh new file mode 100755 index 0000000..970acac --- /dev/null +++ b/kpov_judge/scripts/make-base.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +# Create the base disk image: a minimal Debian install with a user +# account student / vaje. Root password is kaboom. Serial console is +# enabled for grub and boot messages are displayed. Some useful +# additional packages are installed, and the image is sparsified +# (requires at least 30 GB free space). + +set -e + +if [ $# -lt 1 ]; then + echo "usage: ${0} image-name" + exit 1 +fi + +name="${1}" +format=qcow2 + +outfile="${name}.${format}" +fatfile="${name}-fat.${format}" + +tmpdir="$(mktemp -d kpov-tmp.XXXXXX)" +trap 'rm -rf "${tmpdir}"' EXIT + +for f in linux initrd.gz; do + wget "https://d-i.debian.org/daily-images/i386/daily/netboot/debian-installer/i386/${f}" -O "${tmpdir}/${f}" +done + +qemu-img create -f "${format}" -o size=30G "${fatfile}" + +qemu-system-i386 \ + -enable-kvm \ + -nographic \ + -m 1G -smp 2 \ + -kernel "${tmpdir}/linux" -initrd "${tmpdir}/initrd.gz" \ + -append "console=ttyS0,115200n8 serial auto=true url=http://10.0.2.10:8080/preseed.cfg hostname=${name} domain=" \ + -net user,guestfwd=:10.0.2.10:8080-cmd:"/bin/busybox httpd -i" -net nic \ + -hda "${fatfile}" + +virt-customize -a "${fatfile}" \ + --update \ + --install virtualbox-guest-utils,virtualbox-guest-modules \ + --install nftables \ + --install git,nano,net-tools,rsync,sudo,tmux,vim \ + --run-command 'apt clean' \ + --edit /etc/default/grub:'s/^GRUB_CMDLINE_LINUX_DEFAULT=.*$/GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0"/' \ + --edit /etc/default/grub:'s/^GRUB_TERMINAL=.*$/GRUB_TERMINAL=\"console serial\"/' \ + --run-command update-grub + +virt-sparsify "${fatfile}" "${outfile}" +rm -f "${fatfile}" diff --git a/kpov_judge/scripts/make-student.sh b/kpov_judge/scripts/make-student.sh new file mode 100755 index 0000000..f072b47 --- /dev/null +++ b/kpov_judge/scripts/make-student.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# Create the disk image for a basic terminal computer with sshd. +# Typical virtual‐machine network interfaces are configured for DHCP. + +set -e + +if [ $# -lt 1 ]; then + echo "usage: ${0} base" + exit 1 +fi + +base="${1}" +name="student" +format="qcow2" + +file_interfaces=\ +'# see interfaces(5) +source /etc/network/interfaces.d/* + +# loopback interface +auto lo +iface lo inet loopback + +# first interface +allow-hotplug ens3 +iface ens3 inet dhcp +allow-hotplug enp0s3 +iface enp0s3 inet dhcp +' + +qemu-img create -f qcow2 -b "${base}" "${name}.${format}" + +virt-customize -a "${name}.${format}" \ + --hostname "${name}" \ + --update \ + --install openssh-server \ + --write /etc/network/interfaces:"${file_interfaces}" + +#virt-sparsify "${name}.${format}" "${name}x.${format}" +#qemu-img create -f "${format}" -b "${name}x.${format}" "${name}-diff.${format}" +#qemu-img rebase -b "${base}" "${name}-diff.${format}" diff --git a/kpov_judge/scripts/preseed.cfg b/kpov_judge/scripts/preseed.cfg new file mode 100644 index 0000000..7bf3c7a --- /dev/null +++ b/kpov_judge/scripts/preseed.cfg @@ -0,0 +1,91 @@ +d-i debian-installer/language string en +d-i debian-installer/country string SI +d-i debian-installer/locale string en_US.UTF-8 +d-i localechooser/supported-locales multiselect de_DE.UTF-8, es_ES.UTF-8, fr_FR.UTF-8, sl_SI.UTF-8 + +d-i keyboard-configuration/xkb-keymap select slovene +# d-i keyboard-configuration/toggle select No toggling + +d-i netcfg/choose_interface select auto + +# Any hostname and domain names assigned from dhcp take precedence over +# values set here. However, setting the values still prevents the questions +# from being shown, even if values come from dhcp. +d-i netcfg/get_hostname string unassigned-hostname +d-i netcfg/get_domain string unassigned-domain + +d-i netcfg/wireless_wep string + +# mirror settings +d-i mirror/country string manual +d-i mirror/http/hostname string ftp.si.debian.org +d-i mirror/http/directory string /debian +d-i mirror/http/proxy string + +d-i mirror/suite string buster + +# root password, either in clear text +d-i passwd/root-password password kaboom +d-i passwd/root-password-again password kaboom +# or encrypted using a crypt(3) hash. +#d-i passwd/root-password-crypted password [crypt(3) hash] + +d-i passwd/user-fullname string Študent KPOV +d-i passwd/username string student +# normal user's password, either in clear text +d-i passwd/user-password password vaje +d-i passwd/user-password-again password vaje +# or encrypted using a crypt(3) hash. +#d-i passwd/user-password-crypted password [crypt(3) hash] + +d-i passwd/user-default-groups string users audio cdrom video wheel + +d-i clock-setup/utc boolean true +d-i time/zone string Europe/Ljubljana +d-i clock-setup/ntp boolean true + +# Partitioning +# - regular: use the usual partition types for your architecture +# - lvm: use LVM to partition the disk +# - crypto: use LVM within an encrypted partition +d-i partman-auto/method string regular + +# - atomic: all files in one partition +# - home: separate /home partition +# - multi: separate /home, /var, and /tmp partitions +d-i partman-auto/choose_recipe select atomic + +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +# this makes partman automatically partition without confirmation. +d-i partman-md/confirm boolean true +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +# Base system installation +d-i base-installer/install-recommends boolean false +d-i apt-setup/contrib boolean true +d-i apt-setup/source boolean false + +tasksel tasksel/first multiselect standard +popularity-contest popularity-contest/participate boolean false + +# Individual additional packages to install +#d-i pkgsel/include string openssh-server build-essential nano python3 git tmux rsync vim + +d-i grub-installer/only_debian boolean true +d-i grub-installer/with_other_os boolean true + +# Due notably to potential USB sticks, the location of the MBR can not be +# determined safely in general, so this needs to be specified: +#d-i grub-installer/bootdev string /dev/sda +# To install to the first device (assuming it is not a USB stick): +d-i grub-installer/bootdev string default + +d-i finish-install/reboot_in_progress note +d-i debian-installer/exit/poweroff boolean true \ No newline at end of file -- cgit v1.2.1