From bf83715efb51bd56f8db6653d4208c867ea99f8e Mon Sep 17 00:00:00 2001
From: ping <dev@guillaumepin.ch>
Date: Sat, 11 Jan 2025 19:55:31 +0100
Subject: [PATCH] Adding ram only, shared func for init, ubuntu version as
 variable and secure boot

---
 live_exam_os/.env.example                     |   3 +-
 live_exam_os/Dockerfile                       |   2 +-
 live_exam_os/Makefile                         |   2 +-
 live_exam_os/README.md                        |   8 +-
 live_exam_os/build.sh                         | 172 ++++++++++--------
 live_exam_os/config/00-bootloader/grub.cfg    |   6 +
 .../config/00-bootloader/grub.efi.cfg         |   2 +
 live_exam_os/config/00-bootloader/limine.conf |   2 +-
 .../config/00-bootloader/limine_casper.conf   |   7 -
 .../config/00-bootloader/limine_pxe.conf      |   7 -
 .../config/01-packages_install/packages       |  10 +-
 .../NetworkManager/NetworkManager.conf.bak    |   8 -
 .../conf.d/10-default-wired.conf.bak          |  10 -
 .../etc/NetworkManager/conf.d/dns.conf.bak    |   2 -
 .../config/02-customisation/etc/challenge     |   1 -
 .../02-customisation/etc/default/keyboard     |  12 +-
 .../etc/initramfs-tools/hooks/nexus           |   6 -
 .../etc/initramfs-tools/hooks/pxe             |   1 -
 .../etc/initramfs-tools/scripts/init          |  68 -------
 .../etc/initramfs-tools/scripts/nexus         |  46 +++++
 .../etc/initramfs-tools/scripts/pxe           |  80 ++------
 .../etc/initramfs-tools/scripts/tools         |  89 +++++++++
 .../02-customisation/home/user/.profile       |   2 +-
 .../03-post_install/2500-disable_services.sh  |   6 +
 .../config/03-post_install/3000-nexus_exam.sh |   4 +-
 .../03-post_install/5000-push_challenge.sh    |   6 +
 .../config/03-post_install/5000-pxe.sh        |   2 +-
 .../{9999-initramfs.sh => 8000-initramfs.sh}  |   0
 .../config/03-post_install/9999-cleanup.sh    |   7 +
 live_exam_os/tools/functions.sh               |  12 ++
 30 files changed, 313 insertions(+), 270 deletions(-)
 create mode 100644 live_exam_os/config/00-bootloader/grub.cfg
 create mode 100644 live_exam_os/config/00-bootloader/grub.efi.cfg
 delete mode 100644 live_exam_os/config/00-bootloader/limine_casper.conf
 delete mode 100644 live_exam_os/config/00-bootloader/limine_pxe.conf
 delete mode 100644 live_exam_os/config/02-customisation/etc/NetworkManager/NetworkManager.conf.bak
 delete mode 100644 live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/10-default-wired.conf.bak
 delete mode 100644 live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/dns.conf.bak
 delete mode 100644 live_exam_os/config/02-customisation/etc/challenge
 delete mode 100755 live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/nexus
 delete mode 100755 live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/init
 create mode 100755 live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/nexus
 create mode 100755 live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/tools
 create mode 100755 live_exam_os/config/03-post_install/2500-disable_services.sh
 create mode 100755 live_exam_os/config/03-post_install/5000-push_challenge.sh
 rename live_exam_os/config/03-post_install/{9999-initramfs.sh => 8000-initramfs.sh} (100%)
 create mode 100755 live_exam_os/config/03-post_install/9999-cleanup.sh

diff --git a/live_exam_os/.env.example b/live_exam_os/.env.example
index c0e640d..0cd3d7a 100644
--- a/live_exam_os/.env.example
+++ b/live_exam_os/.env.example
@@ -3,7 +3,6 @@ export SQUASHFS="/tmp/squashfs"
 export ROOTFS_DIR="/tmp/rootfs"
 export ISO_DIR="/tmp/iso"
 export BOOT_FOLDER="$ISO_DIR/boot"
-export LUKS_IMG="squash.rootfs.luks"
 
 # Nexus build configuration
 export SERVER="127.0.0.1:1077"
@@ -14,7 +13,9 @@ export EXAM_PWD="password"
 # Build parameters
 export LUKS_PASSPHRASE="passphrase"
 export ADDITIONAL_KEYS="keys keyss"
+export CHALLENGE="challenge"
 export VERBOSE=false
+export RAM="squashfs_tmpfs"
 #export PXE_URL="127.0.0.1:8000"
 export OUTPUT="build"
 export CACHE_FS="cache"
diff --git a/live_exam_os/Dockerfile b/live_exam_os/Dockerfile
index c8909d9..f5e1cdc 100644
--- a/live_exam_os/Dockerfile
+++ b/live_exam_os/Dockerfile
@@ -4,7 +4,7 @@ FROM ubuntu:22.04
 ENV archive=go1.22.6.linux-amd64.tar.gz
 ENV PATH=$PATH:/usr/local/go/bin
 
-RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y gcc pkg-config git wget make ca-certificates libglfw3-dev libxcursor-dev libxinerama-dev libxi-dev libxxf86vm-dev upx-ucl curl cryptsetup squashfs-tools fakechroot debootstrap xorriso
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y gcc pkg-config git wget make ca-certificates libglfw3-dev libxcursor-dev libxinerama-dev libxi-dev libxxf86vm-dev upx-ucl curl cryptsetup squashfs-tools fakechroot debootstrap xorriso mtools dosfstools
 
 RUN git clone https://github.com/limine-bootloader/limine.git --branch=v8.x-binary --depth=1 /opt/limine && \
     cd /opt/limine && \
