From f7c44144cf84205c466e8c093e639a8583995716 Mon Sep 17 00:00:00 2001 From: ping <dev@guillaumepin.ch> Date: Tue, 7 Jan 2025 11:06:55 +0100 Subject: [PATCH] Refactor of live_exam_os for ubuntu --- live_exam_os/.env.example | 20 + live_exam_os/.gitignore | 4 +- live_exam_os/Dockerfile | 30 +- live_exam_os/Makefile | 45 +-- live_exam_os/README.md | 167 ++++---- live_exam_os/build.sh | 376 +++++++++--------- live_exam_os/config/00-bootloader/limine.cfg | 7 - live_exam_os/config/00-bootloader/limine.conf | 7 + .../config/00-bootloader/limine_casper.conf | 7 + .../config/00-bootloader/limine_pxe.conf | 7 + live_exam_os/config/01-initramfs/init | 55 --- live_exam_os/config/01-initramfs/init_no_luks | 53 --- .../config/01-packages_install/packages | 21 + .../NetworkManager/NetworkManager.conf.bak | 8 + .../conf.d/10-default-wired.conf.bak | 10 + .../conf.d/10-globally-managed-devices.conf | 0 .../etc/NetworkManager/conf.d/dns.conf.bak | 2 + .../wifi.nmconnection.example1 | 0 .../wifi.nmconnection.example2 | 0 .../config/02-customisation/etc/challenge | 1 + .../02-customisation/etc/default/keyboard | 10 + .../etc/initramfs-tools/hooks/nexus | 6 + .../etc/initramfs-tools/hooks/pxe | 9 + .../etc/initramfs-tools/hooks/yubikey | 7 + .../etc/initramfs-tools/scripts/init | 68 ++++ .../etc/initramfs-tools/scripts/pxe | 93 +++++ .../getty@tty1.service.d/autologin.conf | 3 + .../etc/xdg/autostart/nexus-exam.desktop | 0 .../xfce-perchannel-xml/xfce4-desktop.xml | 0 .../xfce-perchannel-xml/xfce4-panel.xml | 0 .../xfce4-power-manager.xml | 0 .../xfce4-settings-manager.xml | 0 .../xfconf/xfce-perchannel-xml/xfwm4.xml | 0 .../02-customisation/home/user/.profile | 5 + .../home/user/.xinitrc | 0 .../usr/local/bin/nexus-exam.desktop | 0 .../config/02-packages_install/packages | 3 - .../system-connections/wifi.nmconnection | 32 -- .../03-customisation/etc/default/keyboard | 10 - .../config/03-customisation/etc/inittab | 17 - .../03-customisation/home/user/.profile | 1 - .../03-post_install/1000-create-user.sh | 10 + .../03-post_install/1000-disable_root.sh | 6 + .../03-post_install/2000-enable_services.sh | 7 + .../config/03-post_install/3000-nexus_exam.sh | 17 + .../config/03-post_install/4000-firewall.sh | 16 + .../config/03-post_install/5000-pxe.sh | 8 + .../config/03-post_install/9999-initramfs.sh | 7 + .../04-post_install/1000-create-user.sh | 16 - .../04-post_install/1000-disable_root.sh | 8 - .../04-post_install/2000-enable_services.sh | 13 - .../config/04-post_install/9999-firewall.sh | 18 - live_exam_os/tools/functions.sh | 39 ++ 53 files changed, 708 insertions(+), 541 deletions(-) create mode 100644 live_exam_os/.env.example delete mode 100644 live_exam_os/config/00-bootloader/limine.cfg create mode 100644 live_exam_os/config/00-bootloader/limine.conf create mode 100644 live_exam_os/config/00-bootloader/limine_casper.conf create mode 100644 live_exam_os/config/00-bootloader/limine_pxe.conf delete mode 100644 live_exam_os/config/01-initramfs/init delete mode 100644 live_exam_os/config/01-initramfs/init_no_luks create mode 100644 live_exam_os/config/01-packages_install/packages create mode 100644 live_exam_os/config/02-customisation/etc/NetworkManager/NetworkManager.conf.bak create mode 100644 live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/10-default-wired.conf.bak create mode 100644 live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/10-globally-managed-devices.conf create mode 100644 live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/dns.conf.bak rename live_exam_os/config/{03-customisation => 02-customisation}/etc/NetworkManager/system-connections/wifi.nmconnection.example1 (100%) rename live_exam_os/config/{03-customisation => 02-customisation}/etc/NetworkManager/system-connections/wifi.nmconnection.example2 (100%) create mode 100644 live_exam_os/config/02-customisation/etc/challenge create mode 100644 live_exam_os/config/02-customisation/etc/default/keyboard create mode 100755 live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/nexus create mode 100755 live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/pxe create mode 100755 live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/yubikey create 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/pxe create mode 100644 live_exam_os/config/02-customisation/etc/systemd/system/getty@tty1.service.d/autologin.conf rename live_exam_os/config/{03-customisation => 02-customisation}/etc/xdg/autostart/nexus-exam.desktop (100%) rename live_exam_os/config/{03-customisation => 02-customisation}/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml (100%) rename live_exam_os/config/{03-customisation => 02-customisation}/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml (100%) rename live_exam_os/config/{03-customisation => 02-customisation}/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml (100%) rename live_exam_os/config/{03-customisation => 02-customisation}/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-settings-manager.xml (100%) rename live_exam_os/config/{03-customisation => 02-customisation}/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml (100%) create mode 100644 live_exam_os/config/02-customisation/home/user/.profile rename live_exam_os/config/{03-customisation => 02-customisation}/home/user/.xinitrc (100%) rename live_exam_os/config/{03-customisation => 02-customisation}/usr/local/bin/nexus-exam.desktop (100%) delete mode 100644 live_exam_os/config/02-packages_install/packages delete mode 100644 live_exam_os/config/03-customisation/etc/NetworkManager/system-connections/wifi.nmconnection delete mode 100644 live_exam_os/config/03-customisation/etc/default/keyboard delete mode 100644 live_exam_os/config/03-customisation/etc/inittab delete mode 100644 live_exam_os/config/03-customisation/home/user/.profile create mode 100755 live_exam_os/config/03-post_install/1000-create-user.sh create mode 100755 live_exam_os/config/03-post_install/1000-disable_root.sh create mode 100755 live_exam_os/config/03-post_install/2000-enable_services.sh create mode 100755 live_exam_os/config/03-post_install/3000-nexus_exam.sh create mode 100755 live_exam_os/config/03-post_install/4000-firewall.sh create mode 100755 live_exam_os/config/03-post_install/5000-pxe.sh create mode 100755 live_exam_os/config/03-post_install/9999-initramfs.sh delete mode 100755 live_exam_os/config/04-post_install/1000-create-user.sh delete mode 100755 live_exam_os/config/04-post_install/1000-disable_root.sh delete mode 100755 live_exam_os/config/04-post_install/2000-enable_services.sh delete mode 100755 live_exam_os/config/04-post_install/9999-firewall.sh create mode 100755 live_exam_os/tools/functions.sh diff --git a/live_exam_os/.env.example b/live_exam_os/.env.example new file mode 100644 index 0000000..c0e640d --- /dev/null +++ b/live_exam_os/.env.example @@ -0,0 +1,20 @@ +# Location of generated files +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" +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 VERBOSE=false +#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 9d78b0d..d8019d8 100644 --- a/live_exam_os/.gitignore +++ b/live_exam_os/.gitignore @@ -1,2 +1,4 @@ -output/ *.iso +.env +cache/ +config/02-customisation/etc/NetworkManager/system-connections/wifi.nmconnection diff --git a/live_exam_os/Dockerfile b/live_exam_os/Dockerfile index becfe63..c8909d9 100644 --- a/live_exam_os/Dockerfile +++ b/live_exam_os/Dockerfile @@ -1,25 +1,23 @@ -#ARG ALPINE_VERSION - ARG DEBIAN_FRONTEND=noninteractive -#FROM alpine:${ALPINE_VERSION} FROM ubuntu:22.04 -#RUN apk add mtools xorriso squashfs-tools cryptsetup e2fsprogs limine-x86_64 limine-cd - - +ENV archive=go1.22.6.linux-amd64.tar.gz +ENV PATH=$PATH:/usr/local/go/bin -RUN apt-get update && apt-get install -y gcc pkg-config git wget make ca-certificates libglfw3-dev libxcursor-dev libxinerama-dev libxi-dev libxxf86vm-dev upx-ucl +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 DEBIAN_FRONTEND=noninteractive apt install -y cryptsetup squashfs-tools -RUN apt install -y debootstrap schroot +RUN git clone https://github.com/limine-bootloader/limine.git --branch=v8.x-binary --depth=1 /opt/limine && \ + cd /opt/limine && \ + make && \ + cp /opt/limine/limine /bin/ -RUN git clone https://github.com/limine-bootloader/limine.git --branch=v8.x-binary --depth=1 /opt/limine +RUN wget https://go.dev/dl/$archive && tar -C /usr/local -xzf $archive -# Install go 1.22 from the official GO site -ENV archive=go1.22.6.linux-amd64.tar.gz -ENV PATH=$PATH:/usr/local/go/bin +WORKDIR /nexus -RUN wget https://go.dev/dl/$archive -RUN tar -C /usr/local -xzf $archive +RUN mkdir src +COPY src src +COPY Makefile . +COPY ca-cert.pem . -RUN apt install -y xorriso +RUN make build_nexus-exam SERVER="127.0.0.1:1077" CERT="ca-cert.pem" EXAM_USER="user" EXAM_PWD="pwd" diff --git a/live_exam_os/Makefile b/live_exam_os/Makefile index edc51ea..254f262 100644 --- a/live_exam_os/Makefile +++ b/live_exam_os/Makefile @@ -1,41 +1,20 @@ -image_name := builder_alpine_iso -alpine_version := "3.20.3" -iso_file := image.iso -output := output -squashfs_file := ${output}/squash.rootfs -root_fs := ${output}/rootfs -initrd_fs := ${output}/initrd -iso_path := ${output}/iso -server_ip := "127.0.0.1" -server_port := "1077" -cert := "ca-cert.pem" -exam_user := "user" -exam_pwd := "password" +image_name := builder_nexus_iso -all: build +all: build -build: build_container clean - sudo docker run -it --rm -v $(PWD)/..:/data --workdir /data/live_exam_os --privileged -e SQUASHFS=${squashfs_file} -e ROOTFS_DIR=${root_fs} -e INITRD_DIR=${initrd_fs} -e ISO_DIR=${iso_path} -e SERVER="${server_ip}:${server_port}" -e CERT=${cert} -e EXAM_USER=${exam_user} -e EXAM_PWD=${exam_pwd} ${image_name} ./build.sh ${iso_file} "123" --alpine-version ${alpine_version} --user-password "0" - sudo chown ${USER}:${USER} ${iso_file} +run: + sudo docker run -it --rm -v $(PWD)/..:/data --workdir /data/live_exam_os --privileged ${image_name} ./build.sh $(PARAM) -no_luks: build_container clean - sudo docker run -it --rm -v $(PWD)/..:/data --workdir /data/live_exam_os --privileged -e SQUASHFS=${squashfs_file} -e ROOTFS_DIR=${root_fs} -e INITRD_DIR=${initrd_fs} -e ISO_DIR=${iso_path} -e SERVER="${server_ip}:${server_port}" -e CERT=${cert} -e EXAM_USER=${exam_user} -e EXAM_PWD=${exam_pwd} ${image_name} ./build.sh ${iso_file} '' --no-luks --alpine-version ${alpine_version} --user-password "0" - sudo chown ${USER}:${USER} ${iso_file} - -build_container: - sudo docker build -t ${image_name} --build-arg ALPINE_VERSION=${alpine_version} . - -clean: - sudo rm -rf ${iso_file} ${output} - -uefi: - qemu-system-x86_64 -bios /usr/share/OVMF/x64/OVMF.fd -drive file=${iso_file},format=raw -boot d -m 16G -smp 4 -netdev user,id=n1 -device virtio-net-pci,netdev=n1 +build: + cd .. && sudo docker build -t ${image_name} -f live_exam_os/Dockerfile . bios: - qemu-system-x86_64 -drive file=${iso_file},format=raw -boot d -m 4G -smp 4 + qemu-system-x86_64 -drive file=$(ISO),format=raw -boot d -m 4G -smp 4 bios_cd: - qemu-system-x86_64 -drive file=${iso_file},media=cdrom,if=ide,readonly=on -boot d -m 4G -smp 4 + 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 -uefiserie: - qemu-system-x86_64 -bios /usr/share/OVMF/x64/OVMF.fd -drive file=${iso_file},format=raw -boot d -m 16G -smp 4 -netdev user,id=n1 -device virtio-net-pci,netdev=n1 -serial mon:stdio +.PHONY: build diff --git a/live_exam_os/README.md b/live_exam_os/README.md index 2a6989a..05ca500 100644 --- a/live_exam_os/README.md +++ b/live_exam_os/README.md @@ -1,103 +1,126 @@ -# live_exam_os +# Live Exam OS Builder -This project aims to create a minimal live operating system in the form of an ISO image, specifically designed for use on any computer. The generated ISO boots directly into a lightweight XFCE desktop environment and automatically launches the nexus-client. The focus is on simplicity, speed and portability. +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. -The ISO is based on Alpine Linux, known for its small footprint and security. LUKS encryption to secure the filesystem is enabled by default and can be disabled. +--- -## Features +## Usage - - Minimal ISO: Starts with a lightweight Alpine Linux base. - - Encryption: Utilizes LUKS encryption for securing the filesystem (optional). - - Desktop Environment: Configured for autologin with a minimal desktop environment. - - Nexus Client: Auto-launches the nexus-client at startup. - - Customizable: Flexible options for user credentials, Alpine version, and additional files. +To use the script, run it with the following command: -## Prerequisites - - - Docker: Used to containerize the build process. - - QEMU: Optional, for testing the generated ISO. - -## Environment Setup - -The build.sh script use several environment variables for flexibility: +```bash +./build.sh [options] +``` -| Variable | Description |Example| -|-|-|-| -| SQUASHFS | Path to SquashFS file | out/squash.rootfs | -| ROOTFS_DIR | Temporary root filesystem directory | out/rootfs | -| INITRD_DIR | Temporary initrd directory | out/initrd | -| ISO_DIR| Temporary ISO directory | out/iso | -| SERVER | Server details | 127.0.0.1:1077 | -| CERT| Path to Certificate file |ca-cert.pem | -| EXAM_USER| Default user for exam client| user | -| EXAM_PWD| Default password for exam client | password | +### Requirements -## build.sh Script +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. -The script build.sh generates the live ISO with various options for customization. +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. -### Syntax +### Options -./build.sh iso_output_path luks_passphrase [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. | +| `--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. | -### Required Arguments +### Environment Setup Parameters - - iso_output_path: Path to save the generated ISO image (e.g., out/iso/alpine.iso). - - luks_passphrase: Passphrase for LUKS encryption. Leave blank when using --no-luks. +| 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`). | -### Options +--- - - --no-luks: Disable LUKS encryption (makes luks_passphrase optional). - - --alpine-version: Specify Alpine Linux version (default: 3.20.3). - - --root-enabled: Enable root access (default: disabled). - - --root-password: Set the root password (ignored if root is disabled). - - --user-password: Set the default user password. +## Example Usage -### Example Usage - -#### With Encryption: +Here are some examples of how to use the script: +### Example 1 +Build an ISO image with LUKS encryption: ```bash -./build.sh out/iso/alpine.iso 'my_luks_pass' --alpine-version 3.16 --root-enabled yes --root-password 'rootpass' --user-password 'userpass' +./build.sh --env .env ``` -#### Without Encryption: +### Example 2 +Build an ISO image without LUKS encryption: ```bash -./build.sh out/iso/alpine.iso '' --no-luks --alpine-version 3.18 +./build.sh --output build --luks-passphrase 'my_luks_pass' --cache cache --pxe ``` +--- -## Usage Instructions -### Build the ISO +## Makefile Targets -The core ISO creation is handled by the script build.sh. For development, a Makefile is included to set up the environment and execute the script inside a Docker container. +The Makefile includes targets to facilitate the building, running, and testing processes. -#### Buld the ISO with encryption -Builds an encrypted ISO using LUKS with a default password of "123". -``` -make build -``` +### Available Targets -#### Build the ISO without encryption -``` -make no_luks -``` +| 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. | -### Testing the ISO +### Running Makefile Targets -After building the ISO, you can test it using QEMU: +1. **Build the Docker Image**: + ```bash + make build + ``` -#### UEFI Environment: -``` -make uefi -``` +2. **Run the Build Script**: + ```bash + make run PARAM="--env .env" + ``` -#### BIOS Environment: -``` -make bios -``` +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 + ``` -#### BIOS as CD-ROM: -``` -make bios_cd -``` +--- + +## Project Components + +### Scripts +- **build.sh**: Main script to build the ISO image and configure the environment. + +### 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. + +--- + +## 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`). diff --git a/live_exam_os/build.sh b/live_exam_os/build.sh index 9837640..f222c65 100755 --- a/live_exam_os/build.sh +++ b/live_exam_os/build.sh @@ -1,31 +1,32 @@ -#!/bin/sh +#!/bin/bash -ALPINE_VERSION="3.20.3" -ROOT_ENABLED="no" -LUKS_ENABLED="yes" -ROOT_PASSWORD="" -USER_PASSWORD="" -LUKS_IMG="squash.rootfs.luks" -BOOT_FOLDER="$ISO_DIR/boot" +. tools/functions.sh + +# Default variables +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" +export VERBOSE=false +export OUTPUT="." +export ISO_NAME="nexus.iso" helper() { - echo "USAGE: $(basename "$0") iso_output_path luks_passphrase [options]" - echo - echo "Required arguments:" - echo " iso_output_path Path where the generated ISO image will be saved (e.g., out/iso/alpine.iso)" - echo " luks_passphrase LUKS encryption passphrase for securing the filesystem" + echo "USAGE: $(basename "$0") [options]" echo echo "Options:" - echo " --no-luks Disable LUKS encryption (makes luks_passphrase optional)" - echo " --alpine-version Specify the Alpine Linux version to use (default: 3.20.3)" - echo " --root-enabled Enable root access (default: disabled)" - echo " --root-password Set the root password (ignored if root is disabled)" - echo " --user-password Set the default user password" + echo " -v, --verbose Set verbose mode" + echo " --env Path to an env file with all described parameters" + 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 " --cache Path to a folder with a clean fs already downloaded" echo echo "Environment Setup Parameters:" echo " SQUASHFS Path to the SquashFS file (e.g., out/squash.rootfs)" echo " ROOTFS_DIR Path to the temporary filesystem directory (e.g., out/rootfs)" - echo " INITRD_DIR Temporary directory for initrd (e.g., out/initrd)" 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)" @@ -33,88 +34,62 @@ helper() { echo " EXAM_PWD Default password for exam client (e.g., password)" echo echo "Example Usage:" - echo " $(basename "$0") out/iso/alpine.iso 'my_luks_pass' --alpine-version 3.16 --root-enabled yes --root-password 'rootpass' --user-password 'userpass'" - echo " $(basename "$0") out/iso/alpine.iso '' --no-luks --alpine-version 3.18" + echo " $(basename "$0") --env .env" + echo " $(basename "$0") --luks-passphrase mypassphrase --cache cache -v" exit 1 } -check_container_and_alpine_version() { - if [ ! -f "/.dockerenv" ] && [ ! -f "/run/.containerenv" ]; then - echo "Error: This script should be run inside a container environment on Alpine Linux version $ALPINE_VERSION." - helper - fi - - if [ -f "/etc/os-release" ]; then - . /etc/os-release - if [ "$ID" != "alpine" ] || [ "$VERSION_ID" != "$ALPINE_VERSION" ]; then - echo "Error: This script should be run inside a container environment on Alpine Linux version $ALPINE_VERSION." - echo "Actual version: $VERSION_ID" - helper - fi - else - echo "Error: This script should be run inside a container environment on Alpine Linux version $ALPINE_VERSION." - helper - fi -} - -check_environment_var() { - if [ -z $SQUASHFS ] || [ -z $ROOTFS_DIR ] || [ -z $INITRD_DIR ] || [ -z $ISO_DIR ]; then - echo "Error: Environment variables aren't set" - helper - fi -} - -run() { - chroot "$ROOTFS_DIR" $@ -} - -if [ "$#" -lt 2 ]; then - helper -fi - -ISO_OUTPUT_PATH="$1" -LUKS_PASSPHRASE="$2" -shift 2 - while [ "$#" -gt 0 ]; do case "$1" in - --no-luks) - LUKS_ENABLED="no" - shift + --env) + source $2 > /dev/null + shift 2 ;; - --alpine-version) + --ouput) if [ -n "$2" ]; then - ALPINE_VERSION="$2" + export OUTPUT="$2" shift 2 else - echo "Error: --alpine-version requires an argument" >&2 + echo "Error: --output requires an argument" >&2 helper fi ;; - --root-enabled) - if [ "$2" = "yes" ] || [ "$2" = "no" ]; then - ROOT_ENABLED="$2" + --luks-passphrase) + LUKS_PASSPHRASE="$2" + shit 2 + ;; + --luks-keys) + if [ -n "$2" ]; then + ADDITIONAL_KEYS="$2" shift 2 else - echo "Error: --root-enabled must be 'yes' or 'no'" >&2 + echo "Error: --luks-keys requires an argument" >&2 helper fi ;; - --root-password) + --pxe) if [ -n "$2" ]; then - ROOT_PASSWORD="$2" + export PXE_URL="$2" shift 2 else - echo "Error: --root-password requires an argument" >&2 + echo "Error: --pxe requires an argument" >&2 helper fi ;; - --user-password) + -v) + export VERBOSE=true + shift + ;; + --verbose) + export VERBOSE=true + shift + ;; + --cache) if [ -n "$2" ]; then - USER_PASSWORD="$2" + export CACHE_FS=$2 shift 2 else - echo "Error: --user-password requires an argument" >&2 + echo "Error: --cache requires an argument" >&2 helper fi ;; @@ -125,149 +100,178 @@ while [ "$#" -gt 0 ]; do esac done -if [ "$LUKS_ENABLED" = "yes" ] && [ -z "$LUKS_PASSPHRASE" ]; then - echo "Error: LUKS encryption is enabled, but no passphrase was provided." >&2 - helper -fi - -#check_container_and_alpine_version check_environment_var -#echo "[Compiling nexus-exam...]" -#cd .. -#make build_nexus-exam -#mkdir -p live_exam_os/$ROOTFS_DIR/usr/local/bin -#cp build/nexus-exam live_exam_os/$ROOTFS_DIR/usr/local/bin/nexus-exam -#make clean_client -#cd - - -echo "[Create initramfs...]" -rm -rf $INITRD_DIR -mkdir -p "$INITRD_DIR" -if [ "$LUKS_ENABLED" = "yes" ]; then - packages="busybox cryptsetup libblkid1 libuuid1 libdevmapper1.02.1 libcryptsetup12 \ - libargon2-1 libjson-c5 libudev1 kmod zlib1g xz-utils zstd" -else - packages="busybox libblkid1 libudev1 kmod zlib1g xz-utils zstd" -fi - -chmod 777 $INITRD_DIR - -cd $INITRD_DIR -for package in $packages; do - apt download "$package" --allow-unauthenticated -done - -for deb in *.deb; do - echo "$deb" - dpkg-deb -x "$deb" . - rm "$deb" -done -cd ../.. - - -#apk update -#if [ $LUKS_ENABLED = "yes" ]; then -# cp config/01-initramfs/init $INITRD_DIR/init -# packages="busybox musl cryptsetup cryptsetup-libs popt libuuid libblkid -# device-mapper-libs libcrypto3 argon2-libs json-c libeconf -# udev kmod-libs zlib xz-libs zstd-libs" -#else -# cp config/01-initramfs/init_no_luks $INITRD_DIR/init -# packages="busybox musl libblkid libeconf libcrypto3 -# udev kmod-libs zlib xz-libs zstd-libs" -#fi -#chmod +x $INITRD_DIR/init -#for package in $packages; do -# apk fetch -s "$package" > "$INITRD_DIR/$package.apk" -# tar -xzf "$INITRD_DIR/$package.apk" -C $INITRD_DIR -# rm "$INITRD_DIR/$package.apk" -#done echo "[Create filesystem...]" +rm -rf "$ROOTFS_DIR" "$OUTPUT" mkdir -p "$ROOTFS_DIR" -#apk add --initdb --root "$ROOTFS_DIR" -#cp /etc/apk/repositories "$ROOTFS_DIR/etc/apk/repositories" -echo "[Installing packages...]" -debootstrap --arch=amd64 focal $ROOTFS_DIR http://archive.ubuntu.com/ubuntu/ -chroot $ROOTFS_DIR /bin/bash -c " -apt update && -DEBIAN_FRONTEND=noninteractive apt install -y \$(cat config/02-packages_install/packages)" +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/ + 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 + + + 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 + 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 + 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/ + + 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 + + + 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 + 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 + 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 + else + echo "Skip through cache" + fi -echo "[Installing kernel...]" -chroot $ROOTFS_DIR /bin/bash -c " -apt update && -DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends linux-image-generic" -# && -#update-initramfs -c -k all" + cp -r $CACHE_FS/* $ROOTFS_DIR -#apk update --root "$ROOTFS_DIR" --allow-untrusted -#apk add --root "$ROOTFS_DIR" --allow-untrusted $(cat config/02-packages_install/packages) &>/dev/null -mkdir -p $INITRD_DIR/lib -cp -r $ROOTFS_DIR/lib/modules $INITRD_DIR/lib/ + 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 +fi echo "[Uploading configuration file...]" -cd config/03-customisation -cp -R --parents * ../../$ROOTFS_DIR -cd ../.. +cp -rf config/02-customisation/* $ROOTFS_DIR echo "[Post-install...]" -for script in config/04-post_install/*.sh; do +for script in config/03-post_install/*.sh; do ./$script done -echo "[Moving kernel from rootfs to iso/boot...]" -mkdir -p $BOOT_FOLDER -cp $ROOTFS_DIR/boot/vmlinuz-* $BOOT_FOLDER +echo "[Moving kernel..]" +cp $ROOTFS_DIR/boot/vmlinuz-* /tmp/vmlinuz +cp $ROOTFS_DIR/boot/initrd.img /tmp/initrd rm -rf $ROOTFS_DIR/boot -echo "[Create initrd...]" -mkdir -p "$INITRD_DIR/usr/bin" -chroot "$INITRD_DIR" /bin/busybox --install -TMP_PWD=$(pwd) -cd $INITRD_DIR -find . | cpio -R root:root -H newc -o | gzip > $TMP_PWD/$BOOT_FOLDER/initrd -cd $TMP_PWD +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 echo "[Create squash.rootfs..]" -mksquashfs "$ROOTFS_DIR" "$SQUASHFS" &>/dev/null +run_command mksquashfs "$ROOTFS_DIR" "$SQUASHFS" +check_exit_code $? "Error during squashfs generation" -if [ $LUKS_ENABLED = "yes" ]; 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 TOTAL_SIZE=$(( (TOTAL_SIZE + SECTOR_SIZE - 1) / SECTOR_SIZE * SECTOR_SIZE )) - - fallocate -l $TOTAL_SIZE "$ISO_DIR/$LUKS_IMG" - - echo -n "$LUKS_PASSPHRASE" | cryptsetup luksFormat "$ISO_DIR/$LUKS_IMG" --batch-mode - echo -n "$LUKS_PASSPHRASE" | cryptsetup luksOpen "$ISO_DIR/$LUKS_IMG" container - dd if="$SQUASHFS" of=/dev/mapper/container bs=4M - + + 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 + 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" + done + fi else - cp "$SQUASHFS" "$ISO_DIR/squash.rootfs" + mkdir -p $ISO_DIR/casper + cp "$SQUASHFS" "$ISO_DIR/casper/filesystem.squashfs" fi +mkdir $OUTPUT +if [ ! -z $PXE_URL ];then + cp /tmp/vmlinuz $OUTPUT + cp /tmp/initrd $OUTPUT + cp /tmp/$LUKS_IMG $OUTPUT -echo "[Create iso...]" + echo "[Moving kernel to iso/boot...]" + mkdir -p $BOOT_FOLDER + cp /tmp/vmlinuz $BOOT_FOLDER/vmlinuz + cp /tmp/initrd $BOOT_FOLDER/initrd -mkdir -p "$ISO_DIR/EFI/BOOT" - -cp /opt/limine/BOOTX64.EFI "$ISO_DIR/EFI/BOOT/" -cp /opt/limine/*.bin "$ISO_DIR/" -cp /opt/limine/*.sys "$ISO_DIR/" + 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" +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 -cp config/00-bootloader/limine.cfg "$ISO_DIR/limine.cfg" + 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/" + + 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 -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 image.iso + 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" +fi -#limine bios-install image.iso +chown -R 1000:1000 "$OUTPUT" diff --git a/live_exam_os/config/00-bootloader/limine.cfg b/live_exam_os/config/00-bootloader/limine.cfg deleted file mode 100644 index 485a990..0000000 --- a/live_exam_os/config/00-bootloader/limine.cfg +++ /dev/null @@ -1,7 +0,0 @@ -TIMEOUT=0 - -:AlpineLinux - PROTOCOL=linux - KERNEL_PATH=boot:///boot/vmlinuz-5.4.0-26-generic - KERNEL_CMDLINE=quiet console=ttyS0 - MODULE_PATH=boot:///boot/initrd diff --git a/live_exam_os/config/00-bootloader/limine.conf b/live_exam_os/config/00-bootloader/limine.conf new file mode 100644 index 0000000..a2004d6 --- /dev/null +++ b/live_exam_os/config/00-bootloader/limine.conf @@ -0,0 +1,7 @@ +timeout: 0 + +/Nexus + protocol: linux + kernel_path: boot():/boot/vmlinuz + kernel_cmdline: boot=nexus quiet splash + 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 new file mode 100644 index 0000000..853c8c8 --- /dev/null +++ b/live_exam_os/config/00-bootloader/limine_casper.conf @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000..653cf3a --- /dev/null +++ b/live_exam_os/config/00-bootloader/limine_pxe.conf @@ -0,0 +1,7 @@ +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-initramfs/init b/live_exam_os/config/01-initramfs/init deleted file mode 100644 index 706064b..0000000 --- a/live_exam_os/config/01-initramfs/init +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh -echo "Starting Nexus client..." -dmesg -n 1 - -mkdir -p /dev /proc /sys /tmp -mount -t devtmpfs none /dev -mount -t proc none /proc -mount -t sysfs none /sys -mount -t tmpfs none /tmp -mkdir -p /dev/pts -mount -t devpts none /dev/pts - -modprobe simpledrm -modprobe usbcore -modprobe usb_storage -modprobe usb_common -modprobe uas -modprobe scsi_mod -modprobe sr_mod -modprobe sd_mod -modprobe xhci_pci -modprobe xhci_hcd -modprobe ata_piix -modprobe cdrom -modprobe loop - -/bin/sh - -udevadm trigger - -echo "Mounting cdrom..." -while [ -z $(blkid | grep "NEXUSCLIENTISO" | cut -d ':' -f1) ]; do - echo -n "" -done - -DISK=$(blkid | grep "NEXUSCLIENTISO" | cut -d ':' -f1) -mkdir -p /cdrom -mount -t iso9660 $DISK /cdrom - -cryptsetup open /cdrom/squash.rootfs.luks data - -echo "Mounting overlay..." -mkdir -p /squash /upper/lib /work /newroot -mount -t squashfs /dev/mapper/data /squash -cp -r /lib/modules /upper/lib - -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 diff --git a/live_exam_os/config/01-initramfs/init_no_luks b/live_exam_os/config/01-initramfs/init_no_luks deleted file mode 100644 index 32d7ecb..0000000 --- a/live_exam_os/config/01-initramfs/init_no_luks +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh -echo "Starting Nexus client..." -dmesg -n 1 - -mkdir -p /dev /proc /sys /tmp -mount -t devtmpfs none /dev -mount -t proc none /proc -mount -t sysfs none /sys -mount -t tmpfs none /tmp -mkdir -p /dev/pts -mount -t devpts none /dev/pts - -modprobe simpledrm -modprobe usbcore -modprobe usb_storage -modprobe usb_common -modprobe uas -modprobe scsi_mod -modprobe sr_mod -modprobe sd_mod -modprobe xhci_pci -modprobe xhci_hcd -modprobe ata_piix -modprobe cdrom -modprobe loop - -udevadm trigger - -echo "Mounting cdrom..." -while [ -z $(blkid | grep "NEXUSCLIENTISO" | cut -d ':' -f1) ]; do - echo -n "" -done - -DISK=$(blkid | grep "NEXUSCLIENTISO" | cut -d ':' -f1) -mkdir -p /cdrom -mount -t iso9660 $DISK /cdrom - -/bin/sh - -echo "Mounting overlay..." -mkdir -p /squash /upper/lib /work /newroot -mount -t squashfs /cdrom/squash.rootfs /squash -cp -r /lib/modules /upper/lib - -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 diff --git a/live_exam_os/config/01-packages_install/packages b/live_exam_os/config/01-packages_install/packages new file mode 100644 index 0000000..f60d5f3 --- /dev/null +++ b/live_exam_os/config/01-packages_install/packages @@ -0,0 +1,21 @@ +udev +network-manager +xserver-xorg +xserver-xorg-input-libinput +xinit +xfce4 +xfce4-terminal +systemd +policykit-1 +adwaita-icon-theme +dbus +dbus-x11 +virt-viewer +mesa-va-drivers +iptables +ufw +sudo +vim +rfkill +wpasupplicant +yubikey-personalization 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 new file mode 100644 index 0000000..06c5d59 --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/NetworkManager/NetworkManager.conf.bak @@ -0,0 +1,8 @@ +[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 new file mode 100644 index 0000000..5582524 --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/10-default-wired.conf.bak @@ -0,0 +1,10 @@ +[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/10-globally-managed-devices.conf b/live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/10-globally-managed-devices.conf new file mode 100644 index 0000000..e69de29 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 new file mode 100644 index 0000000..d435aba --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/NetworkManager/conf.d/dns.conf.bak @@ -0,0 +1,2 @@ +[main] +dns=none diff --git a/live_exam_os/config/03-customisation/etc/NetworkManager/system-connections/wifi.nmconnection.example1 b/live_exam_os/config/02-customisation/etc/NetworkManager/system-connections/wifi.nmconnection.example1 similarity index 100% rename from live_exam_os/config/03-customisation/etc/NetworkManager/system-connections/wifi.nmconnection.example1 rename to live_exam_os/config/02-customisation/etc/NetworkManager/system-connections/wifi.nmconnection.example1 diff --git a/live_exam_os/config/03-customisation/etc/NetworkManager/system-connections/wifi.nmconnection.example2 b/live_exam_os/config/02-customisation/etc/NetworkManager/system-connections/wifi.nmconnection.example2 similarity index 100% rename from live_exam_os/config/03-customisation/etc/NetworkManager/system-connections/wifi.nmconnection.example2 rename to live_exam_os/config/02-customisation/etc/NetworkManager/system-connections/wifi.nmconnection.example2 diff --git a/live_exam_os/config/02-customisation/etc/challenge b/live_exam_os/config/02-customisation/etc/challenge new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/challenge @@ -0,0 +1 @@ +test diff --git a/live_exam_os/config/02-customisation/etc/default/keyboard b/live_exam_os/config/02-customisation/etc/default/keyboard new file mode 100644 index 0000000..c7fe671 --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/default/keyboard @@ -0,0 +1,10 @@ +# KEYBOARD CONFIGURATION FILE + +# Consult the keyboard(5) manual page. + +#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 new file mode 100755 index 0000000..e1a61da --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/nexus @@ -0,0 +1,6 @@ +#!/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 new file mode 100755 index 0000000..887c32d --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/pxe @@ -0,0 +1,9 @@ +#!/bin/sh +set -e + +. /usr/share/initramfs-tools/hook-functions + +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/hooks/yubikey b/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/yubikey new file mode 100755 index 0000000..56bc51d --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/initramfs-tools/hooks/yubikey @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e +. /usr/share/initramfs-tools/hook-functions + +copy_exec /usr/bin/ykchalresp /bin/ykchalresp +copy_exec /etc/challenge /scripts/challenge 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 new file mode 100755 index 0000000..337eeb8 --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/init @@ -0,0 +1,68 @@ +#!/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/pxe b/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/pxe new file mode 100755 index 0000000..6579225 --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/initramfs-tools/scripts/pxe @@ -0,0 +1,93 @@ +#!/bin/sh + +LUKS_FILE="/squash.rootfs" + +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" +} + +sleep 3 + +echo "DHCP lookup..." +find_active_interface + +wget $(cat /squashfs-url) -O $LUKS_FILE + +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/systemd/system/getty@tty1.service.d/autologin.conf b/live_exam_os/config/02-customisation/etc/systemd/system/getty@tty1.service.d/autologin.conf new file mode 100644 index 0000000..9712e76 --- /dev/null +++ b/live_exam_os/config/02-customisation/etc/systemd/system/getty@tty1.service.d/autologin.conf @@ -0,0 +1,3 @@ +[Service] +ExecStart= +ExecStart=-/sbin/agetty -o '-p -f -- \\u' --noclear --autologin user %I $TERM diff --git a/live_exam_os/config/03-customisation/etc/xdg/autostart/nexus-exam.desktop b/live_exam_os/config/02-customisation/etc/xdg/autostart/nexus-exam.desktop similarity index 100% rename from live_exam_os/config/03-customisation/etc/xdg/autostart/nexus-exam.desktop rename to live_exam_os/config/02-customisation/etc/xdg/autostart/nexus-exam.desktop diff --git a/live_exam_os/config/03-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml b/live_exam_os/config/02-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml similarity index 100% rename from live_exam_os/config/03-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml rename to live_exam_os/config/02-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml diff --git a/live_exam_os/config/03-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml b/live_exam_os/config/02-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml similarity index 100% rename from live_exam_os/config/03-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml rename to live_exam_os/config/02-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml diff --git a/live_exam_os/config/03-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml b/live_exam_os/config/02-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml similarity index 100% rename from live_exam_os/config/03-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml rename to live_exam_os/config/02-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml diff --git a/live_exam_os/config/03-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-settings-manager.xml b/live_exam_os/config/02-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-settings-manager.xml similarity index 100% rename from live_exam_os/config/03-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-settings-manager.xml rename to live_exam_os/config/02-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-settings-manager.xml diff --git a/live_exam_os/config/03-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml b/live_exam_os/config/02-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml similarity index 100% rename from live_exam_os/config/03-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml rename to live_exam_os/config/02-customisation/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml diff --git a/live_exam_os/config/02-customisation/home/user/.profile b/live_exam_os/config/02-customisation/home/user/.profile new file mode 100644 index 0000000..9992ad7 --- /dev/null +++ b/live_exam_os/config/02-customisation/home/user/.profile @@ -0,0 +1,5 @@ +while [ ! -e /dev/dri/card* ]; do + sleep 1 +done + +startx diff --git a/live_exam_os/config/03-customisation/home/user/.xinitrc b/live_exam_os/config/02-customisation/home/user/.xinitrc similarity index 100% rename from live_exam_os/config/03-customisation/home/user/.xinitrc rename to live_exam_os/config/02-customisation/home/user/.xinitrc diff --git a/live_exam_os/config/03-customisation/usr/local/bin/nexus-exam.desktop b/live_exam_os/config/02-customisation/usr/local/bin/nexus-exam.desktop similarity index 100% rename from live_exam_os/config/03-customisation/usr/local/bin/nexus-exam.desktop rename to live_exam_os/config/02-customisation/usr/local/bin/nexus-exam.desktop diff --git a/live_exam_os/config/02-packages_install/packages b/live_exam_os/config/02-packages_install/packages deleted file mode 100644 index 7d571e7..0000000 --- a/live_exam_os/config/02-packages_install/packages +++ /dev/null @@ -1,3 +0,0 @@ -linux-generic -linux-firmware -ubuntu-minimal diff --git a/live_exam_os/config/03-customisation/etc/NetworkManager/system-connections/wifi.nmconnection b/live_exam_os/config/03-customisation/etc/NetworkManager/system-connections/wifi.nmconnection deleted file mode 100644 index 2cfd7e7..0000000 --- a/live_exam_os/config/03-customisation/etc/NetworkManager/system-connections/wifi.nmconnection +++ /dev/null @@ -1,32 +0,0 @@ -# On a Debian/Ubuntu system, NetworkManager's WIFI connection files are located in /etc/NetworkManager/system-connections - -[connection] -# Name of the connection as shown by Network Manager -id=example1 -# Random UUID referencing the connection -uuid=8a065b14-beb3-4f28-97b5-f560c368ae12 -type=wifi - -[wifi] -# Whether the SSID is hidden or not (true/false) -hidden=false -# Name of the WIFI SSID -ssid=the_empire_strickes_back - -[wifi-security] -key-mgmt=wpa-eap - -[802-1x] -eap=peap; -identity=luke_skywalker -password=you_are_not_ready_young_padawan -phase2-auth=mschapv2 - -[ipv4] -method=auto - -[ipv6] -addr-gen-mode=stable-privacy -method=auto - -[proxy] diff --git a/live_exam_os/config/03-customisation/etc/default/keyboard b/live_exam_os/config/03-customisation/etc/default/keyboard deleted file mode 100644 index ad849b1..0000000 --- a/live_exam_os/config/03-customisation/etc/default/keyboard +++ /dev/null @@ -1,10 +0,0 @@ -# KEYBOARD CONFIGURATION FILE - -# Consult the keyboard(5) manual page. - -XKBMODEL="pc105" -XKBLAYOUT="ch" -XKBVARIANT="fr" -XKBOPTIONS="" - -BACKSPACE="guess" diff --git a/live_exam_os/config/03-customisation/etc/inittab b/live_exam_os/config/03-customisation/etc/inittab deleted file mode 100644 index 37a0b90..0000000 --- a/live_exam_os/config/03-customisation/etc/inittab +++ /dev/null @@ -1,17 +0,0 @@ -# /etc/inittab - -::sysinit:/sbin/openrc sysinit -::sysinit:/sbin/openrc boot -::wait:/sbin/openrc default - -# Set up a couple of getty's -tty1::respawn:/sbin/agetty --autologin user tty1 linux - -# Put a getty on the serial port -#ttyS0::respawn:/sbin/getty -L 115200 ttyS0 vt100 - -# Stuff to do for the 3-finger salute -::ctrlaltdel:/sbin/reboot - -# Stuff to do before rebooting -::shutdown:/sbin/openrc shutdown diff --git a/live_exam_os/config/03-customisation/home/user/.profile b/live_exam_os/config/03-customisation/home/user/.profile deleted file mode 100644 index a3393c0..0000000 --- a/live_exam_os/config/03-customisation/home/user/.profile +++ /dev/null @@ -1 +0,0 @@ -startx diff --git a/live_exam_os/config/03-post_install/1000-create-user.sh b/live_exam_os/config/03-post_install/1000-create-user.sh new file mode 100755 index 0000000..d46fd38 --- /dev/null +++ b/live_exam_os/config/03-post_install/1000-create-user.sh @@ -0,0 +1,10 @@ +#/bin/bash + +. tools/functions.sh + +echo " [User managing...]" +run_command_chroot useradd -m user +run_command_chroot usermod -aG video user +run_command_chroot usermod -aG input user +run_command_chroot usermod -aG plugdev user +run_command_chroot chown -R 1000:1000 /home/user/ diff --git a/live_exam_os/config/03-post_install/1000-disable_root.sh b/live_exam_os/config/03-post_install/1000-disable_root.sh new file mode 100755 index 0000000..5187b34 --- /dev/null +++ b/live_exam_os/config/03-post_install/1000-disable_root.sh @@ -0,0 +1,6 @@ +#/bin/sh + +. tools/functions.sh + +echo " [Disable root user...]" +run_command_chroot passwd -l root diff --git a/live_exam_os/config/03-post_install/2000-enable_services.sh b/live_exam_os/config/03-post_install/2000-enable_services.sh new file mode 100755 index 0000000..a596813 --- /dev/null +++ b/live_exam_os/config/03-post_install/2000-enable_services.sh @@ -0,0 +1,7 @@ +#/bin/sh + +. tools/functions.sh + +echo " [Enabling services...]" +run_command_chroot systemctl enable NetworkManager +run_command_chroot systemctl enable ufw 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 new file mode 100755 index 0000000..5d80457 --- /dev/null +++ b/live_exam_os/config/03-post_install/3000-nexus_exam.sh @@ -0,0 +1,17 @@ +#/bin/bash + +. tools/functions.sh + +echo " [Compiling nexus-exam...]" +cd .. +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 + mkdir -p live_exam_os/$ROOTFS_DIR/usr/local/bin + cp build/nexus-exam live_exam_os/$ROOTFS_DIR/usr/local/bin/nexus-exam +else + mkdir -p $ROOTFS_DIR/usr/local/bin + cp build/nexus-exam $ROOTFS_DIR/usr/local/bin/nexus-exam +fi +make clean_client +cd - diff --git a/live_exam_os/config/03-post_install/4000-firewall.sh b/live_exam_os/config/03-post_install/4000-firewall.sh new file mode 100755 index 0000000..f56281a --- /dev/null +++ b/live_exam_os/config/03-post_install/4000-firewall.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. tools/functions.sh + +IP_SERVER=$(echo $SERVER | cut -d ':' -f1) +PORT_SERVER=$(echo $SERVER | cut -d ':' -f2) + +echo " [Firewall configuration...]" + +run_command_chroot ufw default deny incoming +run_command_chroot ufw default deny outgoing +run_command_chroot ufw allow out from any to $IP_SERVER port $PORT_SERVER proto tcp +run_command_chroot ufw allow out from any to any port 123 proto udp +run_command_chroot ufw allow out from any to any port 53 proto udp +run_command_chroot ufw allow out from any to $IP_SERVER port 1025:65535 proto tcp +run_command_chroot ufw enable diff --git a/live_exam_os/config/03-post_install/5000-pxe.sh b/live_exam_os/config/03-post_install/5000-pxe.sh new file mode 100755 index 0000000..ecf5afd --- /dev/null +++ b/live_exam_os/config/03-post_install/5000-pxe.sh @@ -0,0 +1,8 @@ +#/bin/bash + +. tools/functions.sh + +if [ ! -z $PXE_URL ]; then + echo " [Adding PXE url...]" + echo -n "$PXE_URL/$LUKS_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/9999-initramfs.sh new file mode 100755 index 0000000..a7d37d5 --- /dev/null +++ b/live_exam_os/config/03-post_install/9999-initramfs.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +. tools/functions.sh + +echo " [Update initramfs...]" +run_command_chroot update-initramfs -u +check_exit_code $? "Error during initramfs generation" diff --git a/live_exam_os/config/04-post_install/1000-create-user.sh b/live_exam_os/config/04-post_install/1000-create-user.sh deleted file mode 100755 index 8fa722d..0000000 --- a/live_exam_os/config/04-post_install/1000-create-user.sh +++ /dev/null @@ -1,16 +0,0 @@ -#/bin/sh - -run() { - chroot "$ROOTFS_DIR" $@ -} - -echo "[User managing...]" -run useradd -m user -run usermod -aG video user -run usermod -aG input user -run usermod -aG plugdev user -run usermod -aG wheel user -chown -R 1000:1000 $ROOTFS_DIR/home/user/ -USER_PASSWORD="0" -echo "user:$USER_PASSWORD" | chroot "$ROOTFS_DIR" /usr/sbin/chpasswd -echo "%wheel ALL=(ALL:ALL) ALL" >> "$ROOTFS_DIR/etc/sudoers.d/wheel" diff --git a/live_exam_os/config/04-post_install/1000-disable_root.sh b/live_exam_os/config/04-post_install/1000-disable_root.sh deleted file mode 100755 index 24518d1..0000000 --- a/live_exam_os/config/04-post_install/1000-disable_root.sh +++ /dev/null @@ -1,8 +0,0 @@ -#/bin/sh - -run() { - chroot "$ROOTFS_DIR" $@ -} - -echo "[Disable root user...]" -run passwd -l root diff --git a/live_exam_os/config/04-post_install/2000-enable_services.sh b/live_exam_os/config/04-post_install/2000-enable_services.sh deleted file mode 100755 index 7c05faa..0000000 --- a/live_exam_os/config/04-post_install/2000-enable_services.sh +++ /dev/null @@ -1,13 +0,0 @@ -#/bin/sh - -run() { - chroot "$ROOTFS_DIR" $@ -} - -echo "[Enabling services...]" -run rc-update add dbus -run setup-devd udev -run rc-update add polkit -run rc-update add elogind -run rc-update add networkmanager -run rc-update add ufw diff --git a/live_exam_os/config/04-post_install/9999-firewall.sh b/live_exam_os/config/04-post_install/9999-firewall.sh deleted file mode 100755 index ead64fa..0000000 --- a/live_exam_os/config/04-post_install/9999-firewall.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -IP_SERVER=$(echo $SERVER | cut -d ':' -f1) -PORT_SERVER=$(echo $SERVER | cut -d ':' -f2) - -run() { - chroot "$ROOTFS_DIR" $@ -} - -echo "[Firewall configuration...]" - -run ufw default deny incoming -run ufw default deny outgoing -run ufw allow out from any to $IP_SERVER port $PORT_SERVER proto tcp -run ufw allow out from any to any port 123 proto udp -run ufw allow out from any to any port 53 proto udp -run ufw allow out from any to $IP_SERVER port 1025:65535 proto tcp -run ufw enable diff --git a/live_exam_os/tools/functions.sh b/live_exam_os/tools/functions.sh new file mode 100755 index 0000000..ad9b113 --- /dev/null +++ b/live_exam_os/tools/functions.sh @@ -0,0 +1,39 @@ +run() { + chroot "$ROOTFS_DIR" $@ +} + +run_command() { + local cmd="$@" + if $VERBOSE; then + echo $cmd + bash -c "$cmd" + EXIT_CODE=$? + else + bash -c "$cmd" > /dev/null 2>&1 + EXIT_CODE=$? + fi + return $EXIT_CODE +} + +run_command_chroot() { + run_command chroot "$ROOTFS_DIR" $@ +} + +check_exit_code() { + EXIT_CODE=$1 + if [ ! $EXIT_CODE -eq 0 ]; then + echo $2 + exit + fi +} + +check_environment_var() { + if [ -z $SERVER ] || [ -z $CERT ] || [ -z $EXAM_USER ] || [ -z $EXAM_PWD ]; then + echo "Error: Environment variables aren't set" + echo "SERVER = $SERVER" + echo "CERT = $CERT" + echo "EXAM_USER = $EXAM_USER" + echo "EXAM_PWD = $EXAM_PWD" + helper + fi +} -- GitLab