#!/bin/bash # SPDX-Version: 3.0 # SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; # SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.installer.git # SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency # SPDX-FileCopyrightText: 2024-2025; WEIDNER, Marc S.; # SPDX-FileType: SOURCE # SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0 # SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework. # SPDX-PackageName: CISS.debian.installer # SPDX-Security-Contact: security@coresecret.eu ### Contributions so far see ./docs/CREDITS.md ### WHY BASH? # Ease of installation. No compiling or installing gems, CPAN modules, pip packages, etc. Simple to use and read. Clear syntax # and straightforward output interpretation. Built-in power. Pattern matching, line processing, and regular expression support # are available natively, no external binaries required. Cross-platform consistency. '/bin/bash' is the default shell on most # Linux distributions, ensuring scripts run unmodified across systems. macOS compatibility. Since macOS Catalina (10.15), the # default login shell has been zsh, but bash remains available at '/bin/bash'. Windows support. You can use bash via WSL, MSYS2, # or Cygwin on Windows systems. ### CATCH ARGUMENTS AND DECLARE BASIC VARIABLES. # shellcheck disable=SC2155 declare -grx VAR_PARAM_COUNT="$#" # Arguments passed to script. declare -grx VAR_PARAM_STRNG="$*" # Arguments passed to script as string. declare -ag ARY_PARAM_ARRAY=("$@") # Arguments passed to script as an array. declare -grx VAR_SETUP_FILE="${0##*/}" # 'setup.sh' declare -grx VAR_SETUP_PATH="$(cd "$(dirname "${0}")" && pwd)" # '/opt/git/CISS.debian.installer' declare -grx VAR_SETUP_FULL="$(cd "$(dirname "${0}")" && pwd)/${0##*/}" # '/opt/git/CISS.debian.installer/setup.sh' ### PRELIMINARY CHECKS. ### No ash, dash, ksh, sh, zsh. # shellcheck disable=2292 [ -z "${BASH_VERSINFO[0]}" ] && { . ./meta_loader_early.sh printf "%b❌ Please make sure you are using 'bash'! Bye... %b%b" "${RED}" "${RES}" "${NL}" >&2 exit "${ERR_UNSUPPORTED_BASH}" } ### Not root. [[ ${EUID} -ne 0 ]] && { . ./meta_loader_early.sh printf "%b❌ Please make sure you are 'root'! Bye... %b%b" "${RED}" "${RES}" "${NL}" >&2 exit "${ERR_USER_IS_NOT_ROOT}" } ### Not called by sh. # shellcheck disable=2312 [[ $(kill -l | grep -c SIG) -eq 0 ]] && { . ./meta_loader_early.sh printf "%b❌ Please make sure you are calling the script without leading 'sh'! Bye... %b%b" "${RED}" "${RES}" "${NL}" >&2 exit "${ERR_UNSUPPORTED_BASH}" } ### Not sourced. [[ "${BASH_SOURCE[0]}" != "$0" ]] && { . ./meta_loader_early.sh printf "%b❌ This script must be executed, not sourced. Please run './setup.sh' directly. %b%b" "${RED}" "${RES}" "${NL}" >&2 exit "${ERR_UNSUPPORTED_BASH}" } ### Minimum Bash version 5. [[ ${BASH_VERSINFO[0]} -lt 5 ]] && { . ./meta_loader_early.sh printf "%b❌ Minimum requirement is bash 5.1. You are using '%s'! Bye... %b%b" "${RED}" "${BASH_VERSION}" "${RES}" "${NL}" >&2 exit "${ERR_UNSUPPORTED_BASH}" } ### Minimum Bash version 5.1. [[ ${BASH_VERSINFO[0]} -le 5 ]] && [[ ${BASH_VERSINFO[1]} -le 1 ]] && { . ./meta_loader_early.sh printf "%b❌ Minimum requirement is bash 5.1. You are using '%s'! Bye... %b%b" "${RED}" "${BASH_VERSION}" "${RES}" "${NL}" >&2 exit "${ERR_UNSUPPORTED_BASH}" } ### No arguments. [[ ${#} -eq 0 ]] && { . ./meta_loader_early.sh usage >&2 exit 1 } ### CHECK FOR CONTACT, HELP, AND VERSION STRING. for arg in "$@"; do case "${arg,,}" in -c|--contact) . ./meta_loader_cuv.sh; contact; exit 0;; esac; done for arg in "$@"; do case "${arg,,}" in -h|--help) . ./meta_loader_cuv.sh; usage ; exit 0;; esac; done for arg in "$@"; do case "${arg,,}" in -v|--version) . ./meta_loader_cuv.sh; version; exit 0;; esac; done ### SOURCING MUST SET EARLY VARIABLES. SOURCING COLOR_ECHO() AND GUARD_SOURCING(). . ./lib/0010_guard_sourcing.sh . ./lib/0010_source_guard.sh source_guard "./var/color.var.sh" source_guard "./var/early.var.sh" source_guard "./lib/0004_color_echo.sh" ### ALL CHECKS DONE. READY TO START THE SCRIPT. color_echo "${CYA}" "ALL CHECKS DONE. READY TO START THE SCRIPT." declare -grx VAR_SETUP="true" umask 0022 ### SOURCING FUNCTIONS, LIBRARIES, VARIABLES. if [[ "${VAR_SETUP}" == "true" ]]; then ### SOURCING VARIABLES color_echo "${CYA}" "SOURCING VARIABLES." . ./meta_loader_var.sh ### SOURCING FUNCTIONS color_echo "${CYA}" "SOURCING FUNCTIONS." . ./meta_loader_func.sh ### SOURCING LIBRARIES color_echo "${CYA}" "SOURCING LIBRARIES." . ./meta_loader_lib.sh fi ### PREPARING DIRECTORIES AND FILES. color_echo "${CYA}" "PREPARING DIRECTORIES AND FILES." gen_dir_files ### CHECKING REQUIRED PACKAGES. color_echo "${CYA}" "CHECKING REQUIRED PACKAGES." #check_pkgs check_git ### ADVISORY LOCK. color_echo "${CYA}" "ADVISORY LOCK." exec 127>/var/lock/ciss_debian_installer.lock || { printf "%b❌ Cannot open lockfile for writing! Bye... %b%b" "${RED}" "${RES}" "${NL}" >&2 exit "${ERR_FLOCK_PROTECTED}" } if ! flock -x -n 127; then printf "%b❌ Another instance is running! Bye...%b%b" "${RED}" "${RES}" "${NL}" >&2 exit "${ERR_FLOCK_COLLISION}" fi ### SCAN FOR DEBUG MODE. color_echo "${CYA}" "SCAN FOR DEBUG MODE." pre_scan_debug "$@" ### CHECK FOR AUTO INSTALL MODE. color_echo "${CYA}" "CHECK FOR AUTO INSTALL MODE." for arg in "$@"; do case "${arg,,}" in -a|--autoinstall) declare -gx VAR_AUTO_INSTALL="true";; esac; done; unset arg ### ACTIVATING TRAPS. color_echo "${CYA}" "ACTIVATING TRAPS." trap 'trap_exit "$?" "${BASH_SOURCE[0]}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_COMMAND}"' EXIT trap 'trap_err "$?" "${BASH_SOURCE[0]}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_COMMAND}"' ERR trap 'trap_int' INT TERM ### INTERACTIVE MODE NOTES AND KERNEL SELECTION. # TODO: Update 0110_check_kernel.sh & sourcing # TODO: Update 0120_check_provider.sh & sourcing #if ! "${VAR_AUTO_INSTALL}"; then check_provider; fi #if ! "${VAR_AUTO_INSTALL}"; then check_kernel; fi ### Dialog Output for Initialization START. color_echo "${CYA}" "Dialog Output for Initialization START." if ! "${VAR_AUTO_INSTALL}"; then . ./lib/0200_dialog_helper.sh && dialog_box; fi ### ARGUMENT CHECKS. echo "ARGUMENT CHECKS..." arg_check "$@" declare -ar ARY_ARG_SANITIZED=("$@") declare -grx VAR_ARG_SANITIZED="${ARY_ARG_SANITIZED[*]}" ### ARGUMENT PARSING. echo "ARGUMENT PARSING..." arg_parser "$@" ### PRIORITY UPDATES. echo "PRIORITY UPDATES..." arg_priority_check ### HASHING PASSWORDS. echo "HASHING PASSWORDS..." nuke_passphrase # TODO: Implement loop_pass() for other passwords. ### MAIN PROGRAM SEQUENCE echo "MAIN PROGRAM SEQUENCE: yaml_parser()" yaml_parser echo "MAIN PROGRAM SEQUENCE: yaml_reader()" yaml_reader # TODO: Implement / Activate IP, Port validation # 1222_validation_preseed.sh 1221_validation_ip.sh # validation_preseed ### PARTITIONING echo "MAIN PROGRAM SEQUENCE: partitioning()" partitioning echo "MAIN PROGRAM SEQUENCE: benchmarking_encryption()" benchmarking_encryption echo "MAIN PROGRAM SEQUENCE: partition_encryption()" partition_encryption echo "MAIN PROGRAM SEQUENCE: partition_formatting()" partition_formatting echo "MAIN PROGRAM SEQUENCE: setup_filesystem()" setup_filesystem echo "MAIN PROGRAM SEQUENCE: mount_partition()" mount_partition echo "MAIN PROGRAM SEQUENCE: uuid_logger()" uuid_logger ### DEBOOTSTRAP echo "MAIN PROGRAM SEQUENCE: func_debootstrap()" func_debootstrap echo "MAIN PROGRAM SEQUENCE: configure_system()" configure_system echo "MAIN PROGRAM SEQUENCE: generate_fstab()" generate_fstab # TODO: Checks ongoing. echo "MAIN PROGRAM SEQUENCE: generate_crypttab()" generate_crypttab # TODO: Checks ongoing. echo "MAIN PROGRAM SEQUENCE: generate_sources()" generate_sources echo "MAIN PROGRAM SEQUENCE: minimal_toolset()" minimal_toolset echo "MAIN PROGRAM SEQUENCE: setup_skel()" setup_skel echo "MAIN PROGRAM SEQUENCE: setup_timezone()" setup_timezone echo "MAIN PROGRAM SEQUENCE: setup_locales()" setup_locales # TODO: Implement Clang Build Chain and MOK Signing Workflow echo "MAIN PROGRAM SEQUENCE: installation_kernel()" installation_kernel echo "MAIN PROGRAM SEQUENCE: setup_network()" setup_network echo "MAIN PROGRAM SEQUENCE: setup_hostname()" setup_hostname echo "MAIN PROGRAM SEQUENCE: setup_machineid()" setup_machineid # TODO: Implement Clang Build Chain and MOK Signing Workflow and integrate GRUB, if needed # TODO: Copy Grub Boot Loader to default path echo "MAIN PROGRAM SEQUENCE: setup_grub()" setup_grub echo "MAIN PROGRAM SEQUENCE: setup_grub_password()" setup_grub_password echo "MAIN PROGRAM SEQUENCE: setup_grub_bootparameter()" setup_grub_bootparameter echo "MAIN PROGRAM SEQUENCE: setup_kernel_modules()" setup_kernel_modules echo "MAIN PROGRAM SEQUENCE: setup_kernel_sysctl()" setup_kernel_sysctl echo "MAIN PROGRAM SEQUENCE: installation_microcode()" installation_microcode echo "MAIN PROGRAM SEQUENCE: setup_ssh()" setup_ssh echo "MAIN PROGRAM SEQUENCE: build_dropbear()" build_dropbear echo "MAIN PROGRAM SEQUENCE: install_dropbear_initramfs()" install_dropbear_initramfs # TODO: Update preseed.yaml for pgp signing key AND / OR implementation of presigned unlock-wrapper.sh echo "MAIN PROGRAM SEQUENCE: setup_dropbear()" setup_dropbear # TODO: Implement Console Login Deactivation and 2fa as advertised in preseed.yaml echo "MAIN PROGRAM SEQUENCE: setup_accounts()" setup_accounts # TODO: Check Packages for installation echo "MAIN PROGRAM SEQUENCE: setup_packages()" setup_packages # TODO: What do we need for CISS environment? echo "MAIN PROGRAM SEQUENCE: setup_sudo()" setup_sudo # TODO: Any changes to the NTPSec Servers? echo "MAIN PROGRAM SEQUENCE: setup_chrony()" setup_chrony echo "MAIN PROGRAM SEQUENCE: exiting_chroot()" exiting_chroot # TODO: Hibernate deactivation # TODO: Hardening Scripts Integration # TODO: SSH 2fa integration # TODO: Recovery Partition Integration # TODO: Grub Boot Menu Update for Recovery Integration # TODO: update-grub Post Hook Clang, Recovery, Signing MOK # TODO: Copying Log Files to final System # TODO: Integrate CISS.debian.installer calling arguments and preseed.yaml into CISS.debian.live.builder build chain? # TODO: Reboot function for Autoinstall ### Dialog Output for Initialization END if ! "${VAR_AUTO_INSTALL}"; then . ./lib/0200_dialog_helper.sh && dialog_box_cleaner; fi declare -gx VAR_SCRIPT_SUCCESS="true" exit 0 # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh