From af95999762c1fb872114efdd796c8f4a8e2d7260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Fri, 21 Jun 2024 17:57:27 +0200 Subject: [PATCH 1/6] Set power button to power off --- .../includes.chroot/etc/dconf/db/local.d/00-power-button | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 os/layers/participant/includes.chroot/etc/dconf/db/local.d/00-power-button diff --git a/os/layers/participant/includes.chroot/etc/dconf/db/local.d/00-power-button b/os/layers/participant/includes.chroot/etc/dconf/db/local.d/00-power-button new file mode 100644 index 0000000..e9eefc3 --- /dev/null +++ b/os/layers/participant/includes.chroot/etc/dconf/db/local.d/00-power-button @@ -0,0 +1,5 @@ +# When power button is pressed, show power off dialog. +# The default action is suspend, but laptops can be suspended by closing the +# lid, so it's more useful if the power button does power off. +[org/gnome/settings-daemon/plugins/power] +power-button-action = 'interactive' From 6419fa917eee978c299f0bce948ffb9480643b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Fri, 21 Jun 2024 18:16:12 +0200 Subject: [PATCH 2/6] Insert distribution into packages sources --- os/build.py | 3 +++ .../usr/local/share/target-sources/debian.sources | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/os/build.py b/os/build.py index 8bae320..c84070d 100755 --- a/os/build.py +++ b/os/build.py @@ -165,6 +165,9 @@ def main(): # so we need to copy them somewhere else and restore them after the install. for listpath in pathlib.Path('config/archives').glob('*.list.chroot'): run(["cp", str(listpath), f"config/includes.chroot/usr/local/share/target-sources/{listpath.name.removesuffix('.chroot')}"]) + # Insert distribution into source configs. + for sourcepath in pathlib.Path('config/includes.chroot/usr/local/share/target-sources').glob('*'): + edit_file(sourcepath, lambda s: s.replace("@DISTRIBUTION@", DISTRIBUTION)) elif args.variant == "contestant": # Insert root password into hook script. edit_file("config/hooks/live/2010-contestant.hook.chroot", diff --git a/os/layers/training-installer/includes.chroot/usr/local/share/target-sources/debian.sources b/os/layers/training-installer/includes.chroot/usr/local/share/target-sources/debian.sources index a7c1e88..fd89bcb 100644 --- a/os/layers/training-installer/includes.chroot/usr/local/share/target-sources/debian.sources +++ b/os/layers/training-installer/includes.chroot/usr/local/share/target-sources/debian.sources @@ -1,11 +1,11 @@ Types: deb deb-src URIs: http://deb.debian.org/debian -Suites: bookworm bookworm-updates +Suites: @DISTRIBUTION@ @DISTRIBUTION@-updates Components: main contrib non-free non-free-firmware Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg Types: deb deb-src URIs: http://deb.debian.org/debian-security -Suites: bookworm-security +Suites: @DISTRIBUTION@-security Components: main contrib non-free non-free-firmware Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg From 697bbc3618f1f7af6335403078678b38d6af4ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Fri, 21 Jun 2024 21:16:16 +0200 Subject: [PATCH 3/6] Add netcat --- .../package-lists/training-installer.list.chroot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/os/layers/training-installer/package-lists/training-installer.list.chroot b/os/layers/training-installer/package-lists/training-installer.list.chroot index cd8d058..9049ab7 100644 --- a/os/layers/training-installer/package-lists/training-installer.list.chroot +++ b/os/layers/training-installer/package-lists/training-installer.list.chroot @@ -14,3 +14,6 @@ gnome-boxes qemu-system-x86 qemu-utils libvirt-daemon-system # Run virtual machines with VirtualBox virtualbox-qt + +# Utilities +netcat-openbsd From ecdc506a1a40e431e2f357d404f9bff78ff57815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Sat, 22 Jun 2024 12:01:46 +0200 Subject: [PATCH 4/6] Add a boot menu item for resetting SOI user --- .../live/2010-training-installer.hook.chroot | 3 ++ .../includes.chroot/etc/grub.d/15_reset_user | 40 +++++++++++++++++++ .../etc/systemd/system/reset-user.service | 14 +++++++ .../usr/local/bin/install-config | 9 +---- .../includes.chroot/usr/local/bin/reset-user | 21 ++++++++++ os/readme.md | 1 + 6 files changed, 80 insertions(+), 8 deletions(-) create mode 100755 os/layers/training-installer/includes.chroot/etc/grub.d/15_reset_user create mode 100644 os/layers/training-installer/includes.chroot/etc/systemd/system/reset-user.service create mode 100755 os/layers/training-installer/includes.chroot/usr/local/bin/reset-user diff --git a/os/layers/training-installer/hooks/live/2010-training-installer.hook.chroot b/os/layers/training-installer/hooks/live/2010-training-installer.hook.chroot index c98afce..1c3b713 100644 --- a/os/layers/training-installer/hooks/live/2010-training-installer.hook.chroot +++ b/os/layers/training-installer/hooks/live/2010-training-installer.hook.chroot @@ -5,3 +5,6 @@ set -eu # Install the noauth PAM profile. groupadd noauth pam-auth-update --enable noauth + +# Enable user reset at boot triggered by a kernel parameter. +systemctl enable reset-user.service diff --git a/os/layers/training-installer/includes.chroot/etc/grub.d/15_reset_user b/os/layers/training-installer/includes.chroot/etc/grub.d/15_reset_user new file mode 100755 index 0000000..f4187ac --- /dev/null +++ b/os/layers/training-installer/includes.chroot/etc/grub.d/15_reset_user @@ -0,0 +1,40 @@ +#!/bin/sh +set -e + +. "$pkgdatadir/grub-mkconfig_lib" + +list= +for i in /boot/vmlinuz-* ; do + if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi +done +linux="$(version_find_latest $list)" +basename="$(basename $linux)" +rel_dirname="$(make_system_path_relative_to_its_root /boot)" +version="$(echo $basename | sed -e "s,^[^0-9]*-,,g")" + +prepare_boot="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab | grub_add_tab)" +LINUX_ROOT_DEVICE="UUID=${GRUB_DEVICE_UUID}" + +linux_entry () +{ + title="$1" + args="$2" + + echo " menuentry '$(echo "$title" | grub_quote)' {" + echo " load_video" + echo " insmod gzio" + echo "$prepare_boot" + echo " echo '$(echo "Loading Linux ${version} ..." | grub_quote)'" + echo " linux ${rel_dirname}/${basename} root=${LINUX_ROOT_DEVICE} ro ${args}" + echo " echo 'Loading initial ramdisk ...'" + echo " initrd ${rel_dirname}/initrd.img-${version}" + echo " }" +} + +echo "submenu 'Reset SOI user...' {" +echo " menuentry 'Cancel' {" +echo " configfile \$prefix/grub.cfg" +echo " }" +linux_entry "Reset SOI user (THIS DELETES USER DATA)" "reset-user" +linux_entry "Reset SOI user (THIS DELETES USER DATA) and power off" "reset-user reset-user-poweroff" +echo "}" diff --git a/os/layers/training-installer/includes.chroot/etc/systemd/system/reset-user.service b/os/layers/training-installer/includes.chroot/etc/systemd/system/reset-user.service new file mode 100644 index 0000000..1120578 --- /dev/null +++ b/os/layers/training-installer/includes.chroot/etc/systemd/system/reset-user.service @@ -0,0 +1,14 @@ +[Unit] +Description=Reset user at boot by setting a kernel parameter. +Before=basic.target +After=local-fs.target systemd-tmpfiles-setup.service +DefaultDependencies=no +ConditionKernelCommandLine=reset-user + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/bin/reset-user + +[Install] +WantedBy=basic.target diff --git a/os/layers/training-installer/includes.chroot/usr/local/bin/install-config b/os/layers/training-installer/includes.chroot/usr/local/bin/install-config index 39bfad6..cc74761 100755 --- a/os/layers/training-installer/includes.chroot/usr/local/bin/install-config +++ b/os/layers/training-installer/includes.chroot/usr/local/bin/install-config @@ -6,12 +6,5 @@ set -eu cp -rT /usr/local/share/target-sources /etc/apt/sources.list.d rm /etc/apt/sources.list -USERNAME=soi -USER_FULLNAME="SOI" -# Password: soi -USER_PASSWORD='$y$j9T$h5VhMd4KkdmbxdZD1gO0N/$1hvwZgO8pQw13Xd6jaNXbtkbqVOC4W/ia/KXOcCGYvB' - # Create user. -adduser --disabled-password --gecos "$USER_FULLNAME" "$USERNAME" -usermod -p "$USER_PASSWORD" "$USERNAME" -adduser "$USERNAME" noauth +/usr/local/bin/reset-user diff --git a/os/layers/training-installer/includes.chroot/usr/local/bin/reset-user b/os/layers/training-installer/includes.chroot/usr/local/bin/reset-user new file mode 100755 index 0000000..44497eb --- /dev/null +++ b/os/layers/training-installer/includes.chroot/usr/local/bin/reset-user @@ -0,0 +1,21 @@ +#!/bin/sh + +set -eu + +USERNAME=soi +USER_FULLNAME="SOI" +# Password: soi +USER_PASSWORD='$y$j9T$h5VhMd4KkdmbxdZD1gO0N/$1hvwZgO8pQw13Xd6jaNXbtkbqVOC4W/ia/KXOcCGYvB' + +# Delete user. +userdel --remove "$USERNAME" || true + +# Create user. +adduser --disabled-password --gecos "$USER_FULLNAME" "$USERNAME" +usermod -p "$USER_PASSWORD" "$USERNAME" +adduser "$USERNAME" noauth + +# If the corresponding boot menu item was selected, immediately power off. +if grep --quiet --word-regexp reset-user-poweroff /proc/cmdline; then + systemctl start poweroff.target --job-mode=replace-irreversibly --no-block +fi diff --git a/os/readme.md b/os/readme.md index 9fc0411..508cab8 100644 --- a/os/readme.md +++ b/os/readme.md @@ -107,6 +107,7 @@ Here is a list of features. - login without password for `noauth` group - create an admin user with sudo rights and password - create a participant user without password + - add a boot menu item for resetting participant user data - install packages for firmware updates and power manager - install Gnome Boxes and VirtualBox for running virtual machines - `contestant` From 3f14ff63be1808cb54c49e0f5a60c0aed7d6165f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Sat, 22 Jun 2024 15:26:29 +0200 Subject: [PATCH 5/6] Create custom boot entries in installer --- .../usr/local/bin/install-config | 54 +++++++++++++++++++ .../includes.installer/preseed.cfg | 1 + .../training-installer.list.chroot | 3 ++ 3 files changed, 58 insertions(+) diff --git a/os/layers/training-installer/includes.chroot/usr/local/bin/install-config b/os/layers/training-installer/includes.chroot/usr/local/bin/install-config index cc74761..98d687e 100755 --- a/os/layers/training-installer/includes.chroot/usr/local/bin/install-config +++ b/os/layers/training-installer/includes.chroot/usr/local/bin/install-config @@ -2,6 +2,60 @@ set -eu +# We preseed grub-installer/update-nvram to disable creation of +# EFI boot entries by grub and instead do it ourselves here. +# +# The main reason why we do this is that with the grub-created boot entry, +# Dell Latitude 7480 laptops no longer boot Debian from internal disk after +# having booted from USB stick. This apparently happens because, when a bootable +# USB stick is inserted, the firmware can no longer find the debian EFI file +# (it's probably looking at the wrong EFI partition, the one on the USB stick), +# and then enters boot option recovery, which finds the BOOTx64.EFI on the USB +# stick, and then creates a boot entry for that and sets the bootorder to just +# that new entry. After that, the debian boot entry is no longer in the +# bootorder, so booting fails after removing the USB stick. +# Additionally, it is convenient if laptops boot from USB stick automatically, +# without needing to enter the boot menu. +# +# To solve these problems, we create a boot entry for USB sticks, which is tried +# first, and one for Debian on the internal disk. +# We create path-only boot entries, which apparently work more reliably than +# entries which also specify the disk. +# We use hardcoded entry numbers to avoid needing to find available numbers and +# clean up old entries. + +# Try mounting efivarfs +mountvirtfs () { + fstype="$1" + path="$2" + mkdir -p "$path" + if mount -t "$fstype" "$fstype" "$path"; then + trap "umount $path" HUP INT QUIT KILL PIPE TERM EXIT + fi +} +mountvirtfs efivarfs /sys/firmware/efi/efivars + +# Check if EFI boot is available +if efibootmgr --quiet; then + efibootmgr --delete-bootorder || true + efibootmgr --bootnum 0150 --delete-bootnum || true + efibootmgr --bootnum 0151 --delete-bootnum || true + + # efibootmgr --create-only --bootnum 0150 --label "Removable media" --file-dev-path --loader '\EFI\BOOT\BOOTx64.EFI' + # efibootmgr --create-only --bootnum 0151 --label "Debian" --file-dev-path --loader '\EFI\debian\shimx64.efi' + + # The version of efibootmgr in bookworm does not support the --file-dev-path + # argument, so here are commands that directly write to efivarfs. + # When upgrading from bookworm to trixie, remove the commands below and + # uncomment the commands above. + echo "BwAAAAEAAAA0AFIAZQBtAG8AdgBhAGIAbABlACAAbQBlAGQAaQBhAAAABAQwAFwARQBGAEkAXABCAE8ATwBUAFwAQgBPAE8AVAB4ADYANAAuAEUARgBJAAAAf/8EAA==" | \ + base64 --decode - > /sys/firmware/efi/efivars/Boot0150-8be4df61-93ca-11d2-aa0d-00e098032b8c + echo "BwAAAAEAAAA4AEQAZQBiAGkAYQBuAAAABAQ0AFwARQBGAEkAXABkAGUAYgBpAGEAbgBcAHMAaABpAG0AeAA2ADQALgBlAGYAaQAAAH//BAA=" | \ + base64 --decode - > /sys/firmware/efi/efivars/Boot0151-8be4df61-93ca-11d2-aa0d-00e098032b8c + + efibootmgr --bootorder 0150,0151 +fi + # Set up apt lists. cp -rT /usr/local/share/target-sources /etc/apt/sources.list.d rm /etc/apt/sources.list diff --git a/os/layers/training-installer/includes.installer/preseed.cfg b/os/layers/training-installer/includes.installer/preseed.cfg index d21fb29..c0f2bd8 100644 --- a/os/layers/training-installer/includes.installer/preseed.cfg +++ b/os/layers/training-installer/includes.installer/preseed.cfg @@ -24,5 +24,6 @@ d-i partman/choose_partition select finish d-i apt-setup/use_mirror boolean false d-i grub-installer/only_debian boolean true +d-i grub-installer/update-nvram boolean false d-i preseed/late_command string in-target /usr/local/bin/install-config diff --git a/os/layers/training-installer/package-lists/training-installer.list.chroot b/os/layers/training-installer/package-lists/training-installer.list.chroot index 9049ab7..19897e0 100644 --- a/os/layers/training-installer/package-lists/training-installer.list.chroot +++ b/os/layers/training-installer/package-lists/training-installer.list.chroot @@ -3,6 +3,9 @@ sudo # Make Secure Boot work grub-efi-amd64-signed +# Tool for setting EFI boot variables during install +efibootmgr + # Firmware updates through gnome-software fwupd fwupd-signed From 7768d84c5632309c402d824beda428dc1d49eb2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Sat, 22 Jun 2024 15:46:40 +0200 Subject: [PATCH 6/6] Set power button also for gdm --- .../includes.chroot/etc/dconf/db/gdm.d/00-power-button | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 os/layers/training-installer/includes.chroot/etc/dconf/db/gdm.d/00-power-button diff --git a/os/layers/training-installer/includes.chroot/etc/dconf/db/gdm.d/00-power-button b/os/layers/training-installer/includes.chroot/etc/dconf/db/gdm.d/00-power-button new file mode 100644 index 0000000..e9eefc3 --- /dev/null +++ b/os/layers/training-installer/includes.chroot/etc/dconf/db/gdm.d/00-power-button @@ -0,0 +1,5 @@ +# When power button is pressed, show power off dialog. +# The default action is suspend, but laptops can be suspended by closing the +# lid, so it's more useful if the power button does power off. +[org/gnome/settings-daemon/plugins/power] +power-button-action = 'interactive'