#!/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 guard_sourcing # TODO Important insert cryptdevice=UUID=881366ae-61ee-4ee0-893c-0def27c78c9e:cryptroot root=/dev/mapper/vg00-root # TODO Important insert GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0 biosdevname=0 ip=152.53.66.126::152.53.64.1:255.255.252.0:soc:ens3:none" ########################################################################################### # 3.7.7. Functions - installation - kernel # ########################################################################################### lsinitramfs /boot/initrd.img-$(uname -r) | grep -E 'bin/(reboot|sync|sleep|sh)' command="/usr/local/bin/coresecret.sh",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICp+6S+qM87lLWUtvTGBV/GFNvYyvZ992X4/AcuraKwm 2025_run.coresecret.dev_root *** run.coresecret.dev /dev/sda5: UUID="468ad656-0e2f-4fff-9501-c691bab9f553" TYPE="crypto_LUKS" PARTLABEL="crypt_system" PARTUUID="78c0f711-f84f-425e-9455-a46430f40794" echo "IP=65.21.249.232::172.31.1.1:255.255.255.255:run.coresecret.dev:enp1s0:none:135.181.207.105:89.58.62.53:192.53.103.108" >| /etc/initramfs-tools/conf.d/ip GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=UUID=468ad656-0e2f-4fff-9501-c691bab9f553:cryptroot root=/dev/mapper/vg_system-root" *** /usr/share/cryptsetup/initramfs/bin/cryptroot-unlock # Vorher (Standard) ASKPASS=/lib/cryptsetup/askpass # Danach ASKPASS=/lib/cryptsetup/askpass.cryptsetup apt-get cryptsetup-nuke-password dpkg-reconfigure cryptsetup-nuke-password debconf-set-selections << END cryptsetup-nuke-password cryptsetup-nuke-password/password string Th3Pa$$w0rd cryptsetup-nuke-password cryptsetup-nuke-password/password-again string Th3Pa$$w0rd END sudo dpkg-reconfigure -f noninteractive cryptsetup-nuke-password apt-get install -y busybox cryptsetup-initramfs dropbear-initramfs initramfs-tools rm -f /etc/dropbear/initramfs/dropbear*key dropbearkey -t rsa -s 4096 -f /etc/dropbear/initramfs/dropbear_rsa_host_key dropbearkey -t ed25519 -f /etc/dropbear/initramfs/dropbear_ed25519_host_key chmod 600 /etc/dropbear/initramfs/dropbear*key chown root:root /etc/dropbear/initramfs/dropbear*key cp -af ~/.ssh/authorized_keys /etc/dropbear/initramfs echo "IP=152.53.110.40::152.53.108.1:255.255.252.0:git.coresecret.dev:ens3:none:135.181.207.105:89.58.62.53:192.53.103.108" >| /etc/initramfs-tools/conf.d/ip sed -i 's|#DROPBEAR_OPTIONS=""|DROPBEAR_OPTIONS="-p 37768 -s -j -k -I 300 -c coresecret.sh"|g' /etc/dropbear/initramfs/dropbear.conf GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=UUID=881366ae-61ee-4ee0-893c-0def27c78c9e:cryptroot root=/dev/mapper/vg00-root" update-initramfs -u -v -k all NIC_MODULE=$(lspci -k | grep -A2 -i ethernet | grep 'Kernel driver in use' | awk '{print $5}') echo "$NIC_MODULE" grep_nic_driver_modules() { # Alle Treibernamen sammeln und unique sortieren readarray -t _mods < <( lspci -k \ | grep -A2 -i ethernet \ | grep 'Kernel driver in use' \ | awk '{print $5}' \ | sort -u ) # Wenn nur ein Eintrag übrig bleibt, in NIC_MODULE speichern, # sonst alternativ alle Module in NIC_MODULES if [ "${#_mods[@]}" -eq 1 ]; then NIC_MODULE="${_mods[0]}" else NIC_MODULES="${_mods[*]}" fi # Ausgabe zur Kontrolle if [ -n "$NIC_MODULE" ]; then echo "Einzelnes Modul: $NIC_MODULE" else echo "Mehrere Module: $NIC_MODULES" fi } ########################################################################################### # Installation of the specified kernel incl. dropbear SSH, LUKS Nuke. # Globals: # MODULE_ERR # MODULE_TXT # TARGET # kernel # Arguments: # None ########################################################################################### 3_7_7_functions_installation_kernel() { declare -g -x MODULE_ERR="3_7_7_functions_installation_kernel" declare -g -x MODULE_TXT="Install kernel: '${kernel}'" do_show_header "${MODULE_TXT}" # Installing the chosen Kernel Image according to preseed.yaml do_in_target "${TARGET}" apt-get install -y "${kernel}" if [[ ${accounts_dropbear_ssh,,} == "true" ]]; then do_in_target "${TARGET}" apt-get install -y busybox cryptsetup-initramfs dropbear-initramfs initramfs-tools echo "DROPBEAR_OPTIONS=\"-p ${accounts_ssh_port} -s -j -k -I 300\"" > "${TARGET}/etc/dropbear/initramfs/dropbear.conf" cat > "${TARGET}/etc/dropbear/initramfs/authorized_keys" << EOF command="/bin/security-rescue-shell",no-port-forwarding,no-pty,no-X11-forwarding ${accounts_dropbear_pubkey} EOF chmod 0644 "${TARGET}/etc/dropbear/initramfs/dropbear.conf" chown root:root "${TARGET}/etc/dropbear/initramfs/dropbear.conf" chmod 0600 "${TARGET}/etc/dropbear/initramfs/authorized_keys" chown root:root "${TARGET}/etc/dropbear/initramfs/authorized_keys" do_log "info" "true" "Command: 'echo \"DROPBEAR_OPTIONS=\"-p ${accounts_ssh_port} -s -j -k -I 300 -K curve25519-sha256 -c aes256-gcm@openssh.com -m hmac-sha2-256,hmac-sha2-512\" > ${TARGET}/etc/dropbear/initramfs/dropbear.conf' executed in: '${TARGET}'." do_log "info" "true" "Command: 'echo ${accounts_dropbear_pubkey} > ${TARGET}/etc/dropbear/initramfs/authorized_keys' executed in: '${TARGET}'." # Network-Pre-Script for initramfs DHCP cat > "${TARGET}/etc/initramfs-tools/scripts/init-premount/dhcp-network" << 'EOF' #!/bin/sh # ^^ no bash in initramfs environment, only BusyBox PREREQ="" prereqs() { echo "${PREREQ}"; } case $1 in prereqs) prereqs; exit 0 ;; esac # NIC without ":" and VLAN-Suffix iface=$(grep -E '^(eth|en)[^:.]*$' /sys/class/net | head -n1) [ -n "${iface}" ] || exit 0 # Setup Link and dhclient or udhcpc ip link set "${iface}" up if command -v dhclient >/dev/null 2>&1; then dhclient "${iface}" else udhcpc -i "${iface}" fi exit 0 EOF chmod +x "${TARGET}/etc/initramfs-tools/scripts/init-premount/dhcp-network" do_log "info" "true" "Generated: '${TARGET}/etc/initramfs-tools/scripts/init-premount/dhcp-network: '${TARGET}'." cat > "${TARGET}/etc/initramfs-tools/scripts/init-bottom/dropbear_fw" << EOF #!/bin/sh # ^^ no bash in initramfs environment, only BusyBox if command -v iptables >/dev/null 2>&1; then iptables -F iptables -P INPUT DROP iptables -P OUTPUT ACCEPT iptables -P FORWARD DROP iptables -A INPUT -p tcp --dport "${accounts_ssh_port}" -s "${accounts_bastion_vpn_ipv4}" -j ACCEPT iptables -A INPUT -i lo -j ACCEPT fi if command -v ip6tables >/dev/null 2>&1; then ip6tables -F ip6tables -P INPUT DROP ip6tables -P OUTPUT ACCEPT ip6tables -P FORWARD DROP ip6tables -A INPUT -p tcp --dport "${accounts_ssh_port}" -s "${accounts_bastion_vpn_ipv6}" -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT fi EOF chmod +x "${TARGET}/etc/initramfs-tools/scripts/init-bottom/dropbear_fw" cat > "${TARGET}/bin/remote-nuke.sh" << EOF #!/bin/sh # ^^ no bash in initramfs environment, only BusyBox # remote-nuke.sh – to be executed at the end of Initramfs PREREQ="local-bottom" prereqs() { echo "${PREREQ}"; } case $1 in prereqs) prereqs; exit 0 ;; esac message() { if [ ${#*} -lt 76 ]; then echo "$*" 1>&2 else # use busybox's fold(1) and sed(1) at initramfs stage echo "$*" | fold -s | sed '1! s/^/ /' 1>&2 fi return 0 } . /scripts/functions # delivers log_* und ASKPASS # Brief break, to ensure all devices are mapped sleep 1 readonly MAX_RETRIES=5 for DEV in /dev/sd*[0-9]; do [ -b "${DEV}" ] || continue DEV_NAME=$(basename "${DEV}" | tr -cs 'a-zA-Z0-9' '_') NUKE_MAP="nuke_${DEV_NAME}" TRY_MAP="try_${DEV_NAME}" ASKPASS=/usr/bin/ssh-askpass password="$(${ASKPASS} "Enter LUKS passphrase: ")" message "Checking ${DEV} ..." if ! cryptsetup isLuks "${DEV}" 2>/dev/null; then message "${DEV} is not a LUKS-Container – skipped." continue fi # Verify, if LUKS Key Slot #31 exists if cryptsetup luksDump "${DEV}" 2>/dev/null | grep -q '^Key Slot 31: *ENABLED'; then has_slot31="yes" else has_slot31="no" fi attempt=1 while [ ${attempt} -le ${MAX_RETRIES} ]; do message "Attempt '${attempt}/${MAX_RETRIES}' for opening ${DEV} ..." if [ "${has_slot31}" = yes ]; then if echo "${password}" | cryptsetup open --test-passphrase --key-slot 31 "${DEV}" "${NUKE_MAP}" 2>/dev/null; then echo YES | cryptsetup erase "${DEV}" message "Slot 31 of ${DEV} exists. Cleaning OK successful." break fi fi if echo "$((password))" | cryptsetup open "${DEV}" "crypt_${NAME}" 2>/dev/null; then decrypted_any=yes break fi # 2) Normales Entschlüsseln (jeder Slot) echo "$password" | cryptsetup open \ --test-passphrase \ "$DEV" nuke_tmp 2>/dev/null if [ $? -eq 0 ]; then log_success_msg "Normales Test-Passphrase erfolgreich" cryptsetup erase "$DEV" && \ log_success_msg "LUKS-Header von $DEV gelöscht" break else log_warning_msg "Normales Test-Passphrase fehlgeschlagen" fi attempt=$((attempt + 1)) if [ $attempt -le $MAX_RETRIES ]; then log_begin_msg "Warte 1s vor erneutem Versuch für $DEV…" sleep 1 else log_error_msg "Maximale Versuche für $DEV erreicht – überspringe" fi done # Aufräumen: falls ein Mapper existiert, schließen if [ -e /dev/mapper/nuke_tmp ]; then cryptsetup close nuke_tmp fi done log_end_msg 0 exit 0 EOF chmod +x "${TARGET}/bin/security-rescue-shell" # Regenerate Initramfs incl. Dropbear SSH, Scripts and Keys do_in_target "${TARGET}" update-initramfs -u fi do_log "info" "true" "Dropbear SSH in initramfs des Targets installiert und konfiguriert (Port: ${accounts_ssh_port}, CA aktiviert, RateLimit & Nuke-Key)." do_show_footer "${MODULE_TXT}" } # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh: