diff --git a/live_exam_os/.env.example b/live_exam_os/.env.example
deleted file mode 100644
index 0cd3d7a9e87782eb072cf08fe18898849fc92db5..0000000000000000000000000000000000000000
--- a/live_exam_os/.env.example
+++ /dev/null
@@ -1,21 +0,0 @@
-# Location of generated files
-export SQUASHFS="/tmp/squashfs"
-export ROOTFS_DIR="/tmp/rootfs"
-export ISO_DIR="/tmp/iso"
-export BOOT_FOLDER="$ISO_DIR/boot"
-
-# Nexus build configuration
-export SERVER="127.0.0.1:1077"
-export CERT="ca-cert.pem"
-export EXAM_USER="user"
-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/.gitignore b/live_exam_os/.gitignore
index d8019d83dcf6a8ca82333333c7c9925cb6fcddac..13e2528deaca3ca35d47df372b92142538ebc354 100644
--- a/live_exam_os/.gitignore
+++ b/live_exam_os/.gitignore
@@ -1,4 +1,4 @@
 *.iso
-.env
+.env*
 cache/
 config/02-customisation/etc/NetworkManager/system-connections/wifi.nmconnection
diff --git a/live_exam_os/README.md b/live_exam_os/README.md
index 3fe607e463a843a35271fbd78f94946d5d3ff244..32b56cf55921d1965892a941853a4c3f1a5aea87 100644
--- a/live_exam_os/README.md
+++ b/live_exam_os/README.md
@@ -1,130 +1,197 @@
 # Live Exam OS Builder
 
-This project provides a set of tools and scripts to build a customized ISO image for live examination environments. It supports features such as PXE booting, LUKS encryption, and user environment setup.
+This project provides a set of tools and scripts to build a customized ISO image for live examination environments. It supports features such as PXE booting, LUKS encryption, user environment setup, and secure boot.
+
+---
+
+## Important Notice
+
+**This script should be run inside a container or a virtual machine (VM).** The script binds directories like `/dev`, `/sys`, and others to the new filesystem. If a problem occurs, it could corrupt the host system, necessitating a reboot. Running the script in an isolated environment like a container or VM helps prevent these issues.
 
 ---
 
 ## Usage
 
-To use the script, run it with the following command:
+To build the ISO image, you should use the provided Docker setup. The script `build.sh` should not be run directly on the host system. Instead, use the following methods:
 
-```bash
-./build.sh [options]
-```
+### Using Makefile
 
-### Requirements
+The Makefile simplifies the process of building and running the project in a Docker container.
 
-The `build.sh` script should be executed on a Ubuntu/Debian environment with the following tools installed:
-- `debootstrap`
-- Other necessary dependencies for building ISO images.
+1. **Build the Docker Image**:
+   ```bash
+   make build
+   ```
 
-For simpler deployment on any environment that supports Docker, we provide a `Dockerfile` and `Makefile`. These tools allow you to build and run the project without worrying about host system dependencies.
+2. **Run the Build Script**:
+    ```bash
+    make run PARAM="<param>"
+    ```
+Replace <param> with the desired parameters for the build.sh script.
 
-### Options
+### Using Docker Directly
 
-| Option                | Description |
-|-----------------------|-------------|
-| `-v, --verbose`      | Enable verbose mode for detailed output. |
-| `--env`              | Specify the path to an environment file with the required parameters. |
-| `--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. |
-| `--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) |
+If you prefer to use Docker commands directly, you can run the script with the following command:
+
+```bash
+docker run -it --rm -v $(pwd)/..:/data --workdir /data/live_exam_os --privileged <image_name> ./build.sh <param>
+```
+
+Replace <image_name> with the name of your Docker image and <param> with the desired parameters for the build.sh script.
+
+### Options
+| Option 	| Description 	|
+|:-	|:---|
+| -v, --verbose 	| Enable verbose mode for detailed output. 	|
+| --env 	| Specify the path to an environment file with the required parameters. 	|
+| --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. 	|
+| --ram 	| Use the system in RAM. 	|
+| --challenge 	| Specify the 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 filesystem already downloaded. 	|
+| --version 	| Version of Ubuntu (e.g., Noble). 	|
 
 ### Environment Setup Parameters
+| SQUASHFS   	| Path to the SquashFS file (e.g., out/squash.rootfs).           	|
+|:-	|:------------------------------------	|
+| ROOTFS_DIR 	| Path to the temporary filesystem directory (e.g., out/rootfs). 	|
+| ISO_DIR    	| Path to the temporary ISO directory (e.g., out/iso).           	|
+| SERVER     	| IP address of the Nexus server (e.g., 127.0.0.1:1077).         	|
+| CERT       	| Path to the certificate file (e.g., ca-cert.pem).              	|
+| EXAM_USER  	| Default username for the exam client (e.g., user).             	|
+| EXAM_PWD   	| Default password for the exam client (e.g., password).         	|
+
+### .env File
+The .env file is used to configure the build environment. Below is an example of what the .env file might look like:
 
-| Parameter      | Description |
-|----------------|-------------|
-| `SQUASHFS`     | Path to the SquashFS file (e.g., `out/squash.rootfs`). |
-| `ROOTFS_DIR`   | Path to the temporary filesystem directory (e.g., `out/rootfs`). |
-| `ISO_DIR`      | Path to the temporary ISO directory (e.g., `out/iso`). |
-| `SERVER`       | IP address of the Nexus server (e.g., `127.0.0.1:1077`). |
-| `CERT`         | Path to the certificate file (e.g., `ca-cert.pem`). |
-| `EXAM_USER`    | Default username for the exam client (e.g., `user`). |
-| `EXAM_PWD`     | Default password for the exam client (e.g., `password`). |
+```bash
+# Location of generated files
+export SQUASHFS="output/squashfs"
+export ROOTFS_DIR="output/rootfs"
+export ISO_DIR="output/iso"
+export BOOT_FOLDER="$ISO_DIR/boot"
+
+# Nexus build configuration
+export SERVER="127.0.0.1:1077"
+export CERT="ca-cert.pem"
+export EXAM_USER="user"
+export EXAM_PWD="password"
+
+# Build parameters
+export LUKS_PASSPHRASE="passphrase"
+export ADDITIONAL_KEYS="key1 key2"
+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"
+```
+Uncomment and set the necessary variables to customize your build environment.
 
----
+### Example Usage
 
-## Example Usage
+Here are some examples of how to use the script with the Makefile:
 
-Here are some examples of how to use the script:
+#### Example 1
 
-### Example 1
 Build an ISO image with LUKS encryption:
 ```bash
-./build.sh --env .env
+make run PARAM="--env .env"
 ```
 
-### Example 2
+#### Example 2
+
 Build an ISO image without LUKS encryption:
 ```bash
-./build.sh --output build --luks-passphrase 'my_luks_pass' --cache cache --pxe
+make run PARAM="--output build --luks-passphrase 'my_luks_pass' --cache cache --pxe 127.0.0.1:8000"
 ```
-
----
-
-## Makefile Targets
+#### Makefile Targets
 
 The Makefile includes targets to facilitate the building, running, and testing processes.
+|  Target 	|                              Description                             	|
+|:- |:----------	|
+| build   	| Build the Docker image for the project.                              	|
+| run     	| Run the Docker container to execute the build script.                	|
+| bios    	| Run the ISO in QEMU using BIOS mode.                                 	|
+| bios_cd 	| Run the ISO in QEMU using BIOS mode with a CD-ROM interface.         	|
+| uefi    	| Run the ISO in QEMU using UEFI mode. 	                                |
 
-### Available Targets
-
-| Target    | Description |
-|-----------|-------------|
-| `build`   | Build the Docker image for the project. |
-| `run`     | Run the Docker container to execute the build script. |
-| `bios`    | Run the ISO in QEMU using BIOS mode. |
-| `bios_cd` | Run the ISO in QEMU using BIOS mode with a CD-ROM interface. |
-| `uefi`    | Run the ISO in QEMU using UEFI mode with network and serial options. |
-
-### Running Makefile Targets
-
-1. **Build the Docker Image**:
-   ```bash
-   make build
-   ```
+#### Running Makefile Targets
 
-2. **Run the Build Script**:
-   ```bash
-   make run PARAM="--env .env"
-   ```
+1. Build the Docker Image:
+```bash
+make build
+```
 
-3. **Test the ISO in QEMU**:
-   - BIOS mode:
-     ```bash
-     make bios ISO=image.iso
-     ```
-   - BIOS with CD-ROM:
-     ```bash
-     make bios_cd ISO=image.iso
-     ```
-   - UEFI mode:
-     ```bash
-     make uefi ISO=image.iso
-     ```
+2. Run the Build Script:
+```bash
+make run PARAM="<param>"
+```
 
+3. Test the ISO in QEMU:
+ - BIOS mode:
+    ```bash
+    make bios ISO=image.iso
+    ```
+
+ - BIOS with CD-ROM:
+    ```bash
+    make bios_cd ISO=image.iso
+    ```
+ - UEFI mode:
+    ```bash
+    make uefi ISO=image.iso
+    ```
 ---
 
 ## Project Components
-
 ### Scripts
-- **build.sh**: Main script to build the ISO image and configure the environment.
+ - **build.sh**: Main script to build the ISO image and configure the environment.
+ - **tools/functions.sh**: Contains helper functions used by the build.sh script to streamline operations and ensure consistency.
 
 ### Docker
 - **Dockerfile**: Defines the Docker image used to build the live examination environment.
 - **Makefile**: Simplifies the process of building and running the project in a Docker container.
 
 ### Configuration Files
-- **Environment file**: Provides parameters and paths required by the build script.
+The configuration files are organized in the config/ directory and include the following subdirectories:
+
+ - **config/00-bootloader**: Contains bootloader configuration files.
+    - grub.cfg, grub.efi.cfg, limine.conf
+
+ - **config/01-packages_install**: Lists packages to be installed.
+    - packages
+
+ - **config/02-customisation**: Contains customization files for the filesystem.
+    - etc/, home/, usr/
+
+ - **config/03-post_install**: Contains post-installation scripts to further customize the environment.
+    - 1000-create-user.sh, 2000-enable_services.sh, 3000-nexus_exam.sh, 5000-push_challenge.sh, 8000-initramfs.sh, 1000-disable_root.sh, 2500-disable_services.sh, 4000-firewall.sh, 5000-pxe.sh, 9999-cleanup.sh
 
 ---
 
-## Notes
+## Requirements (For Advanced Users)
 
-- Ensure that all required dependencies are installed before running the script or Makefile.
-- For UEFI testing, verify that the `OVMF` firmware is installed on your system (e.g., `/usr/share/OVMF/x64/OVMF.fd`).
+The build.sh script should be executed in an environment with the following tools installed. These requirements are already satisfied within the provided Dockerfile. Advanced users who wish to modify the Dockerfile or run the script outside of Docker should ensure these tools are available:
+
+ - debootstrap
+ - chroot
+ - sed
+ - mount
+ - umount
+ - fallocate
+ - mkfs.vfat
+ - mksquashfs
+ - cryptsetup
+ - bash
+ - xorriso
+ - limine
+
+## Notes
+ - Ensure that all required dependencies are installed before running the script or Makefile.
+ - For UEFI testing, verify that the OVMF firmware is installed on your system (e.g., /usr/share/OVMF/x64/OVMF.fd).
+ - When specifying a cache directory or a folder for downloading the filesystem, avoid using /tmp in the container, as it is often set with the noexec attribute, which can prevent tools like debootstrap from functioning correctly. Choose a directory with execution permissions instead.
diff --git a/live_exam_os/build.sh b/live_exam_os/build.sh
index 2542af4917dfa2af6d7f0053460d86b3c5f073e3..ad54c3269337c951a2b6b6bcb9cb710145735a5b 100755
--- a/live_exam_os/build.sh
+++ b/live_exam_os/build.sh
@@ -15,6 +15,10 @@ export UBUNTU_VERSION="noble"
 export CHALLENGE="default_challenge"
 export ARCH="amd64"
 
+TMP_KERNEL=$(mktemp /tmp/vmlinuz.XXXXXX)
+TMP_INITRD=$(mktemp /tmp/initrd.XXXXXX)
+TMP_SQUASHFS_IMG=$(mktemp /tmp/squashfs_img.XXXXXX)
+
 helper() {
   echo "USAGE: $(basename "$0") [options]"
   echo
@@ -37,9 +41,9 @@ helper() {
   echo "  ROOTFS_DIR            Path to the temporary filesystem directory (e.g., out/rootfs)"
   echo "  ISO_DIR               Path to the temporary ISO directory (e.g., out/iso)"
   echo "  SERVER                IP of the nexus server (e.g., 127.0.0.1:1077)"
-  echo "  CERT 	                Path to the Certificate file 	(e.g., ca-cert.pem)"
-  echo "  EXAM_USER             Default user for exam client 	(e.g., user)" 
-  echo "  EXAM_PWD              Default password for exam client 	(e.g., password)"
+  echo "  CERT                  Path to the Certificate file    (e.g., ca-cert.pem)"
+  echo "  EXAM_USER             Default user for exam client    (e.g., user)"
+  echo "  EXAM_PWD              Default password for exam client        (e.g., password)"
   echo
   echo "Example Usage:"
   echo "  $(basename "$0") --env .env"
@@ -50,10 +54,15 @@ helper() {
 while [ "$#" -gt 0 ]; do
   case "$1" in
     --env)
-      source $2 > /dev/null
+      if [ -f "$2" ]; then
+        source "$2" > /dev/null
+      else
+        echo "Error: File '$2' not found." >&2
+        helper
+      fi
       shift 2
       ;;
-    --ouput)
+    --output)
       if [ -n "$2" ]; then
         export OUTPUT="$2"
         shift 2
@@ -67,7 +76,7 @@ while [ "$#" -gt 0 ]; do
         LUKS_PASSPHRASE="$2"
         shift 2
       else
-        echo "Error: --luks-keys requires an argument" >&2
+        echo "Error: --luks-passphrase requires an argument" >&2
         helper
       fi
       ;;
@@ -85,7 +94,7 @@ while [ "$#" -gt 0 ]; do
         CHALLENGE="$2"
         shift 2
       else
-        echo "Error: --luks-keys requires an argument" >&2
+        echo "Error: --challenge requires an argument" >&2
         helper
       fi
       ;;
@@ -98,21 +107,17 @@ while [ "$#" -gt 0 ]; do
         helper
       fi
       ;;
-    -v)
-      export VERBOSE=true
-      shift
-      ;;
     --ram)
       export RAM="squashfs_tmpfs"
       shift
       ;;
-    --verbose)
+    -v|--verbose)
       export VERBOSE=true
       shift
       ;;
     --cache)
       if [ -n "$2" ]; then
-        export CACHE_FS=$2
+        export CACHE_FS="$2"
         shift 2
       else
         echo "Error: --cache requires an argument" >&2
@@ -121,19 +126,19 @@ while [ "$#" -gt 0 ]; do
       ;;
     --version)
       if [ -n "$2" ]; then
-        export UBUNTU_VERSION=$2
+        export UBUNTU_VERSION="$2"
         shift 2
       else
-        echo "Error: --cache requires an argument" >&2
+        echo "Error: --version requires an argument" >&2
         helper
       fi
       ;;
     --arch)
       if [ -n "$2" ]; then
-        export ARCH=$2
+        export ARCH="$2"
         shift 2
       else
-        echo "Error: --cache requires an argument" >&2
+        echo "Error: --arch requires an argument" >&2
         helper
       fi
       ;;
@@ -144,151 +149,205 @@ while [ "$#" -gt 0 ]; do
   esac
 done
 
+check_inside_container
 check_environment_var
+check_dependencies
 CMDLINE="boot=nexus quiet splash $RAM modprobe.blacklist=floppy"
 
+echo "[Cleanup $ROOTFS_DIR]"
+ROOTFS_PATH="${ROOTFS_DIR%/}"
+child_mounts=$(findmnt -rn -o TARGET | grep -E "^${ROOTFS_PATH}/[^/]+$")
+
+if [ -n "$child_mounts" ]; then
+    echo "WARNING: The following mount points are directly under $ROOTFS_DIR:"
+    echo "$child_mounts"
+    echo
+    read -p "Do you want to unmount these mount points? [y/N]: " confirmation
+    case "$confirmation" in
+        [yY][eE][sS]|[yY])
+            while IFS= read -r mount_point; do
+                echo "Unmounting $mount_point..."
+                if ! umount "$mount_point"; then
+                    echo "Error: Failed to unmount $mount_point. Please unmount manually or reboot the system to avoid issues."
+                    exit 1
+                fi
+            done <<< "$child_mounts"
+            ;;
+        *)
+            echo "Cleanup aborted by user."
+            exit 1
+            ;;
+    esac
+fi
+run_command rm -rf "$ROOTFS_DIR"
+
+echo "[Cleanup $OUTPUT]"
+run_command rm -rf "$OUTPUT"
+
 echo "[Create filesystem...]"
-rm -rf "$ROOTFS_DIR" "$OUTPUT"
 mkdir -p "$ROOTFS_DIR"
 
-if [ -z $CACHE_FS ]; then
-  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
-  mount --rbind /run $ROOTFS_DIR/run
-  mount -t tmpfs tmpfs $ROOTFS_DIR/tmp
-  
-  
+if [ -z "$CACHE_FS" ]; then
+  run_command debootstrap --arch="$ARCH" "$UBUNTU_VERSION" "$ROOTFS_DIR" http://archive.ubuntu.com/ubuntu/
+  run_command mount -t proc /proc "$ROOTFS_DIR/proc"
+  run_command mount --rbind /sys "$ROOTFS_DIR/sys"
+  run_command mount --rbind /dev "$ROOTFS_DIR/dev"
+  run_command mount --rbind /run "$ROOTFS_DIR/run"
+  run_command mount -t tmpfs tmpfs "$ROOTFS_DIR/tmp"
+
   echo "[Installing packages...]"
   packages=$(tr '\n' ' ' < config/01-packages_install/packages)
-  echo "deb http://archive.ubuntu.com/ubuntu $UBUNTU_VERSION 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 $packages
-  check_exit_code $? "Error during packages installation"
+  run_command_chroot apt install -y --no-install-recommends "$packages"
 else
-  if [ ! -d $CACHE_FS ]; then
-    mkdir $CACHE_FS
-    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
-    mount --rbind /dev $CACHE_FS/dev
-    mount --rbind /run $CACHE_FS/run
-    mount -t tmpfs tmpfs $CACHE_FS/tmp
-    
-    
+  if [ ! -d "$CACHE_FS" ]; then
+    mkdir "$CACHE_FS"
+    run_command debootstrap --arch="$ARCH" "$UBUNTU_VERSION" "$CACHE_FS" http://archive.ubuntu.com/ubuntu/
+
+    run_command mount -t proc /proc "$CACHE_FS/proc"
+    run_command mount --rbind /sys "$CACHE_FS/sys"
+    run_command mount --rbind /dev "$CACHE_FS/dev"
+    run_command mount --rbind /run "$CACHE_FS/run"
+    run_command mount -t tmpfs tmpfs "$CACHE_FS/tmp"
+
     echo "[Installing packages...]"
     packages=$(tr '\n' ' ' < config/01-packages_install/packages)
-    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 $packages
-    check_exit_code $? "Error during packages installation"
-
-    umount -l $CACHE_FS/proc
-    umount -l $CACHE_FS/sys
-    umount -l $CACHE_FS/dev
-    umount -l $CACHE_FS/run
-    umount -l $CACHE_FS/tmp
+    echo "deb http://archive.ubuntu.com/ubuntu $UBUNTU_VERSION main universe" > "$CACHE_FS/etc/apt/sources.list"
+    run_command chroot "$CACHE_FS" apt update
+    run_command chroot "$CACHE_FS" apt install -y --no-install-recommends "$packages"
+
+    run_command umount -l "$CACHE_FS/proc"
+    run_command umount -l "$CACHE_FS/sys"
+    run_command umount -l "$CACHE_FS/dev"
+    run_command umount -l "$CACHE_FS/run"
+    run_command umount -l "$CACHE_FS/tmp"
   else
     echo " [Skip through cache]"
   fi
 
-  cp -r $CACHE_FS/* $ROOTFS_DIR
+  run_command cp -r "$CACHE_FS"/. "$ROOTFS_DIR"/
 
-  mount -t proc /proc $ROOTFS_DIR/proc
-  mount --rbind /sys $ROOTFS_DIR/sys
-  mount --rbind /dev $ROOTFS_DIR/dev
-  mount --rbind /run $ROOTFS_DIR/run
-  mount -t tmpfs tmpfs $ROOTFS_DIR/tmp
+  run_command mount -t proc /proc "$ROOTFS_DIR/proc"
+  run_command mount --rbind /sys "$ROOTFS_DIR/sys"
+  run_command mount --rbind /dev "$ROOTFS_DIR/dev"
+  run_command mount --rbind /run "$ROOTFS_DIR/run"
+  run_command mount -t tmpfs tmpfs "$ROOTFS_DIR/tmp"
 fi
 
 echo "[Uploading configuration file...]"
-cp -rf config/02-customisation/* $ROOTFS_DIR
+run_command cp -rf config/02-customisation/* "$ROOTFS_DIR"
+
+echo "[Checking for required dependencies...]"
+if [ ! -d "/opt/limine" ]; then
+  echo "Error: /opt/limine not found. Please install the Limine bootloader files in /opt/limine."
+  exit 1
+fi
+
+if [ ! -f "$ROOTFS_DIR/usr/lib/shim/shimx64.efi.signed.latest" ] || [ ! -f "$ROOTFS_DIR/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed" ]; then
+  echo "Error: Required EFI files not found in $ROOTFS_DIR."
+  exit 1
+fi
 
-if [ -z $PXE_URL ]; then
+if [ -z "$PXE_URL" ]; then
+  EFIBOOT=$(mktemp /tmp/efiboot.img.XXXXXX)
+  EFIBOOT_MOUNT=$(mktemp -d /tmp/efiboot.XXXXXX)
   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)
+  run_command mkdir -p "$ISO_DIR/boot/grub"
+  run_command "sed 's/CMDLINE/$CMDLINE/g' config/00-bootloader/grub.cfg > $ISO_DIR/boot/grub/grub.cfg"
+  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
+
+  run_command fallocate -l $(( $SIZE_EFIBOOT + $OFFSET)) "$EFIBOOT"
+  run_command mkfs.vfat "$EFIBOOT"
+  run_command mount -o loop "$EFIBOOT" "$EFIBOOT_MOUNT"
+  run_command mkdir -p "$EFIBOOT_MOUNT/EFI/BOOT"
+  run_command cp config/00-bootloader/grub.efi.cfg "$EFIBOOT_MOUNT/EFI/BOOT/grub.cfg"
+  run_command cp "$ROOTFS_DIR/usr/lib/shim/shimx64.efi.signed.latest" "$EFIBOOT_MOUNT/EFI/BOOT/BOOTx64.EFI"
+  run_command cp "$ROOTFS_DIR/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed" "$EFIBOOT_MOUNT/EFI/BOOT/grubx64.efi"
+  run_command umount "$EFIBOOT_MOUNT"
+  run_command rmdir "$EFIBOOT_MOUNT"
 fi
 
 echo "[Post-install...]"
 for script in config/03-post_install/*.sh; do
-  ./$script
+  ./"$script"
 done
 
 echo "[Moving kernel...]"
-cp $ROOTFS_DIR/boot/vmlinuz-* /tmp/vmlinuz
-cp $ROOTFS_DIR/boot/initrd.img /tmp/initrd
-rm -rf $ROOTFS_DIR/boot
+KERNEL_FILE=$(ls -1 "$ROOTFS_DIR/boot/vmlinuz-"* 2>/dev/null | head -n 1)
+if [ -z "$KERNEL_FILE" ]; then
+  echo "Error: No kernel file found in $ROOTFS_DIR/boot"
+  exit 1
+fi
+run_command cp "$KERNEL_FILE" "$TMP_KERNEL"
+run_command cp "$ROOTFS_DIR/boot/initrd.img" "$TMP_INITRD"
+run_command rm -rf "$ROOTFS_DIR/boot"
 
 echo "[Unmount subsystem...]"
-umount -l $ROOTFS_DIR/proc
-umount -l $ROOTFS_DIR/sys
-umount -l $ROOTFS_DIR/dev
-umount -l $ROOTFS_DIR/run
-umount -l $ROOTFS_DIR/tmp
+run_command umount -l "$ROOTFS_DIR/proc"
+run_command umount -l "$ROOTFS_DIR/sys"
+run_command umount -l "$ROOTFS_DIR/dev"
+run_command umount -l "$ROOTFS_DIR/run"
+run_command umount -l "$ROOTFS_DIR/tmp"
 
 echo "[Create squash.rootfs...]"
 run_command mksquashfs "$ROOTFS_DIR" "$SQUASHFS"
-check_exit_code $? "Error during squashfs generation"
 
-if [ ! -z $LUKS_PASSPHRASE ]; then
+if [ ! -z "$LUKS_PASSPHRASE" ]; then
   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
 
-  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
+  run_command fallocate -l "$TOTAL_SIZE" "$TMP_SQUASHFS_IMG"
+  run_command bash -c "cat <<EOF | cryptsetup luksFormat '$TMP_SQUASHFS_IMG' --batch-mode
+$LUKS_PASSPHRASE
+EOF"
+
+  run_command bash -c "cat <<EOF | cryptsetup luksOpen '$TMP_SQUASHFS_IMG' container
+$LUKS_PASSPHRASE
+EOF"
+  run_command dd if="$SQUASHFS" of=/dev/mapper/container bs=4M
+  run_command cryptsetup luksClose container
+
+  if [ ! -z "$ADDITIONAL_KEYS" ]; then
     for key in $ADDITIONAL_KEYS; do
-      echo -e "$LUKS_PASSPHRASE\n$key" | cryptsetup luksAddKey "/tmp/$SQUASHFS_IMG"
+      key_file=$(mktemp)
+      echo "$key" > "$key_file"
+      run_command bash -c "cat <<EOF | cryptsetup luksAddKey '$TMP_SQUASHFS_IMG'
+$LUKS_PASSPHRASE
+$key
+EOF"
+      rm -f "$key_file"
     done
   fi
 else
-  cp "$SQUASHFS" "/tmp/$SQUASHFS_IMG"
+  cp "$SQUASHFS" "$TMP_SQUASHFS_IMG"
 fi
 
-mkdir $OUTPUT
-if [ ! -z $PXE_URL ]; then
-  cp /tmp/vmlinuz $OUTPUT
-  cp /tmp/initrd $OUTPUT
-  cp /tmp/$SQUASHFS_IMG $OUTPUT
+mkdir "$OUTPUT"
+if [ ! -z "$PXE_URL" ]; then
+  run_command cp "$TMP_KERNEL" "$OUTPUT/vmlinuz"
+  run_command cp "$TMP_INITRD" "$OUTPUT/initrd"
+  run_command cp "$TMP_SQUASHFS_IMG" "$OUTPUT/$SQUASHFS_IMG"
+  run_command cp "$ROOTFS_DIR/usr/lib/shim/shimx64.efi.signed.latest" "$OUTPUT/BOOTx64.EFI"
+  run_command cp "$ROOTFS_DIR/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed" "$OUTPUT/grubx64.efi"
+  CMDLINE="boot=pxe quiet splash $RAM modprobe.blacklist=floppy"
+  run_command "sed 's/CMDLINE/$CMDLINE/g' config/00-bootloader/grub.cfg > $OUTPUT/grub.cfg"
 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
+  run_command mkdir -p "$BOOT_FOLDER"
+  run_command cp "$TMP_KERNEL" "$BOOT_FOLDER/vmlinuz"
+  run_command cp "$TMP_INITRD" "$BOOT_FOLDER/initrd"
 
   echo "[Create iso...]"
-  cp /tmp/$SQUASHFS_IMG $ISO_DIR/$SQUASHFS_IMG
-  cp /opt/limine/*.bin "$ISO_DIR/"
-  cp /opt/limine/*.sys "$ISO_DIR/"
-  cp $EFIBOOT $ISO_DIR
-  sed "s/CMDLINE/$CMDLINE/g" config/00-bootloader/limine.conf > "$ISO_DIR/boot/limine.conf"
-
+  run_command cp "$TMP_SQUASHFS_IMG" "$ISO_DIR/$SQUASHFS_IMG"
+  run_command cp /opt/limine/*.bin "$ISO_DIR/"
+  run_command cp /opt/limine/*.sys "$ISO_DIR/"
+  run_command cp "$EFIBOOT" "$ISO_DIR/efiboot.img"
+  run_command "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 "efiboot.img" \
@@ -296,8 +355,10 @@ else
         -volid "NEXUSCLIENTISO" \
         "$ISO_DIR" -o "$OUTPUT/$ISO_NAME"
 
-  check_exit_code $? "Error during iso creation"
   run_command limine bios-install "$OUTPUT/$ISO_NAME"
 fi
 
 chown -R 1000:1000 "$OUTPUT"
+
+echo "[Cleanup temporary files...]"
+rm -f "$TMP_KERNEL" "$TMP_INITRD" "$TMP_SQUASHFS_IMG" "$EFIBOOT"
diff --git a/live_exam_os/config/00-bootloader/isolinux.cfg b/live_exam_os/config/00-bootloader/isolinux.cfg
deleted file mode 100644
index 04d9d383eb14abcd1386584cd822dd8d4a837a82..0000000000000000000000000000000000000000
--- a/live_exam_os/config/00-bootloader/isolinux.cfg
+++ /dev/null
@@ -1,14 +0,0 @@
-menu hidden
-menu autoboot "Booting nexus-live-exam..."
-menu background black.png
-
-menu title nexus-live-exam
-include live.cfg
-menu disable
-menu end
-
-default vesamenu.c32
-
-prompt 0
-timeout 1
-totaltimeout 1
diff --git a/live_exam_os/config/00-bootloader/isolinux.png b/live_exam_os/config/00-bootloader/isolinux.png
deleted file mode 100644
index b15862c3c0f851040a62c96005861610bcc6214c..0000000000000000000000000000000000000000
Binary files a/live_exam_os/config/00-bootloader/isolinux.png and /dev/null differ
diff --git a/live_exam_os/config/01-build_hooks/wallpapers/wallpaper.png b/live_exam_os/config/01-build_hooks/wallpapers/wallpaper.png
deleted file mode 100644
index 32541088f322c3aace863efd3e9dc58075088036..0000000000000000000000000000000000000000
Binary files a/live_exam_os/config/01-build_hooks/wallpapers/wallpaper.png and /dev/null differ
diff --git a/live_exam_os/config/03-post_install/4000-firewall.sh b/live_exam_os/config/03-post_install/4000-firewall.sh
index f56281ab60469193195c3920dd7888b964e347d7..f0ef7e38e0eace8bd937faf281a8be4b01974117 100755
--- a/live_exam_os/config/03-post_install/4000-firewall.sh
+++ b/live_exam_os/config/03-post_install/4000-firewall.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 
 . tools/functions.sh
 
diff --git a/live_exam_os/config/03-post_install/8000-initramfs.sh b/live_exam_os/config/03-post_install/8000-initramfs.sh
index a7d37d5fefe63679acbff3a98f720d4237d8bf73..0c5e737be3e3460f5b3b1e5caad49651fab51610 100755
--- a/live_exam_os/config/03-post_install/8000-initramfs.sh
+++ b/live_exam_os/config/03-post_install/8000-initramfs.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 
 . tools/functions.sh
 
diff --git a/live_exam_os/tools/functions.sh b/live_exam_os/tools/functions.sh
index 0a945add858c7f1637233dc99b424adf8d1ffc86..1b6745a8455ee0b8d1604255e71c1f0a5229041a 100755
--- a/live_exam_os/tools/functions.sh
+++ b/live_exam_os/tools/functions.sh
@@ -1,3 +1,5 @@
+#/bin/bash
+
 run() {
   chroot "$ROOTFS_DIR" $@
 }
@@ -12,7 +14,7 @@ run_command() {
       bash -c "$cmd" > /dev/null 2>&1
       EXIT_CODE=$?
   fi
-  return $EXIT_CODE
+  check_exit_code $EXIT_CODE "Error durring command execution : $cmd"
 }
 
 run_command_chroot() {
@@ -23,7 +25,7 @@ check_exit_code() {
   EXIT_CODE=$1
   if [ ! $EXIT_CODE -eq 0 ]; then
     echo $2
-    exit
+    exit 1
   fi
 }
 
@@ -49,3 +51,29 @@ get_total_size() {
     done
     echo "$total"
 }
+
+check_inside_container() {
+  if [ ! -f "/.dockerenv" ] && [ ! -f "/run/.containerenv" ]; then
+    echo "Error: This script must be run inside a Docker or Podman container."
+    exit 1
+  fi
+}
+
+check_dependencies() {
+  local dependencies=(debootstrap chroot sed mount umount fallocate mkfs.vfat mksquashfs cryptsetup bash xorriso limine)
+  local missing=()
+
+  for cmd in "${dependencies[@]}"; do
+    if ! command -v "$cmd" >/dev/null 2>&1; then
+      missing+=("$cmd")
+    fi
+  done
+
+  if [ "${#missing[@]}" -ne 0 ]; then
+    echo "Error: The following required tools are missing or not in the PATH:" >&2
+    for tool in "${missing[@]}"; do
+      echo " - $tool" >&2
+    done
+    exit 1
+  fi
+}