diff --git a/live_exam_os/Makefile b/live_exam_os/Makefile
index 254f262..ae29092 100644
--- a/live_exam_os/Makefile
+++ b/live_exam_os/Makefile
@@ -15,6 +15,6 @@ bios_cd:
 	qemu-system-x86_64 -drive file=$(ISO),media=cdrom,if=ide,readonly=on -boot d -m 4G -smp 4
 
 uefi:
-	qemu-system-x86_64 -bios /usr/share/OVMF/x64/OVMF.fd -drive file=$(ISO),format=raw -boot d -m 16G -smp 4 -netdev user,id=n1 -device virtio-net-pci,netdev=n1 -serial mon:stdio
+	qemu-system-x86_64 -bios /usr/share/OVMF/x64/OVMF.fd -drive file=$(ISO),format=raw -boot d -m 16G -smp 4 -netdev user,id=n1 -device virtio-net-pci,netdev=n1
 
 .PHONY: build
diff --git a/live_exam_os/README.md b/live_exam_os/README.md
index 05ca500..3fe607e 100644
--- a/live_exam_os/README.md
+++ b/live_exam_os/README.md
@@ -29,8 +29,12 @@ For simpler deployment on any environment that supports Docker, we provide a `Do
 | `--output`           | Define the output folder (default: `.`). |
 | `--luks-passphrase`  | Enable LUKS encryption with a passphrase. |
 | `--luks-keys`        | Provide a list of additional keys for LUKS encryption. |
-| `--pxe`              | Set the URL of the PXE and generate an initramfs, kernel, and SquashFS for PXE use. |
-| `--cache`            | Specify the path to a folder containing a pre-downloaded clean filesystem. |
+| `--ram`              | Using the system in RAM. |
+| `--challenge`        | Challenge in use by yubikeys. |
+| `--arch`             | Set the architecture of the system (e.g., amd64). |
+| `--pxe`              |  Set the url of the pxe and generate an initramfs, kernel and squashfs for the pxe to use (use the url of the folder where the squashfs is stored, not the direct link to the squashfs). |
+| `--cache`            | Path to a folder with a clean fs already downloaded. |
+| `--version`          | Version of Ubuntu (e.g., Noble) |
 
 ### Environment Setup Parameters
 
diff --git a/live_exam_os/build.sh b/live_exam_os/build.sh
index f222c65..2542af4 100755
--- a/live_exam_os/build.sh
+++ b/live_exam_os/build.sh
@@ -3,14 +3,17 @@
 . tools/functions.sh
 
 # Default variables
-export SQUASHFS="/tmp/squashfs"
-export ROOTFS_DIR="/tmp/rootfs"
-export ISO_DIR="/tmp/iso"
+export SQUASHFS="output/squashfs"
+export ROOTFS_DIR="output/rootfs"
+export ISO_DIR="output/iso"
 export BOOT_FOLDER="$ISO_DIR/boot"
-export LUKS_IMG="squash.rootfs.luks"
+export SQUASHFS_IMG="squash.rootfs"
 export VERBOSE=false
-export OUTPUT="."
+export OUTPUT="build"
 export ISO_NAME="nexus.iso"
+export UBUNTU_VERSION="noble"
+export CHALLENGE="default_challenge"
+export ARCH="amd64"
 
 helper() {
   echo "USAGE: $(basename "$0") [options]"
@@ -21,8 +24,13 @@ helper() {
   echo "  --output              Set the output folder (default: .)"
   echo "  --luks-passphrase     Enable LUKS encryption with passphrase"
   echo "  --luks-keys           List of additional keys"
-  echo "  --pxe                 Set the url of the pxe and generate an initramfs, kernel and squashfs for pxe use"
+  echo "  --ram                 Using the system in RAM"
+  echo "  --challenge           List of additional keys"
+  echo "  --arch                Set the architecture of the system (e.g., amd64)"
+  echo "  --pxe                 Set the url of the pxe and generate an initramfs, kernel and squashfs for the pxe to use
+                        (use the url of the folder where the squashfs is stored, not the direct link to the squashfs)"
   echo "  --cache               Path to a folder with a clean fs already downloaded"
+  echo "  --version             Version of Ubuntu (e.g., Noble)"
   echo
   echo "Environment Setup Parameters:"
   echo "  SQUASHFS              Path to the SquashFS file (e.g., out/squash.rootfs)"
@@ -55,8 +63,13 @@ while [ "$#" -gt 0 ]; do
       fi
       ;;
     --luks-passphrase)
-      LUKS_PASSPHRASE="$2"
-      shit 2
+      if [ -n "$2" ]; then
+        LUKS_PASSPHRASE="$2"
+        shift 2
+      else
+        echo "Error: --luks-keys requires an argument" >&2
+        helper
+      fi
       ;;
     --luks-keys)
       if [ -n "$2" ]; then
@@ -67,6 +80,15 @@ while [ "$#" -gt 0 ]; do
         helper
       fi
       ;;
+    --challenge)
+      if [ -n "$2" ]; then
+        CHALLENGE="$2"
+        shift 2
+      else
+        echo "Error: --luks-keys requires an argument" >&2
+        helper
+      fi
+      ;;
     --pxe)
       if [ -n "$2" ]; then
         export PXE_URL="$2"
@@ -80,6 +102,10 @@ while [ "$#" -gt 0 ]; do
       export VERBOSE=true
       shift
       ;;
+    --ram)
+      export RAM="squashfs_tmpfs"
+      shift
+      ;;
     --verbose)
       export VERBOSE=true
       shift
@@ -93,6 +119,24 @@ while [ "$#" -gt 0 ]; do
         helper
       fi
       ;;
+    --version)
+      if [ -n "$2" ]; then
+        export UBUNTU_VERSION=$2
+        shift 2
+      else
+        echo "Error: --cache requires an argument" >&2
+        helper
+      fi
+      ;;
+    --arch)
+      if [ -n "$2" ]; then
+        export ARCH=$2
+        shift 2
+      else
+        echo "Error: --cache requires an argument" >&2
+        helper
+      fi
+      ;;
     *)
       echo "Unknown option: $1" >&2
       helper
@@ -101,15 +145,14 @@ while [ "$#" -gt 0 ]; do
 done
 
 check_environment_var
-
+CMDLINE="boot=nexus quiet splash $RAM modprobe.blacklist=floppy"
 
 echo "[Create filesystem...]"
 rm -rf "$ROOTFS_DIR" "$OUTPUT"
 mkdir -p "$ROOTFS_DIR"
 
 if [ -z $CACHE_FS ]; then
-  echo "debootstrap --arch=amd64 noble $ROOTFS_DIR http://archive.ubuntu.com/ubuntu/"
-  debootstrap --arch=amd64 noble $ROOTFS_DIR http://archive.ubuntu.com/ubuntu/
+  run_command debootstrap --arch=$ARCH $UBUNTU_VERSION $ROOTFS_DIR http://archive.ubuntu.com/ubuntu/
   mount -t proc /proc $ROOTFS_DIR/proc
   mount --rbind /sys $ROOTFS_DIR/sys
   mount --rbind /dev $ROOTFS_DIR/dev
@@ -119,15 +162,15 @@ if [ -z $CACHE_FS ]; then
   
   echo "[Installing packages...]"
   packages=$(tr '\n' ' ' < config/01-packages_install/packages)
-  echo "deb http://archive.ubuntu.com/ubuntu noble main universe" > $ROOTFS_DIR/etc/apt/sources.list
+  echo "deb http://archive.ubuntu.com/ubuntu $UBUNTU_VERSION main universe" > $ROOTFS_DIR/etc/apt/sources.list
   run_command_chroot apt update
   check_exit_code $? "Error during apt update"
-  run_command_chroot apt install -y --no-install-recommends zstd initramfs-tools linux-image-generic linux-firmware casper cryptsetup-initramfs $packages
+  run_command_chroot apt install -y --no-install-recommends $packages
   check_exit_code $? "Error during packages installation"
 else
   if [ ! -d $CACHE_FS ]; then
     mkdir $CACHE_FS
-    debootstrap --arch=amd64 noble $CACHE_FS http://archive.ubuntu.com/ubuntu/
+    run_command debootstrap --arch=$ARCH $UBUNTU_VERSION $CACHE_FS http://archive.ubuntu.com/ubuntu/
 
     mount -t proc /proc $CACHE_FS/proc
     mount --rbind /sys $CACHE_FS/sys
@@ -138,10 +181,10 @@ else
     
     echo "[Installing packages...]"
     packages=$(tr '\n' ' ' < config/01-packages_install/packages)
-    echo "deb http://archive.ubuntu.com/ubuntu noble main universe" > $CACHE_FS/etc/apt/sources.list
+    echo "deb http://archive.ubuntu.com/ubuntu $UBUNTU_VERSION main universe" > $CACHE_FS/etc/apt/sources.list
     run_command chroot $CACHE_FS apt update
     check_exit_code $? "Error during apt update"
-    run_command chroot $CACHE_FS apt install -y --no-install-recommends zstd initramfs-tools linux-image-generic linux-firmware casper cryptsetup-initramfs $packages
+    run_command chroot $CACHE_FS apt install -y --no-install-recommends $packages
     check_exit_code $? "Error during packages installation"
 
     umount -l $CACHE_FS/proc
@@ -150,7 +193,7 @@ else
     umount -l $CACHE_FS/run
     umount -l $CACHE_FS/tmp
   else
-    echo "Skip through cache"
+    echo " [Skip through cache]"
   fi
 
   cp -r $CACHE_FS/* $ROOTFS_DIR
@@ -165,12 +208,32 @@ fi
 echo "[Uploading configuration file...]"
 cp -rf config/02-customisation/* $ROOTFS_DIR
 
+if [ -z $PXE_URL ]; then
+  echo "[EFI img preparation]"
+  mkdir -p "$ISO_DIR/boot/grub"
+  sed "s/CMDLINE/$CMDLINE/g" config/00-bootloader/grub.cfg > "$ISO_DIR/boot/grub/grub.cfg"
+  EFIBOOT=/tmp/efiboot.img
+  EFIBOOT_MOUNT=/tmp/efiboot
+  SIZE_EFIBOOT=$(get_total_size $ROOTFS_DIR/usr/lib/shim/shimx64.efi.signed.latest $ROOTFS_DIR/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed)
+  OFFSET=$(( 150 * 1024 )) # Some space for fat header and grub.cfg file
+  
+  fallocate -l $(( $SIZE_EFIBOOT + $OFFSET)) $EFIBOOT
+  run_command mkfs.vfat $EFIBOOT
+  mkdir $EFIBOOT_MOUNT
+  mount -o loop $EFIBOOT $EFIBOOT_MOUNT
+  mkdir -p $EFIBOOT_MOUNT/EFI/BOOT
+  cp config/00-bootloader/grub.efi.cfg $EFIBOOT_MOUNT/EFI/BOOT/grub.cfg
+  cp $ROOTFS_DIR/usr/lib/shim/shimx64.efi.signed.latest "$EFIBOOT_MOUNT/EFI/BOOT/BOOTx64.EFI"
+  cp $ROOTFS_DIR/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed "$EFIBOOT_MOUNT/EFI/BOOT/grubx64.efi"
+  umount $EFIBOOT_MOUNT
+fi
+
 echo "[Post-install...]"
 for script in config/03-post_install/*.sh; do
   ./$script
 done
 
-echo "[Moving kernel..]"
+echo "[Moving kernel...]"
 cp $ROOTFS_DIR/boot/vmlinuz-* /tmp/vmlinuz
 cp $ROOTFS_DIR/boot/initrd.img /tmp/initrd
 rm -rf $ROOTFS_DIR/boot
@@ -182,96 +245,59 @@ umount -l $ROOTFS_DIR/dev
 umount -l $ROOTFS_DIR/run
 umount -l $ROOTFS_DIR/tmp
 
-echo "[Create squash.rootfs..]"
+echo "[Create squash.rootfs...]"
 run_command mksquashfs "$ROOTFS_DIR" "$SQUASHFS"
 check_exit_code $? "Error during squashfs generation"
 
 if [ ! -z $LUKS_PASSPHRASE ]; then
-  echo "[Encrypt squash.rootfs..]"
+  echo "[Encrypt squash.rootfs...]"
   SQUASHFS_SIZE=$(stat -c %s "$SQUASHFS")
   LUKS_HEADER_SIZE=$((1024 * 1024 * 16)) # 16 MiB header LUKS2
   TOTAL_SIZE=$((SQUASHFS_SIZE + LUKS_HEADER_SIZE))
   SECTOR_SIZE=512
-  TOTAL_SIZE=$(( (TOTAL_SIZE + SECTOR_SIZE - 1) / SECTOR_SIZE * SECTOR_SIZE ))
 
-  fallocate -l $TOTAL_SIZE "/tmp/$LUKS_IMG"
-  echo -n "$LUKS_PASSPHRASE" | cryptsetup luksFormat "/tmp/$LUKS_IMG" --batch-mode
-  echo -n "$LUKS_PASSPHRASE" | cryptsetup luksOpen "/tmp/$LUKS_IMG" container
+  fallocate -l $TOTAL_SIZE "/tmp/$SQUASHFS_IMG"
+  echo -n "$LUKS_PASSPHRASE" | cryptsetup luksFormat "/tmp/$SQUASHFS_IMG" --batch-mode
+  echo -n "$LUKS_PASSPHRASE" | cryptsetup luksOpen "/tmp/$SQUASHFS_IMG" container
   run_command dd if="$SQUASHFS" of=/dev/mapper/container bs=4M 
   cryptsetup luksClose container
   
   if [ ! -z $ADDITIONAL_KEYS ]; then
     for key in $ADDITIONAL_KEYS; do
-      echo -e "$LUKS_PASSPHRASE\n$key" | cryptsetup luksAddKey "/tmp/$LUKS_IMG"
+      echo -e "$LUKS_PASSPHRASE\n$key" | cryptsetup luksAddKey "/tmp/$SQUASHFS_IMG"
     done
   fi
 else
-  mkdir -p $ISO_DIR/casper
-  cp "$SQUASHFS" "$ISO_DIR/casper/filesystem.squashfs"
+  cp "$SQUASHFS" "/tmp/$SQUASHFS_IMG"
 fi
 
 mkdir $OUTPUT
-if [ ! -z $PXE_URL ];then
+if [ ! -z $PXE_URL ]; then
   cp /tmp/vmlinuz $OUTPUT
   cp /tmp/initrd $OUTPUT
-  cp /tmp/$LUKS_IMG $OUTPUT
-
-  echo "[Moving kernel to iso/boot...]"
-  mkdir -p $BOOT_FOLDER
-  cp /tmp/vmlinuz $BOOT_FOLDER/vmlinuz
-  cp /tmp/initrd $BOOT_FOLDER/initrd
-
-  echo "[Create iso...]"
-  
-  mkdir -p "$ISO_DIR/EFI/BOOT"
-  
-  cp /opt/limine/*.EFI "$ISO_DIR/EFI/BOOT/"
-  cp /opt/limine/*.bin "$ISO_DIR/"
-  cp /opt/limine/*.sys "$ISO_DIR/"
-  
-  cp config/00-bootloader/limine_pxe.conf "$ISO_DIR/boot/limine.conf"
-
-  run_command xorriso -as mkisofs -R -r -J -b "limine-bios-cd.bin" \
-          -no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \
-          -apm-block-size 2048 --efi-boot "limine-uefi-cd.bin" \
-          -efi-boot-part --efi-boot-image --protective-msdos-label \
-          -volid "NEXUSCLIENTISO" \
-          "$ISO_DIR" -o "$OUTPUT/$ISO_NAME"
-  check_exit_code $? "Error during iso creation"
-  
-  run_command limine bios-install "$OUTPUT/$ISO_NAME"
-  check_exit_code $? "Error during add bios header"
+  cp /tmp/$SQUASHFS_IMG $OUTPUT
 else
   echo "[Moving kernel && squashfs from rootfs to iso/boot...]"
   mkdir -p $BOOT_FOLDER
   cp /tmp/vmlinuz $BOOT_FOLDER/vmlinuz
   cp /tmp/initrd $BOOT_FOLDER/initrd
-  cp /tmp/$LUKS_IMG $ISO_DIR/$LUKS_IMG
 
   echo "[Create iso...]"
-  
-  mkdir -p "$ISO_DIR/EFI/BOOT"
-  
-  cp /opt/limine/*.EFI "$ISO_DIR/EFI/BOOT/"
+  cp /tmp/$SQUASHFS_IMG $ISO_DIR/$SQUASHFS_IMG
   cp /opt/limine/*.bin "$ISO_DIR/"
   cp /opt/limine/*.sys "$ISO_DIR/"
-  
-  if [ ! -z $LUKS_PASSPHRASE ]; then
-    cp config/00-bootloader/limine.conf "$ISO_DIR/boot/"
-  else
-    cp config/00-bootloader/limine_casper.conf "$ISO_DIR/boot/limine.conf"
-  fi
+  cp $EFIBOOT $ISO_DIR
+  sed "s/CMDLINE/$CMDLINE/g" config/00-bootloader/limine.conf > "$ISO_DIR/boot/limine.conf"
 
   run_command xorriso -as mkisofs -R -r -J -b "limine-bios-cd.bin" \
-          -no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \
-          -apm-block-size 2048 --efi-boot "limine-uefi-cd.bin" \
-          -efi-boot-part --efi-boot-image --protective-msdos-label \
-          -volid "NEXUSCLIENTISO" \
-          "$ISO_DIR" -o "$OUTPUT/$ISO_NAME"
+        -no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \
+        -apm-block-size 2048 --efi-boot "efiboot.img" \
+        -efi-boot-part --efi-boot-image --protective-msdos-label \
+        -volid "NEXUSCLIENTISO" \
+        "$ISO_DIR" -o "$OUTPUT/$ISO_NAME"
+
   check_exit_code $? "Error during iso creation"
-  
   run_command limine bios-install "$OUTPUT/$ISO_NAME"
-  check_exit_code $? "Error during add bios header"
 fi
 
 chown -R 1000:1000 "$OUTPUT"
diff --git a/live_exam_os/config/00-bootloader/grub.cfg b/live_exam_os/config/00-bootloader/grub.cfg
new file mode 100644
index 0000000..b9c1390
--- /dev/null
+++ b/live_exam_os/config/00-bootloader/grub.cfg
@@ -0,0 +1,6 @@
+set timeout=0
+
+menuentry "Nexus-Exam" {
+    linux /boot/vmlinuz CMDLINE --
+    initrd /boot/initrd
+}
diff --git a/live_exam_os/config/00-bootloader/grub.efi.cfg b/live_exam_os/config/00-bootloader/grub.efi.cfg
new file mode 100644
index 0000000..08ef767
--- /dev/null
+++ b/live_exam_os/config/00-bootloader/grub.efi.cfg
@@ -0,0 +1,2 @@
+search --file /boot/vmlinuz --no-floppy --set root
+configfile /boot/grub/grub.cfg
diff --git a/live_exam_os/config/00-bootloader/limine.conf b/live_exam_os/config/00-bootloader/limine.conf
index a2004d6..5a2cf96 100644
--- a/live_exam_os/config/00-bootloader/limine.conf
+++ b/live_exam_os/config/00-bootloader/limine.conf
@@ -3,5 +3,5 @@ timeout: 0
 /Nexus
     protocol: linux
     kernel_path: boot():/boot/vmlinuz
-    kernel_cmdline: boot=nexus quiet splash
+    kernel_cmdline: CMDLINE
     module_path: boot():/boot/initrd
diff --git a/live_exam_os/config/00-bootloader/limine_casper.conf b/live_exam_os/config/00-bootloader/limine_casper.conf
deleted file mode 100644
index 853c8c8..0000000
--- a/live_exam_os/config/00-bootloader/limine_casper.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-timeout: 0
-
-/Nexus
-    protocol: linux
-    kernel_path: boot():/boot/vmlinuz
-    kernel_cmdline: boot=casper quiet splash
-    module_path: boot():/boot/initrd
diff --git a/live_exam_os/config/00-bootloader/limine_pxe.conf b/live_exam_os/config/00-bootloader/limine_pxe.conf
deleted file mode 100644
index 653cf3a..0000000
--- a/live_exam_os/config/00-bootloader/limine_pxe.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-timeout: 0
-
-/Nexus
-    protocol: linux
-    kernel_path: boot():/boot/vmlinuz
-    kernel_cmdline: boot=pxe quiet splash
-    module_path: boot():/boot/initrd
diff --git a/live_exam_os/config/01-packages_install/packages b/live_exam_os/config/01-packages_install/packages
index f60d5f3..c47aa32 100644
--- a/live_exam_os/config/01-packages_install/packages
+++ b/live_exam_os/config/01-packages_install/packages
@@ -1,4 +1,8 @@
-udev
+zstd
+initramfs-tools
+linux-image-generic
+linux-firmware
+cryptsetup-initramfs 
 network-manager
 xserver-xorg
 xserver-xorg-input-libinput
@@ -14,8 +18,8 @@ virt-viewer
 mesa-va-drivers
 iptables
 ufw
-sudo
-vim
 rfkill
 wpasupplicant
 yubikey-personalization
+shim-signed
+grub-efi-amd64-signed
diff --git a/live_exam_os/config/02-customisation/etc/NetworkManager/NetworkManager.conf.bak b/live_exam_os/config/02-customisation/etc/NetworkManager/NetworkManager.conf.bak
deleted file mode 100644
index 06c5d59..0000000
--- a/live_exam_os/config/02-customisation/etc/NetworkManager/NetworkManager.conf.bak
+++ /dev/null
@@ -1,8 +0,0 @@
-[main]
-plugins=ifupdown,keyfile
-
-[ifupdown]
-managed=true
-
-[device]
-wifi.scan-rand-mac-address=no
diff --git a/live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/10-default-wired.conf.bak b/live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/10-default-wired.conf.bak
deleted file mode 100644
index 5582524..0000000
--- a/live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/10-default-wired.conf.bak
+++ /dev/null
@@ -1,10 +0,0 @@
-[connection]
-id=Auto Ethernet
-type=ethernet
-autoconnect=true
-
-[ipv4]
-method=auto
-
-[ipv6]
-method=auto
diff --git a/live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/dns.conf.bak b/live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/dns.conf.bak
deleted file mode 100644
index d435aba..0000000
--- a/live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/dns.conf.bak
+++ /dev/null
@@ -1,2 +0,0 @@
-[main]
-dns=none
diff --git a/live_exam_os/config/02-customisation/etc/challenge b/live_exam_os/config/02-customisation/etc/challenge
deleted file mode 100644
index 9daeafb..0000000
--- a/live_exam_os/config/02-customisation/etc/challenge
+++ /dev/null
@@ -1 +0,0 @@
-test
diff --git a/live_exam_os/config/02-customisation/etc/default/keyboard b/live_exam_os/config/02-customisation/etc/default/keyboard
index c7fe671..ad849b1 100644
--- a/live_exam_os/config/02-customisation/etc/default/keyboard
+++ b/live_exam_os/config/02-customisation/etc/default/keyboard
@@ -2,9 +2,9 @@
 
 # Consult the keyboard(5) manual page.
 
-#XKBMODEL="pc105"
-#XKBLAYOUT="ch"
-#XKBVARIANT="fr"
-#XKBOPTIONS=""
-#
-#BACKSPACE="guess"
+XKBMODEL="pc105"
+XKBLAYOUT="ch"
+XKBVARIANT="fr"
+XKBOPTIONS=""
+
+BACKSPACE="guess"
diff --git a/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/nexus b/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/nexus
deleted file mode 100755
index e1a61da..0000000
--- a/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/nexus
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-set -e
-
-. /usr/share/initramfs-tools/hook-functions
-
-copy_exec /etc/initramfs-tools/scripts/init /scripts/nexus
diff --git a/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/pxe b/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/pxe
index 887c32d..64ef189 100755
--- a/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/pxe
+++ b/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/pxe
@@ -6,4 +6,3 @@ set -e
 if [ -f /etc/squashfs-url ]; then
   copy_exec /etc/squashfs-url /squashfs-url
 fi
-copy_exec /etc/initramfs-tools/scripts/pxe /scripts/pxe
diff --git a/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/init b/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/init
deleted file mode 100755
index 337eeb8..0000000
--- a/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/init
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/sh
-
-mount_and_switch() {
-  SQUASHFS_PATH=$1
-
-  echo "Mounting overlay..."
-  mkdir -p /squash /upper /work /newroot
-  mount -t squashfs $SQUASHFS_PATH /squash
-
-  mount -t overlay -o lowerdir=/squash,upperdir=/upper,workdir=/work overlayfs /newroot
-  
-  mount -t devtmpfs none /newroot/dev
-  mount -t proc none /newroot/proc
-  mount -t sysfs none /newroot/sys
-  mount -t tmpfs none /newroot/tmp
-  mount -t devpts none /newroot/dev/pts
-  
-  exec switch_root /newroot /sbin/init
-}
-
-decrypt_with_passphrase() {
-  cryptsetup open /cdrom/squash.rootfs.luks data
-  exit_code=$?
-  
-  if [ "$exit_code" -eq 0 ]; then
-    mount_and_switch /dev/mapper/data
-  fi
-
-  echo "Wrong passphrase"
-}
-
-decrypt_with_challenge() {
-  echo -n "$1" | cryptsetup open /cdrom/squash.rootfs.luks data
-  exit_code=$?
-
-  if [ "$exit_code" -eq 0 ]; then
-    mount_and_switch /dev/mapper/data
-  fi
-
-  echo "Decryption error, possibly wrong Yubikey"
-}
-
-while [ -z $(blkid | grep "NEXUSCLIENTISO" | cut -d ':' -f1) ]; do
-  echo -n ""
-done
-
-DISK=$(blkid | grep "NEXUSCLIENTISO" | cut -d ':' -f1 | sed 's/.$//')
-mkdir -p /cdrom
-mount -t iso9660 $DISK /cdrom
-
-echo "Waiting for Yubikey. Press 'p' to enter the passphrase"
-while true; do
-  output=$(ykchalresp -2 -i /scripts/challenge 2>&1)
-  exit_code=$?
-  
-  if read -t 1 -n 1 input && [ "$input" = "p" ]; then
-    echo ""
-    decrypt_with_passphrase
-    continue
-  fi
-  
-  if [ "$exit_code" -eq 1 ]; then
-      sleep 1
-      continue
-  fi
-
-  decrypt_with_challenge $output
-done
diff --git a/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/nexus b/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/nexus
new file mode 100755
index 0000000..0b2fb41
--- /dev/null
+++ b/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/nexus
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+. /scripts/tools
+
+while true; do
+    for dev in /dev/sd* /dev/sr*; do
+        if [ -e "$dev" ]; then
+            label="$(blkid -o value -s LABEL "$dev" 2>/dev/null)"
+            if [ "$label" = "NEXUSCLIENTISO" ]; then
+                DISK="$dev"
+                break 2
+            fi
+        fi
+    done
+done
+
+
+mkdir -p /cdrom
+mount -t iso9660 $DISK /cdrom
+
+cryptsetup isLuks /cdrom/squash.rootfs
+exit_code=$?
+if [ ! $exit_code -eq 0 ]; then
+  mount_and_switch /cdrom/squash.rootfs
+fi
+
+
+echo "Waiting for Yubikey."
+while true; do
+  output=$(ykchalresp -2 -i /scripts/challenge 2>&1)
+
+  exit_code=$?
+  
+  if read -t 1 -n 1 input && [ "$input" = "p" ]; then
+    echo ""
+    decrypt_with_passphrase /cdrom/squash.rootfs
+    continue
+  fi
+  
+  if [ "$exit_code" -eq 1 ]; then
+      sleep 1
+      continue
+  fi
+
+  decrypt_with_challenge /cdrom/squash.rootfs $output
+done
diff --git a/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/pxe b/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/pxe
index 6579225..d5ed66b 100755
--- a/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/pxe
+++ b/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/pxe
@@ -1,86 +1,30 @@
 #!/bin/sh
 
-LUKS_FILE="/squash.rootfs"
+. /scripts/tools
 
-find_active_interface() {
-    for iface in $(ls /sys/class/net); do
-        if [ "$iface" = "lo" ]; then
-            continue
-        fi
-
-        if [ "$(cat /sys/class/net/$iface/type)" = "1" ]; then
-            if ip link show "$iface" | grep -q "<BROADCAST,MULTICAST>"; then
-                echo "Lookup for $iface interface"
-                dhcpcd -q $iface
-                exit_code=$?
-
-                if [ "$exit_code" -eq 0 ]; then
-                  return 0
-                fi
-            fi
-        fi
-    done
-
-    echo "No active network interface found." >&2
-    /bin/sh
-    return 1
-}
-
-mount_and_switch() {
-  SQUASHFS_PATH=$1
-
-  echo "Mounting overlay..."
-  mkdir -p /squash /upper /work /newroot
-  mount -t squashfs $SQUASHFS_PATH /squash
-
-  mount -t overlay -o lowerdir=/squash,upperdir=/upper,workdir=/work overlayfs /newroot
-  
-  mount -t devtmpfs none /newroot/dev
-  mount -t proc none /newroot/proc
-  mount -t sysfs none /newroot/sys
-  mount -t tmpfs none /newroot/tmp
-  mount -t devpts none /newroot/dev/pts
-  
-  exec switch_root /newroot /sbin/init
-}
-
-decrypt_with_passphrase() {
-  cryptsetup open $LUKS_FILE data
-  exit_code=$?
-  
-  if [ "$exit_code" -eq 0 ]; then
-    mount_and_switch /dev/mapper/data
-  fi
-
-  echo "Wrong passphrase"
-}
-
-decrypt_with_challenge() {
-  echo -n "$1" | cryptsetup open $LUKS_FILE data
-  exit_code=$?
-
-  if [ "$exit_code" -eq 0 ]; then
-    mount_and_switch /dev/mapper/data
-  fi
-
-  echo "Decryption error, possibliy wrong Yubikey"
-}
+SQUASH_FILE="/squash.rootfs"
 
 sleep 3
 
 echo "DHCP lookup..."
 find_active_interface
 
-wget $(cat /squashfs-url) -O $LUKS_FILE
+wget $(cat /squashfs-url) -O $SQUASH_FILE
+
+cryptsetup isLuks $SQUASH_FILE
+exit_code=$?
+if [ ! $exit_code -eq 0 ]; then
+  mount_and_switch $SQUASH_FILE
+fi
 
-echo "Waiting for Yubikey. Press 'p' to enter the passphrase"
+echo "Waiting for Yubikey"
 while true; do
   output=$(ykchalresp -2 -i /scripts/challenge 2>&1)
   exit_code=$?
   
   if read -t 1 -n 1 input && [ "$input" = "p" ]; then
     echo ""
-    decrypt_with_passphrase
+    decrypt_with_passphrase $SQUASH_FILE
     continue
   fi
   
@@ -89,5 +33,5 @@ while true; do
       continue
   fi
   
-  decrypt_with_challenge $output
+  decrypt_with_challenge $SQUASH_FILE $output
 done
diff --git a/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/tools b/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/tools
new file mode 100755
index 0000000..1f71251
--- /dev/null
+++ b/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/tools
@@ -0,0 +1,89 @@
+#!/bin/bash
+
+mount_and_switch() {
+  SQUASHFS_PATH=$1
+
+  mount_fs $SQUASHFS_PATH
+  
+  mount -t devtmpfs none /newroot/dev
+  mount -t proc none /newroot/proc
+  mount -t sysfs none /newroot/sys
+  mount -t tmpfs none /newroot/tmp
+  mount -t devpts none /newroot/dev/pts
+  
+  exec switch_root /newroot /sbin/init
+}
+
+decrypt_with_passphrase() {
+  SQUASHFS_LUKS=$1
+  cryptsetup open $1 data
+  exit_code=$?
+  
+  if [ "$exit_code" -eq 0 ]; then
+    mount_and_switch /dev/mapper/data
+  fi
+
+  echo "Wrong passphrase"
+}
+
+decrypt_with_challenge() {
+  SQUASHFS_LUKS=$1
+  echo -n "$2" | cryptsetup open $SQUASHFS_LUKS data
+  exit_code=$?
+
+  if [ "$exit_code" -eq 0 ]; then
+    mount_and_switch /dev/mapper/data
+  fi
+
+  echo "Decryption error, possibly wrong Yubikey"
+}
+
+mount_fs() {
+  SQUASHFS_PATH=$1
+  mkdir -p /newroot/{home, run, tmp, var/log, var/tmp} /rw_home /squash
+
+  if grep -q "squashfs_tmpfs" /proc/cmdline; then
+    echo "Mounting fs on ram..."
+    mount -t squashfs -o loop,ro $SQUASHFS_PATH /squash
+    mount -t tmpfs none /newroot
+    cp -rp /squash/* /newroot
+  else
+    echo "Mounting fs..."
+    mount -t squashfs -o loop,ro "$SQUASHFS_PATH" /newroot
+  fi
+
+  mount -t tmpfs none /rw_home
+  cp -rp /newroot/home/. /rw_home/
+
+  mount -t tmpfs none /newroot/run
+  mount -t tmpfs none /newroot/tmp
+  mount -t tmpfs none /newroot/var/log
+  mount -t tmpfs none /newroot/var/tmp
+  mount -t tmpfs none /newroot/var/lib/systemd
+  mount --bind /rw_home /newroot/home
+}
+
+
+find_active_interface() {
+    for iface in $(ls /sys/class/net); do
+        if [ "$iface" = "lo" ]; then
+            continue
+        fi
+
+        if [ "$(cat /sys/class/net/$iface/type)" = "1" ]; then
+            if ip link show "$iface" | grep -q "<BROADCAST,MULTICAST>"; then
+                echo "Lookup for $iface interface"
+                dhcpcd -q $iface
+                exit_code=$?
+
+                if [ "$exit_code" -eq 0 ]; then
+                  return 0
+                fi
+            fi
+        fi
+    done
+
+    echo "No active network interface found." >&2
+    /bin/sh
+    return 1
+}
diff --git a/live_exam_os/config/02-customisation/home/user/.profile b/live_exam_os/config/02-customisation/home/user/.profile
index 9992ad7..fecabe0 100644
--- a/live_exam_os/config/02-customisation/home/user/.profile
+++ b/live_exam_os/config/02-customisation/home/user/.profile
@@ -2,4 +2,4 @@ while [ ! -e /dev/dri/card* ]; do
     sleep 1
 done
 
-startx
+startx && poweroff
diff --git a/live_exam_os/config/03-post_install/2500-disable_services.sh b/live_exam_os/config/03-post_install/2500-disable_services.sh
new file mode 100755
index 0000000..7d247d7
--- /dev/null
+++ b/live_exam_os/config/03-post_install/2500-disable_services.sh
@@ -0,0 +1,6 @@
+#/bin/sh
+
+. tools/functions.sh
+
+echo " [Masking services...]"
+run_command_chroot systemctl mask console-setup
diff --git a/live_exam_os/config/03-post_install/3000-nexus_exam.sh b/live_exam_os/config/03-post_install/3000-nexus_exam.sh
index 5d80457..0894fb9 100755
--- a/live_exam_os/config/03-post_install/3000-nexus_exam.sh
+++ b/live_exam_os/config/03-post_install/3000-nexus_exam.sh
@@ -3,7 +3,7 @@
 . tools/functions.sh
 
 echo " [Compiling nexus-exam...]"
-cd ..
+pushd ..  > /dev/null
 run_command make build_nexus-exam SERVER=$SERVER CERT=$CERT EXAM_USER=$EXAM_USER EXAM_PWD=$EXAM_PWD
 check_exit_code $? "Error during nexus-exam compilation"
 if [[ "$ROOTFS_DIR" != /* ]]; then
@@ -14,4 +14,4 @@ else
   cp build/nexus-exam $ROOTFS_DIR/usr/local/bin/nexus-exam
 fi
 make clean_client
-cd -
+popd  > /dev/null
diff --git a/live_exam_os/config/03-post_install/5000-push_challenge.sh b/live_exam_os/config/03-post_install/5000-push_challenge.sh
new file mode 100755
index 0000000..27bfbe6
--- /dev/null
+++ b/live_exam_os/config/03-post_install/5000-push_challenge.sh
@@ -0,0 +1,6 @@
+#/bin/bash
+
+. tools/functions.sh
+
+ echo " [Adding challenge file...]"
+ echo "$CHALLENGE" > $ROOTFS_DIR/etc/challenge
diff --git a/live_exam_os/config/03-post_install/5000-pxe.sh b/live_exam_os/config/03-post_install/5000-pxe.sh
index ecf5afd..5f11861 100755
--- a/live_exam_os/config/03-post_install/5000-pxe.sh
+++ b/live_exam_os/config/03-post_install/5000-pxe.sh
@@ -4,5 +4,5 @@
 
 if [ ! -z $PXE_URL ]; then
   echo " [Adding PXE url...]"
-  echo -n "$PXE_URL/$LUKS_IMG" > $ROOTFS_DIR/etc/squashfs-url
+  echo -n "$PXE_URL/$SQUASHFS_IMG" > $ROOTFS_DIR/etc/squashfs-url
 fi
diff --git a/live_exam_os/config/03-post_install/9999-initramfs.sh b/live_exam_os/config/03-post_install/8000-initramfs.sh
similarity index 100%
rename from live_exam_os/config/03-post_install/9999-initramfs.sh
rename to live_exam_os/config/03-post_install/8000-initramfs.sh
diff --git a/live_exam_os/config/03-post_install/9999-cleanup.sh b/live_exam_os/config/03-post_install/9999-cleanup.sh
new file mode 100755
index 0000000..deafdfb
--- /dev/null
+++ b/live_exam_os/config/03-post_install/9999-cleanup.sh
@@ -0,0 +1,7 @@
+#/bin/bash
+
+. tools/functions.sh
+
+echo " [Cleanup...]"
+PACKAGES="casper krb5-locales libatm1t64 libglib2.0-data libnss-systemd libpam-cap logrotate python3-rich rfkill rsyslog systemd-hwe-hwdb systemd-resolved systemd-timesyncd ubuntu-pro-client-l10n xfce4-terminal xxd yubikey-personalization zstd"
+run_command_chroot apt remove --purge -y $PACKAGES
diff --git a/live_exam_os/tools/functions.sh b/live_exam_os/tools/functions.sh
index ad9b113..0a945ad 100755
--- a/live_exam_os/tools/functions.sh
+++ b/live_exam_os/tools/functions.sh
@@ -37,3 +37,15 @@ check_environment_var() {
     helper
   fi
 }
+
+get_total_size() {
+    local total=0
+    for file in "$@"; do
+        if [[ -f "$file" ]]; then
+            total=$(( total + $(stat -c%s "$file") ))
+        else
+            return 1
+        fi
+    done
+    echo "$total"
+}
-- 
GitLab