#!/bin/bash set -Eeuo pipefail # disable command path hashing as we are going to move fast and break things set +h # config WORKDIR="/tmp/menhera" MIRROR="https://iso-ultralite.meson.cc/archlinux" ROOTFS="${MIRROR}/iso/latest/arch/x86_64/airootfs.sfs" declare -A ARCH_MAP=( ["x86_64"]="amd64" ) # internal global variables OLDROOT="/" NEWROOT="" MACHINE_TYPE=$(uname -m) ARCH_ID=${ARCH_MAP[$MACHINE_TYPE]:-$MACHINE_TYPE} # fix possible PATH problems export PATH="$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" menhera::reset_sshd_config() { cat > /etc/ssh/sshd_config <&2 exit 1 fi } menhera::__compat_reload_init() { if [ -x "$(command -v systemctl)" ]; then systemctl daemon-reexec elif [ -x "$(command -v telinit)" ]; then telinit u else echo "ERROR: Cannot re-exec init, init system not recognized" >&2 exit 1 fi } # helper functions # https://stackoverflow.com/a/3232082/2646069 menhera::confirm() { # call with a prompt string or use a default read -r -p "${1:-Are you sure? [y/N]} " response case "$response" in [yY][eE][sS]|[yY]) true ;; *) false ;; esac } # jobs menhera::get_rootfs() { if [ -z "${ROOTFS}" ]; then echo "Getting rootfs URL..." # forgive me for parsing HTML with these shit # and hope it works ROOTFS_TIME=$(wget -qO- --show-progress "https://images.linuxcontainers.org/images/debian/buster/${ARCH_ID}/default/?C=M;O=D" | grep -oP '(\d{8}_\d{2}:\d{2})' | head -n 1) ROOTFS="https://images.linuxcontainers.org/images/debian/buster/${ARCH_ID}/default/${ROOTFS_TIME}/rootfs.squashfs" else echo "\$ROOTFS is set to '$ROOTFS'" fi } menhera::sync_filesystem() { echo "Syncing..." sync sync } menhera::prepare_environment() { echo "Loading kernel modules..." modprobe overlay modprobe squashfs sysctl kernel.panic=10 echo "Creating workspace in '${WORKDIR}'..." # workspace mkdir -p "${WORKDIR}" mount -t tmpfs -o size=100% tmpfs "${WORKDIR}" # new rootfs mkdir -p "${WORKDIR}/newroot" # readonly part of new rootfs mkdir -p "${WORKDIR}/newrootro" # writeable part of new rootfs mkdir -p "${WORKDIR}/newrootrw" # overlayfs workdir mkdir -p "${WORKDIR}/overlayfs_workdir" echo "Downloading temporary rootfs..." wget -q --show-progress -O "${WORKDIR}/rootfs.squashfs" "${ROOTFS}" } menhera::mount_new_rootfs() { echo "Mounting temporary rootfs..." mount -t squashfs "${WORKDIR}/rootfs.squashfs" "${WORKDIR}/newrootro" mount -t overlay overlay -o rw,lowerdir="${WORKDIR}/newrootro",upperdir="${WORKDIR}/newrootrw",workdir="${WORKDIR}/overlayfs_workdir" "${WORKDIR}/newroot" NEWROOT="${WORKDIR}/newroot" } menhera::install_software() { return echo "Installing OpenSSH Server into new rootfs..." # disable APT cache echo -e 'Dir::Cache "";\nDir::Cache::archives "";' > "${NEWROOT}/etc/apt/apt.conf.d/00_disable-cache-directories" DEBIAN_FRONTEND=noninteractive chroot "${NEWROOT}" apt-get update -y DEBIAN_FRONTEND=noninteractive chroot "${NEWROOT}" apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install -y openssh-server } menhera::copy_config() { echo "Copying important config into new rootfs..." ! cp -axL "${OLDROOT}/etc/resolv.conf" "${NEWROOT}/etc" ! cp -axr "${OLDROOT}/etc/ssh" "${NEWROOT}/etc" ! cp -ax "${OLDROOT}/etc/"{passwd,shadow} "${NEWROOT}/etc" ! cp -axr "${OLDROOT}/root/.ssh" "${NEWROOT}/root" chroot "${NEWROOT}" chsh -s /bin/bash root cat > "${NEWROOT}/etc/motd" <