V8.02.512.2025.05.30

Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
This commit is contained in:
2025-05-30 00:28:39 +02:00
parent 2680012395
commit b2282d3475
172 changed files with 14057 additions and 41 deletions

386
lib/lib_arg_parser.sh Normal file
View File

@@ -0,0 +1,386 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Argument Parser
# Globals:
# BUILD_LOG
# DEBUG
# EARLY_DEBUG
# ERR_CONTROL_CT
# ERR_MISS_PWD_F
# ERR_MISS_PWD_P
# ERR_OWNS_PWD_F
# ERR_PASS_LENGH
# ERR_PASS_PLICY
# ERR_REIONICE_P
# ERR_REIO_C_VAL
# ERR_REIO_P_VAL
# ERR_RENICE_PRI
# ERR_RGHT_PWD_F
# ERR_SPLASH_PNG
# ERR_UNCRITICAL
# ERR__SSH__PORT
# HANDLER_ARCHITECTURE
# HANDLER_BUILD_DIR
# HANDLER_CDI
# HANDLER_DHCP
# HANDLER_ISO_COUNTER
# HANDLER_PRIORITY
# HANDLER_SPLASH
# HANDLER_SSHPORT
# HANDLER_SSHPUBKEY
# HANDLER_STA
# HASHED_PWD
# ISO8601
# REIONICE_CLASS
# REIONICE_PRIORITY
# VERSION
# handler_jumphost
# Arguments:
# None
#######################################
arg_parser() {
while [[ $# -gt 0 ]]; do
declare argument="${1}"
case "${argument,,}" in
-c | --contact)
if [[ -n "${2}" && "${2}" != -* ]]; then
boot_screen_cleaner
printf "\e[91m❌ Error: --contact MUST NOT be followed by an argument.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_ARG_MSMTCH}"
fi
shift 1
;;
-h | --help)
if [[ -n "${2}" && "${2}" != -* ]]; then
boot_screen_cleaner
printf "\e[91m❌ Error: --help MUST NOT be followed by an argument.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_ARG_MSMTCH}"
fi
shift 1
;;
-v | --version)
if [[ -n "${2}" && "${2}" != -* ]]; then
boot_screen_cleaner
printf "\e[91m❌ Error: --version MUST NOT be followed by an argument.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_ARG_MSMTCH}"
fi
shift 1
;;
--architecture)
if [[ "${2}" == "amd64" || "${2}" == "arm64" ]]; then
declare -gx HANDLER_ARCHITECTURE="$2"
shift 2
else
boot_screen_cleaner
printf "\e[91m❌ Error: --architecture MUST be 'amd64' or 'arm64'.\e[0m\n" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_UNCRITICAL}"
fi
;;
--build-directory)
declare -gx HANDLER_BUILD_DIR="${2}"
declare -gx BUILD_LOG="${HANDLER_BUILD_DIR}/${ISO8601}_build.log"
shift 2
;;
--cdi)
if [[ -n "${2}" && "${2}" != -* ]]; then
boot_screen_cleaner
printf "\e[91m❌ Error: --cdi MUST NOT be followed by an argument.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_ARG_MSMTCH}"
fi
declare -g HANDLER_CDI=true
shift 1
;;
--change-splash )
if [[ "${2}" == "club" || "${2}" == "hexagon" ]]; then
declare -g HANDLER_SPLASH="${2}"
shift 2
else
boot_screen_cleaner
printf "\e[91m❌ Error: --change-splash MUST be 'club' or 'hexagon'.\e[0m\n" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_SPLASH_PNG}"
fi
;;
--control)
if [[ -n "${2}" && "${2}" =~ ^-?[0-9]+$ && "${2}" -ge 1 && "${2}" -le 65536 ]]; then
declare -gi HANDLER_ISO_COUNTER="$2"
shift 2
else
boot_screen_cleaner
printf "\e[91m❌ Error: --control MUST be an integer between '1' and '65535'.\e[0m\n" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_CONTROL_CT}"
fi
;;
--debug)
if [[ -n "${2}" && "${2}" != -* ]]; then
boot_screen_cleaner
printf "\e[91m❌ Error: --debug MUST NOT be followed by an argument.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_ARG_MSMTCH}"
fi
shift 1
;;
--dhcp-centurion)
if [[ -n "${2}" && "${2}" != -* ]]; then
boot_screen_cleaner
printf "\e[91m❌ Error: --dhcp-centurion MUST NOT be followed by an argument.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_ARG_MSMTCH}"
fi
declare -gi HANDLER_DHCP=1
shift 1
;;
--jump-host)
if [[ -n "${2}" && "${2}" != -* ]]; then
declare -i count=0
shift
while [[ "${#}" -gt 0 && "${1}" != -* && count -lt 10 ]]; do
declare -g handler_jumphost+=("$1")
count=$((count + 1))
shift
done
while [[ "${#}" -gt 0 && "${1}" != -* ]]; do
shift
done
else
boot_screen_cleaner
printf "\e[91m❌ Error: --jump-host MUST contain one or up to ten IPs.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_ARG_MSMTCH}"
fi
;;
--log-statistics-only)
if [[ -n "${2}" && "${2}" != -* ]]; then
boot_screen_cleaner
printf "\e[91m❌ Error: --log-statistics-only MUST NOT be followed by an argument.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_ARG_MSMTCH}"
fi
declare -gi HANDLER_STA=1
shift 1
;;
--provider-netcup-ipv6)
if [[ -n "${2}" && "${2}" != -* ]]; then
declare -i count=0
declare -g handler_netcup_ipv6=true
shift
while [[ "${#}" -gt 0 && "${1}" != -* && count -lt 1 ]]; do
declare cleaned="${1//[\[\]]/}"
declare -g handler_netcup_ipv6_array+=("${cleaned}")
count=$((count + 1))
shift
done
while [[ "${#}" -gt 0 && "${1}" != -* ]]; do
shift
done
else
boot_screen_cleaner
printf "\e[91m❌ Error: --provider-netcup-ipv6 MUST provide one IPv6.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_ARG_MSMTCH}"
fi
;;
--renice-priority)
if [[ -n ${2} && ${2} =~ ^-?[0-9]+$ && ${2} -ge -19 && ${2} -le 19 ]]; then
declare -gi HANDLER_PRIORITY="$2"
shift 2
else
boot_screen_cleaner
printf "\e[91m❌ Error: --renice-priority MUST an integer between '-19' and '19'.\e[0m\n" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_RENICE_PRI}"
fi
;;
--reionice-priority)
if [[ -z "${2}" ]]; then
boot_screen_cleaner
printf "\e[91m❌ Error: --reionice-priority no values provided.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_REIONICE_P}"
else
if [[ "${2}" =~ ^[1-3]$ ]]; then
declare -gi REIONICE_CLASS="${2}"
if [[ -z "${3}" ]]; then
:
else
if [[ "${3}" =~ ^[0-7]$ ]]; then
declare -gi REIONICE_PRIORITY="${3}"
else
boot_screen_cleaner
printf "\e[91m❌ Error: --reionice-priority PRIORITY MUST be an integer between '0' and '7'.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_REIO_P_VAL}"
fi
fi
else
boot_screen_cleaner
printf "\e[91m❌ Error: --reionice-priority CLASS MUST be an integer between '1' and '3'.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_REIO_C_VAL}"
fi
fi
if [[ -n ${REIONICE_PRIORITY} ]]; then
shift 3
else
shift 2
fi
;;
--root-password-file)
declare pw_file="${2}"
if [[ -z "${pw_file}" ]]; then
boot_screen_cleaner
printf "\e[91m❌ Error: --root-password-file missing password file path argument.\e[0m\n" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_MISS_PWD_P}"
fi
if [[ ! -f "${pw_file}" ]]; then
boot_screen_cleaner
printf "\e[91m❌ Error: --root-password-file password file '%s' does not exist.\e[0m\n" "${pw_file}" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_MISS_PWD_F}"
fi
declare owner
owner=$(stat -c '%U:%G' "${pw_file}")
if [[ "${owner}" != "root:root" ]]; then
chown root:root "${pw_file}" || {
boot_screen_cleaner
printf "\e[91m❌ Error: --root-password-file failed to set owner root:root on '%s'.\e[0m\n" "${pw_file}" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_OWNS_PWD_F}"
}
fi
declare perms
perms=$(stat -c '%a' "${pw_file}")
if [[ "${perms}" -ne 400 ]]; then
chmod 400 "${pw_file}" || {
boot_screen_cleaner
printf "\e[91m❌ Error: --root-password-file failed to set permissions 0400 on '%s'.\e[0m\n" "${pw_file}" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_RGHT_PWD_F}"
}
fi
declare plaintext_pw
[[ "${EARLY_DEBUG}" == "true" ]] && set +x # No tracing for security reasons
if ! IFS= read -r plaintext_pw < "${pw_file}"; then
:
fi
[[ "${EARLY_DEBUG}" == "true" ]] && set -x # Turn on tracing again
declare pw_length
pw_length=${#plaintext_pw}
if (( pw_length < 20 || pw_length > 64 )); then
boot_screen_cleaner
printf "\e[91m❌ Error: --root-password-file password MUST be between 20 and 64 characters (got %d).\e[0m\n" "${pw_length}" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_PASS_LENGH}"
fi
[[ "${EARLY_DEBUG}" == "true" ]] && set +x # No tracing for security reasons
if [[ "${plaintext_pw}" == *\"* ]]; then
[[ "${EARLY_DEBUG}" == "true" ]] && set -x # Turn on tracing again
boot_screen_cleaner
printf "\e[91m❌ Error: --root-password-file password MUST NOT contain double quotes (\").\e[0m\n" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_PASS_PLICY}"
fi
[[ "${EARLY_DEBUG}" == "true" ]] && set -x # Turn on tracing again
declare salt
set +o pipefail
while :; do
salt=$(tr -dc 'A-Za-z0-9' </dev/random | head -c 16)
[[ ${#salt} -eq 16 ]] && break
done
set -o pipefail
declare hash_temp
[[ "${EARLY_DEBUG}" == "true" ]] && set +x # No tracing for security reasons
hash_temp=$(mkpasswd --method=sha-512 --salt="${salt}" --rounds=8388608 "${plaintext_pw}")
[[ "${EARLY_DEBUG}" == "true" ]] && set -x # Turn on tracing again
declare -g HASHED_PWD="${hash_temp}"
unset hash_temp plaintext_pw
sync
if shred -vfzu -n 5 "${pw_file}" > /dev/null 2>&1; then
printf "\e[92m✅ Password file '%s': shred -vfzu -n 5 >> done. \e[0m\n" "${pw_file}" > /dev/null 2>&1
else
printf "\e[91m❌ Password file '%s': shred -vfzu -n 5 >> NOT successful. \e[0m\n" "${pw_file}" > /dev/null 2>&1
fi
sync
shift 2
;;
--ssh-port)
if [[ -n "${2}" && "${2}" =~ ^-?[0-9]+$ && "${2}" -ge 1 && "${2}" -le 65535 ]]; then
declare -gi HANDLER_SSHPORT="${2}"
shift 2
else
boot_screen_cleaner
printf "\e[91m❌ Error: --ssh-port MUST be an integer between '1' and '65535'.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR__SSH__PORT}"
fi
;;
--ssh-pubkey)
declare -g HANDLER_SSHPUBKEY="${2}"
shift 2
;;
*)
boot_screen_cleaner
usage
;;
esac
done
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,42 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Check and setup Script Priorities
# Globals:
# HANDLER_PRIORITY
# REIONICE_CLASS
# REIONICE_PRIORITY
# Arguments:
# None
#######################################
arg_priority_check() {
declare var
# Check if nice PRIORITY is set and adjust nice priority.
if [[ -n ${HANDLER_PRIORITY} ]]; then
renice "${HANDLER_PRIORITY}" -p "$$"
var=$(ps -o ni= -p $$) > /dev/null 2>&1
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ New renice value: %s\e[0m\n" "${var}"
# sleep 1
unset var
fi
# Check if ionice PRIORITY is set and adjust ionice priority.
if [[ -n ${REIONICE_CLASS} ]]; then
ionice -c"${REIONICE_CLASS:-2}" -n"${REIONICE_PRIORITY:-4}" -p "$$"
var=$(ionice -p $$) > /dev/null 2>&1
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ New ionice value: %s\e[0m\n" "${var}"
# sleep 1
unset var
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

53
lib/lib_boot_screen.sh Normal file
View File

@@ -0,0 +1,53 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Change Grub Boot Screen Splash
# Globals:
# boot_screen_pid
# boot_screen_pipe
# Arguments:
# None
#######################################
boot_screen() {
clear
declare -gr boot_screen_pipe="/tmp/progress.fifo"
[[ -p "${boot_screen_pipe}" ]] || mkfifo "${boot_screen_pipe}"
setsid dialog --no-collapse \
--ascii-lines \
--keep-tite \
--title "CISS.debian.live.builder" \
--gauge "Starting initialization..." \
10 70 0 \
< "${boot_screen_pipe}" &
declare -gr boot_screen_pid="$!"
exec 3> "${boot_screen_pipe}"
}
#######################################
# Boot Screen Terminal Cleaner
# Globals:
# boot_screen_pid
# boot_screen_pipe
# Arguments:
# None
#######################################
boot_screen_cleaner() {
exec 3>&-
kill -TERM -- -"${boot_screen_pid}" 2>/dev/null || true
wait "${boot_screen_pid}" 2>/dev/null || true
rm -f "${boot_screen_pipe}"
clean_screen
sleep 1
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

62
lib/lib_cdi.sh Normal file
View File

@@ -0,0 +1,62 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# CISS.2025.debian.installer GRUB and Autostart Generator
# Globals:
# BASH_SOURCE
# HANDLER_BUILD_DIR
# HANDLER_CDI
# WORKDIR
# kernel
# Arguments:
# None
#######################################
cdi() {
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 %s starting ... \e[0m\n" "${BASH_SOURCE[0]}"
if [[ "${HANDLER_CDI}" == "true" ]]; then
if [[ ! -d "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/live/config" ]]; then
mkdir -p "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/live/config"
fi
cp "${WORKDIR}/scripts/9000-cdi-starter" "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/live/config/9000-cdi-starter"
chmod 0750 "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/live/config/9000-cdi-starter"
chown root:root "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/live/config/9000-cdi-starter"
declare tmp_entry
tmp_entry="$(mktemp)"
cat << EOF >| "${tmp_entry}"
menuentry "CISS Hardened DI (${kernel})" --hotkey=i {
linux /live/vmlinuz-${kernel} boot=live verify-checksums live-config.components splash nopersistence toram ramdisk-size=1024M swap=true noeject locales=en_US.UTF-8 keyboard-layouts=de keyboard-model=pc105 keyboard-options= keyboard-variants= timezone=Europe/Lisbon audit_backlog_limit=8192 audit=1 cfi=kcfi debugfs=off efi=disable_early_pci_dma efi_no_storage_paranoia hardened_usercopy=1 ia32_emulation=0 init_on_alloc=1 init_on_free=1 iommu=force kfence.sample_interval=100 kvm.nx_huge_pages=force l1d_flush=on lockdown=confidentiality loglevel=0 mce=0 mitigations=auto,nosmt mmio_stale_data=full,nosmt oops=panic page_alloc.shuffle=1 page_poison=1 panic=-1 pti=on random.trust_bootloader=off random.trust_cpu=off randomize_kstack_offset=on randomize_va_space=2 retbleed=auto,nosmt rodata=on tsx=off vdso32=0 vsyscall=none findiso=\${iso_path}
initrd /live/initrd.img-${kernel}
}
EOF
sed -i "/#MUST_BE_REPLACED/{
r ${tmp_entry}
d
}" "${HANDLER_BUILD_DIR}/config/bootloaders/grub-efi/grub.cfg"
sed -i "/#MUST_BE_REPLACED/{
r ${tmp_entry}
d
}" "${HANDLER_BUILD_DIR}/config/bootloaders/grub-pc/grub.cfg"
rm -f "${tmp_entry}"
else
# shellcheck disable=SC1003
sed -i '/#MUST_BE_REPLACED/c\\' "${HANDLER_BUILD_DIR}/config/bootloaders/grub-efi/grub.cfg"
fi
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ %s successful applied. \e[0m\n" "${BASH_SOURCE[0]}"
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

37
lib/lib_change_splash.sh Normal file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Change Grub Boot Screen Splash
# Globals:
# HANDLER_BUILD_DIR
# HANDLER_SPLASH
# WORKDIR
# Arguments:
# None
#######################################
change_splash() {
if [[ ${HANDLER_SPLASH} == "club" ]]; then
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Grub Splash 'club.png' selected ...\e[0m\n"
cp -af "${WORKDIR}"/.archive/background/club.png "${HANDLER_BUILD_DIR}"/config/bootloaders/splash.png
cp -af "${WORKDIR}"/.archive/background/club.png "${HANDLER_BUILD_DIR}"/config/bootloaders/grub-efi/splash.png
cp -af "${WORKDIR}"/.archive/background/club.png "${HANDLER_BUILD_DIR}"/config/bootloaders/grub-pc/splash.png
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Grub Splash 'club.png' selected done. \e[0m\n"
elif [[ ${HANDLER_SPLASH} == "hexagon" ]]; then
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Grub Splash 'hexagon.png' selected ...\e[0m\n"
cp -af "${WORKDIR}"/.archive/background/hexagon.png "${HANDLER_BUILD_DIR}"/config/bootloaders/splash.png
cp -af "${WORKDIR}"/.archive/background/hexagon.png "${HANDLER_BUILD_DIR}"/config/bootloaders/grub-efi/splash.png
cp -af "${WORKDIR}"/.archive/background/hexagon.png "${HANDLER_BUILD_DIR}"/config/bootloaders/grub-pc/splash.png
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Grub Splash 'hexagon.png' selected done. \e[0m\n"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

26
lib/lib_check_dhcp.sh Normal file
View File

@@ -0,0 +1,26 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Check if hardened Centurion DNS servers are desired.
# Globals:
# HANDLER_DHCP
# WORKDIR
# Arguments:
# None
#######################################
check_dhcp() {
if [[ ${HANDLER_DHCP} -eq 1 ]]; then
chmod +x "${WORKDIR}"/scripts/0010_dhcp_supersede.sh && "${WORKDIR}"/scripts/0010_dhcp_supersede.sh
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

37
lib/lib_check_hooks.sh Normal file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Check and apply 0755 Permissions on every ./config/hooks/live/*.chroot file
# Globals:
# ERR_UNCRITICAL
# WORKDIR
# Arguments:
# None
#######################################
check_hooks() {
declare ifs
ifs=$'\n\t'
shopt -s nullglob
declare -a files=("${WORKDIR}"/config/hooks/live/*.chroot)
if (( ${#files[@]} == 0 )); then
printf "\e[91m❌ No '*.chroot' files found in '%s/config/hooks/live'. \e[0m\n" "${WORKDIR}" >&2
exit "${ERR_UNCRITICAL}"
fi
declare file
for file in "${files[@]}"; do
chmod 0755 "${file}"
done
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

72
lib/lib_check_kernel.sh Normal file
View File

@@ -0,0 +1,72 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Kernel Image Selector
# Globals:
# HANDLER_ARCHITECTURE
# KERNEL_SRT
# KERNEL_TMP
# kernel
# Arguments:
# None
# Returns:
# 42: Sorting Error.
#######################################
check_kernel() {
clear
declare -i counter=1
declare first_string=""
declare line=""
declare -gx kernel=""
declare name=""
declare options=""
if [[ ${HANDLER_ARCHITECTURE} != arm64 ]]; then
apt-cache search linux-image | grep linux-image | grep amd64 | grep -v "meta-package" | grep -v "dbg" | grep -v "template" >> "${KERNEL_TMP}"
else
apt-cache search linux-image | grep linux-image | grep arm64 | grep -v "meta-package" | grep -v "dbg" | grep -v "template" >> "${KERNEL_TMP}"
fi
sort --output="${KERNEL_SRT}" "${KERNEL_TMP}" || {
printf "❌ Error check_kernel() Line 40 sort failed\n" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
return 42
}
while IFS= read -r line; do
first_string=${line%% *}
name=${first_string#linux-image-}
options+=("${name}" "${counter}" off)
((counter++))
done < "${KERNEL_SRT}"
# shellcheck disable=SC2155
if declare -g kernel=$(dialog \
--no-collapse \
--ascii-lines \
--clear \
--backtitle "CISS.debian.live.builder" \
--title "Select the Kernel for the CISS Hardened Debian Live Image ISO" \
--radiolist "Kernel available \n *+bpo* : Debian Backported Kernel \n *cloud* : Special lightweight images for KVM \n *unsigned* : Unsigned Kernel \n *preempt_rt* : Special Kernel for real-time-computing \n Not unsigned marked are MS signed Kernel for Secure Boot \n" 0 0 "${options[@]}" 3>&1 1>&2 2>&3 3>&-); then
clear
else
clear
if [[ "${HANDLER_ARCHITECTURE}" == "amd64" ]]; then
declare -gr kernel="amd64"
elif [[ "${HANDLER_ARCHITECTURE}" == "arm64" ]]; then
declare -gr kernel="arm64"
fi
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

32
lib/lib_check_pkgs.sh Normal file
View File

@@ -0,0 +1,32 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Check for required Deb Packages to run the script.
# Arguments:
# None
#######################################
check_pkgs() {
if [[ ! -f /usr/share/live/build/VERSION ]]; then
apt-get update -y
apt-get install live-build -y
fi
if [[ -z "$(command -v dialog || true)" ]]; then
apt-get install --no-install-recommends dialog -y
fi
if [[ -z "$(command -v mkpasswd || true)" ]]; then
apt-get install --no-install-recommends whois -y
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

65
lib/lib_check_provider.sh Normal file
View File

@@ -0,0 +1,65 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Notes Textbox
# Arguments:
# None
#######################################
check_provider() {
clear
cat << 'EOF' >| "${notes}"
Build: Master V8.02.512.2025.05.30
Press 'EXIT' to continue with CISS.debian.live.builder.
When you provision ISO images using the Netcup provider, you MUST always supply a globally unique identifier
for each image via the --control argument. If you omit this flag or reuse an existing identifier, Netcup's
backend will automatically locate and mount the oldest ISO carrying that same name. In practice, this means
you might believe you're booting a freshly uploaded image, but in fact the system silently reattaches an
earlier one—leading to confusing failures and wasted troubleshooting time.
A separate but related issue emerges when booting certain Debian "cloud" kernel images—specifically those
matching the patterns *.+bpo-cloud-amd64 or *.+bpo-cloud-arm64—on a Netcup G11 instance or on a Hetzner VM.
After the initramfs is loaded, the console output often becomes garbled or completely unreadable. This is not
due to a kernel panic, but rather to a mismatch between the framebuffer mode expected by the initramfs and the
one actually provided by the virtual hardware. Common workarounds, like editing the boot entry (e) and appending
— 'nomodeset', or
— 'vga=0x318',
do not resolve the issue because they address legacy VGA modes rather than the EFI framebuffer parameters used
in modern cloud images.
To mitigate this, you can:
— Use a plain Debian kernel (e.g., linux-image-amd64) instead of the bpo-cloud variants, which are optimized
for cloud-init but presume a different console setup.
— Explicitly set an EFI-compatible framebuffer by adding something like 'video=efifb:mode=auto' to the kernel
command line. This aligns the initramfs console driver with the actual firmware framebuffer.
— Build a custom initramfs that includes the correct video modules or switches back to a serial console. For
example, adding 'console=ttyS0,115200' can force all early messages to the serial port bypassing the
graphical framebuffer entirely.
EOF
dialog --no-collapse \
--ascii-lines \
--clear \
--backtitle "CISS.debian.live.builder" \
--title "Important Notes" \
--scrollbar \
--textbox "${notes}" 32 128
clear
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

27
lib/lib_check_stats.sh Normal file
View File

@@ -0,0 +1,27 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Check if analysis run is desired only.
# Globals:
# HANDLER_STA
# Arguments:
# None
#######################################
check_stats() {
if [[ ${HANDLER_STA} -eq 1 ]]; then
clear
run_analysis
exit 0
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

35
lib/lib_check_var.sh Normal file
View File

@@ -0,0 +1,35 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Unbound Variable Check and call Trap on ERR
# Globals:
# ERR_UNBOUNDVAR
# Arguments:
# $1: VAR_NAME to check
# Returns:
# "${ERR_UNBOUNDVAR}"
#######################################
check_var() {
declare var_name_to_check="$1"
if [[ -n "${!var_name_to_check+exists}" ]]; then
if [[ -n "${!var_name_to_check}" ]]; then
printf "\e[92m✅ Variable: '%s' exists and is NOT empty: »%s« \e[0m\n" "${var_name_to_check}" "${!var_name_to_check}"
else
printf "\e[92m✅ Variable: '%s' exists but is empty. \e[0m\n" "${var_name_to_check}"
fi
else
printf "\e[91m❌ Variable: '%s' is not declared. Exiting Script. \e[0m\n" "${var_name_to_check}" >&2
return "${ERR_UNBOUNDVAR}"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

28
lib/lib_clean_screen.sh Normal file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Terminal cleaner before Trap on Error
# Arguments:
# None
#######################################
clean_screen() {
tput cnorm > /dev/tty # Cursor visible
tput sgr0 > /dev/tty # Attributes off
stty sane < /dev/tty # Sane modes
tput rmcup > /dev/tty # Back to the main buffer
clear > /dev/tty # Clear residual
#lines=$(tput lines)
#tput cup $((lines-1)) 0 > /dev/tty
#printf "\n" > /dev/tty
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

38
lib/lib_clean_up.sh Normal file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Clean Up Wrapper on Trap on 'ERR' and 'EXIT'.
# Globals:
# ERROR_LOG
# KERNEL_INF
# KERNEL_SRT
# KERNEL_TMP
# WORKDIR
# Arguments:
# 1 : ${trap_on_exit_code} of trap_on_exit()
#######################################
clean_up() {
declare clean_exit_code="$1"
rm -f -- "${KERNEL_INF}"
rm -f -- "${KERNEL_SRT}"
rm -f -- "${KERNEL_TMP}"
rm -f /run/lock/ciss_live_builder.lock
if (( clean_exit_code == 0 )); then rm -f -- "${ERROR_LOG}"; fi
if [[ -f "${WORKDIR}/hosts.allow" ]]; then
rm -f "${WORKDIR}/hosts.allow"
fi
if [[ -f "${WORKDIR}/hosts.deny" ]]; then
rm -f "${WORKDIR}/hosts.deny"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

38
lib/lib_copy_integrity.sh Normal file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Copy Initial ISO aide Database into Host System
# Globals:
# BASH_SOURCE
# HANDLER_BUILD_DIR
# Arguments:
# None
# Returns:
# 0 : Aide Init DB copying successful.
#######################################
copy_db() {
# printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 '%s' starting ... \e[0m\n" "${BASH_SOURCE[0]}"
if [[ ! -d "${HANDLER_BUILD_DIR}/.integrity" ]]; then
mkdir -p "${HANDLER_BUILD_DIR}/.integrity"
fi
if cp -p "${HANDLER_BUILD_DIR}/chroot/var/lib/aide/"* "${HANDLER_BUILD_DIR}/.integrity/"; then
chmod 0400 "${HANDLER_BUILD_DIR}/.integrity/"*
# printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ '%s' successful applied. \e[0m\n" "${BASH_SOURCE[0]}"
return 0
else
printf "\e[91m++++ ++++ ++++ ++++ ++++ ++++ ++ ❌ '%s' NOT successful applied. \e[0m\n" "${BASH_SOURCE[0]}"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

60
lib/lib_debug.sh Normal file
View File

@@ -0,0 +1,60 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Debugger Wrapper for xtrace to Debug Log
# Globals:
# BASH_XTRACEFD
# DEBUG_LOG
# EARLY_DEBUG
# PS4
# SHELLOPTS
# dump_vars_initial
# var
# Arguments:
# None
#######################################
debugger() {
### Capture an initial snapshot of all variables (excluding '^(BASH|_).*')
# shellcheck disable=SC2155
declare -grx dump_vars_initial=$(mktemp)
{
declare var
while IFS= read -r var; do
declare -p "${var}" 2>/dev/null
done < <(compgen -v | grep -Ev '^(BASH|_).*')
} | sort >| "${dump_vars_initial}"
declare -grx EARLY_DEBUG=true
### Set a verbose PS4 prompt including timestamp, source, line, exit status, and function name
declare -grx PS4='\e[97m+\e[0m\e[96m$(date +%T.%4N)\e[0m\e[97m:\e[0m\e[92m[${BASH_SOURCE[0]}:${LINENO}]\e[0m\e[97m|\e[0m\e[93m${?}\e[0m\e[97m>\e[0m\e[95m${FUNCNAME[0]:-main}()\e[0m \e[97m>>\e[0m '
# shellcheck disable=SC2155
declare -grx DEBUG_LOG="/tmp/ciss_live_builder_$$_debug.log"
### Generates empty DEBUG_LOG
touch "${DEBUG_LOG}" && chmod 0600 "${DEBUG_LOG}"
### Open file descriptor 42 for writing to the debug log
exec 42>| "${DEBUG_LOG}"
### Write Debug Log Header https://www.gnu.org/software/bash/manual/html_node/Bash-Variables
### Determine the directory of this script, even if sourced.
# shellcheck disable=SC2155
declare script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
### Source the header from the same directory. This ensures we always load lib/lib_debug_header.sh correctly.
. "${script_dir}/lib_debug_header.sh"
# shellcheck disable=SC2119
debug_header "$#" "$*"
### Tell Bash to send xtrace output to FD 42
export BASH_XTRACEFD=42
### Enable inheritable shell options
export SHELLOPTS
### Turn on xtrace
set -x
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

56
lib/lib_debug_header.sh Normal file
View File

@@ -0,0 +1,56 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Generates Debug Log Header
# Globals:
# BASHOPTS
# BASH_VERSINFO
# EPOCHREALTIME
# EUID
# HOSTNAME
# PPID
# PWD
# UID
# VERSION
# Arguments:
# $0: Script Name $0
# $1: Argument Counter $#
# $2: Argument String $*
#######################################
debug_header() {
declare -r arg_counter="$1"
declare -r arg_string="$2"
{
printf "\e[97m+\e[0m\e[92m%s: CISS.debian.live.builder Debug Log \e[0m\n" "$(date +%T.%4N)"
printf "\e[97m+\e[0m\e[92m%s: Version : %s \e[0m\n" "$(date +%T.%4N)" "${VERSION}"
printf "\e[97m+\e[0m\e[92m%s: Epoch : %s \e[0m\n" "$(date +%T.%4N)" "${EPOCHREALTIME}"
printf "\e[97m+\e[0m\e[92m%s: Bash MAJ Release : %s \e[0m\n" "$(date +%T.%4N)" "${BASH_VERSINFO[0]}"
printf "\e[97m+\e[0m\e[92m%s: Bash MIN Version : %s \e[0m\n" "$(date +%T.%4N)" "${BASH_VERSINFO[1]}"
printf "\e[97m+\e[0m\e[92m%s: Bash Patch Level : %s \e[0m\n" "$(date +%T.%4N)" "${BASH_VERSINFO[2]}"
printf "\e[97m+\e[0m\e[92m%s: Bash Build Version : %s \e[0m\n" "$(date +%T.%4N)" "${BASH_VERSINFO[3]}"
printf "\e[97m+\e[0m\e[92m%s: Bash Release : %s \e[0m\n" "$(date +%T.%4N)" "${BASH_VERSINFO[4]}"
printf "\e[97m+\e[0m\e[92m%s: UID : %s \e[0m\n" "$(date +%T.%4N)" "${UID}"
printf "\e[97m+\e[0m\e[92m%s: EUID : %s \e[0m\n" "$(date +%T.%4N)" "${EUID}"
printf "\e[97m+\e[0m\e[92m%s: Hostname : %s \e[0m\n" "$(date +%T.%4N)" "${HOSTNAME}"
printf "\e[97m+\e[0m\e[92m%s: Script name : %s \e[0m\n" "$(date +%T.%4N)" "$0"
printf "\e[97m+\e[0m\e[92m%s: Argument Counter : %s \e[0m\n" "$(date +%T.%4N)" "${arg_counter}"
printf "\e[97m+\e[0m\e[92m%s: Argument String Original : %s \e[0m\n" "$(date +%T.%4N)" "${arg_string}"
printf "\e[97m+\e[0m\e[92m%s: Script PID : %s \e[0m\n" "$(date +%T.%4N)" "$$"
printf "\e[97m+\e[0m\e[92m%s: Script Parent PID : %s \e[0m\n" "$(date +%T.%4N)" "${PPID}"
printf "\e[97m+\e[0m\e[92m%s: Script work DIR : %s \e[0m\n" "$(date +%T.%4N)" "${PWD}"
printf "\e[97m+\e[0m\e[92m%s: Shell Options : %s \e[0m\n" "$(date +%T.%4N)" "$-"
printf "\e[97m+\e[0m\e[92m%s: BASHOPTS : %s \e[0m\n" "$(date +%T.%4N)" "${BASHOPTS}"
printf "\e[97m+\e[0m\e[92m%s: ==== Debug Log Begin ==== : \e[0m\n" "$(date +%T.%4N)"
} >&42
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,101 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Updates the Live ISO to use root password authentication for local console access.
# Globals:
# HANDLER_BUILD_DIR
# HASHED_PWD
# Arguments:
# None
# Returns:
# 0: In case no root password is desired.
#######################################
hardening_root_pw() {
if [[ -z ${HASHED_PWD} ]]; then
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ No Root Password for Console set, skipping root password hook.\e[0m\n"
# sleep 1
return 0
fi
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Setup Root Password for Console ... \e[0m\n"
# sleep 1
declare cfg_dir="${HANDLER_BUILD_DIR}/config/includes.chroot/etc/live"
declare cfg_file="${cfg_dir}/config.conf"
declare dropin_dir="${cfg_dir}/config.conf.d"
declare dropin_file="${dropin_dir}/20-root-password.conf"
mkdir -p "${dropin_dir}"
cat << 'EOF' >| "${dropin_dir}"/10-disable-autologin.conf
live-config.noautologin
EOF
if ! grep -q 'LIVE_CONFIGS=.*root-password' "${cfg_file}"; then
sed -i -E 's|LIVE_CONFIGS="([^"]*)"|LIVE_CONFIGS="\1 root-password"|' "${cfg_file}"
fi
declare clean_hash="${HASHED_PWD//\"/}"
printf 'live-config.root-password-hash=%s\n' "${clean_hash}" >| "${dropin_file}"
chmod 0600 "${dropin_file}"
chown root:root "${dropin_file}"
mkdir -p "${HANDLER_BUILD_DIR}/config/includes.chroot/root"
printf '%s\n' "${clean_hash}" >| "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.pwd"
chmod 0600 "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.pwd"
chown root:root "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.pwd"
mkdir -p "${HANDLER_BUILD_DIR}"/config/includes.chroot/etc/systemd/system/getty@tty1.service.d
cat << 'EOF' >| "${HANDLER_BUILD_DIR}"/config/includes.chroot/etc/systemd/system/getty@tty1.service.d/override.conf
[Service]
ExecStart=
#ExecStart=-/usr/sbin/agetty --noclear %I $TERM
ExecStart=-agetty --noclear %I $TERM
EOF
mkdir -p "${HANDLER_BUILD_DIR}"/config/includes.chroot/etc
cat << 'EOF' >| "${HANDLER_BUILD_DIR}"/config/includes.chroot/etc/securetty
tty1
tty2
tty3
tty4
tty5
tty6
EOF
mkdir -p "${HANDLER_BUILD_DIR}"/config/includes.chroot/usr/sbin
mkdir -p "${HANDLER_BUILD_DIR}"/config/includes.chroot/usr/bin
mkdir -p "${HANDLER_BUILD_DIR}"/config/includes.chroot/sbin
cp -af /usr/sbin/agetty "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/sbin/agetty"
cp -af /usr/sbin/agetty "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/bin/agetty"
cp -af /usr/sbin/agetty "${HANDLER_BUILD_DIR}/config/includes.chroot/sbin/agetty"
### Hotfix I
mkdir -p "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/systemd/system-generators"
cat << 'EOF' >| "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/systemd/system-generators/live-config-getty-generator"
#!/bin/sh
# bypass live-config-getty-generator
exit 0
EOF
chmod +x "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/systemd/system-generators/live-config-getty-generator"
### Hotfix II
#mkdir -p "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/systemd/system-generators"
#touch "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/systemd/system-generators/live-config-getty-generator"
#chmod -x "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/systemd/system-generators/live-config-getty-generator"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Setup Root Password for Console done. \e[0m\n"
# sleep 1
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

63
lib/lib_hardening_ssh.sh Normal file
View File

@@ -0,0 +1,63 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# SSH Hardening Ultra via TCP Wrapper
# Globals:
# WORKDIR
# handler_jumphost
# Arguments:
# None
#######################################
hardening_ssh() {
if ((${#handler_jumphost[@]} > 0)); then
declare allowed=""
cat << 'EOF' >| "${WORKDIR}/hosts.allow"
# /etc/hosts.allow: list of hosts that are allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: LOCAL @some_netgroup
# ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#
EOF
allowed=$(echo "${handler_jumphost[*]}" | tr '\n' ' ')
printf 'sshd: %s\n' "${allowed}" >> "${WORKDIR}/hosts.allow"
cat << 'EOF' >| "${WORKDIR}/hosts.deny"
# /etc/hosts.deny: list of hosts that are _not_ allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: some.host.name, .some.domain
# ALL EXCEPT in.fingerd: other.host.name, .other.domain
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#
# The PARANOID wildcard matches any host whose name does not match its
# address.
#
# You may wish to enable this to ensure any programs that don't
# validate looked-up hostnames still leave understandable logs. In past
# versions of Debian this has been the default.
# ALL: PARANOID
ALL: ALL
EOF
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

210
lib/lib_hardening_ultra.sh Normal file
View File

@@ -0,0 +1,210 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Wrapper for accompanying all CISS.2025 hardening features into the Live ISO image.
# Globals:
# HANDLER_ARCHITECTURE
# HANDLER_BUILD_DIR
# HANDLER_SSHPORT
# HANDLER_SSHPUBKEY
# WORKDIR
# handler_jumphost
# handler_jumphost_unique
# Arguments:
# None
#######################################
hardening_ultra() {
# shellcheck disable=SC2164
cd "${WORKDIR}"
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Copying ./config/bootloaders ... \e[0m\n"
if [[ ! -d "${HANDLER_BUILD_DIR}/config/bootloaders" ]]; then
mkdir -p "${HANDLER_BUILD_DIR}/config/bootloaders"
cp -af ./config/bootloaders "${HANDLER_BUILD_DIR}/config"
else
cp -af ./config/bootloaders "${HANDLER_BUILD_DIR}/config"
fi
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Copying ./config/bootloaders done.\e[0m\n"
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Copying ./config/includes.binary ... \e[0m\n"
if [[ ! -d "${HANDLER_BUILD_DIR}/config/includes.binary/boot/grub" ]]; then
mkdir -p "${HANDLER_BUILD_DIR}/config/includes.binary/boot/grub"
cp -af ./config/includes.binary "${HANDLER_BUILD_DIR}/config"
else
cp -af ./config/includes.binary "${HANDLER_BUILD_DIR}/config"
fi
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Copying ./config/includes.binary done.\e[0m\n"
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Copying ./config/hooks/live ... \e[0m\n"
if [[ ! -d "${HANDLER_BUILD_DIR}/config/hooks/live" ]]; then
mkdir -p "${HANDLER_BUILD_DIR}/config/hooks/live"
cp -af ./config/hooks/live "${HANDLER_BUILD_DIR}/config/hooks"
else
cp -af ./config/hooks/live "${HANDLER_BUILD_DIR}/config/hooks"
fi
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Copying ./config/hooks/live done.\e[0m\n"
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Copying ./config/includes.chroot ... \e[0m\n"
if [[ ! -d "${HANDLER_BUILD_DIR}/config/includes.chroot" ]]; then
mkdir -p "${HANDLER_BUILD_DIR}/config/includes.chroot"
cp -af ./config/includes.chroot "${HANDLER_BUILD_DIR}/config"
else
cp -af ./config/includes.chroot "${HANDLER_BUILD_DIR}/config"
fi
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Copying ./config/includes.chroot done.\e[0m\n"
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Copying ./config/package-lists ... \e[0m\n"
if [[ ! -d "${HANDLER_BUILD_DIR}/config/package-lists" ]]; then
mkdir -p "${HANDLER_BUILD_DIR}/config/package-lists"
fi
cp -af ./config/package-lists/live.list.common.chroot "${HANDLER_BUILD_DIR}/config/package-lists/live.list.chroot"
case "${HANDLER_ARCHITECTURE}" in
amd64)
declare arch_list="./config/package-lists/live.list.amd64.chroot"
declare arch_comment="# amd64 specific packages"
;;
arm64)
declare arch_list="./config/package-lists/live.list.arm64.chroot"
declare arch_comment="# arm64 specific packages"
;;
*)
printf "\e[91m++++ ++++ ++++ ++++ ++++ ++++ ++ ❌ Unsupported architecture '%s'.\e[0m\n" "${HANDLER_ARCHITECTURE}"
exit 1
;;
esac
declare pkgs
mapfile -t pkgs < <(
grep -v '^\s*#' "${arch_list}" | sed '/^\s*$/d'
)
awk -v comment="${arch_comment}" -v n_pkgs="${#pkgs[@]}" -v pkgs="$(printf '%s\n' "${pkgs[@]}")" '
BEGIN {
split(pkgs, pkg_arr, "\n")
inserted = 0
}
{
# Detect the vim-modeline (last line marker)
if ($0 ~ /^# vim:.*$/ && !inserted) {
print comment
for (i = 1; i <= length(pkg_arr); i++) {
print pkg_arr[i]
}
inserted = 1
}
print
}
' "${HANDLER_BUILD_DIR}/config/package-lists/live.list.chroot" > temp && mv temp "${HANDLER_BUILD_DIR}/config/package-lists/live.list.chroot"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Copying ./config/package-lists done.\e[0m\n"
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Updating SSH Keys, Ports ... \e[0m\n"
if [[ ! -d "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh" ]]; then
mkdir -p "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh"
cp -af "${HANDLER_SSHPUBKEY}/authorized_keys" "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh"
chmod 0600 "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/authorized_keys"
chown root:root "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/authorized_keys"
declare -r sshport="${HANDLER_SSHPORT:-22}"
sed -i "s|^port = MUST_BE_SET|port = ${sshport}|" "${HANDLER_BUILD_DIR}/config/hooks/live/9950_fail2ban_hardening.chroot"
sed -i "s|^declare -r SSHPORT=\"MUST_BE_SET\"|declare -r SSHPORT=\"${sshport}\"|" "${HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot"
sed -i "s|^Port MUST_BE_CHANGED|Port ${sshport}|" "${HANDLER_BUILD_DIR}/config/includes.chroot/etc/ssh/sshd_config"
if [[ ${#handler_jumphost[@]} -gt 0 ]]; then
declare file="${HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot"
sed -i "/^ufw allow in \"\${SSHPORT}\"\/tcp comment 'Incoming SSH (Custom-Port)'$/d" "${file}"
declare line
line=$(grep -n '^ufw default deny forward$' "${file}" | cut -d: -f1)
if [[ -z "${line}" ]]; then
printf "\e[91m++++ ++++ ++++ ++++ ++++ ++++ ++ ❌'ufw default deny forward' not found in: '%s'\e[0m\n" "${file}" >&2
exit 1
fi
declare host
for host in "${handler_jumphost_unique[@]}"; do
((line++))
sed -i "${line}a ufw allow from \"${host}\" to any port \"${sshport}\" proto tcp comment \"Incoming SSH ([${host}]:${sshport})\"" "$file"
done
fi
else
cp -af "${HANDLER_SSHPUBKEY}/authorized_keys" "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh"
chmod 0600 "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/authorized_keys"
chown root:root "${HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/authorized_keys"
declare -r sshport="${HANDLER_SSHPORT:-22}"
sed -i "s|^port = MUST_BE_SET|port = ${sshport}|" "${HANDLER_BUILD_DIR}/config/hooks/live/9950_fail2ban_hardening.chroot"
sed -i "s|^declare -r SSHPORT=\"MUST_BE_SET\"|declare -r SSHPORT=\"$sshport\"|" "${HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot"
sed -i "s|^Port MUST_BE_CHANGED|Port ${sshport}|" "${HANDLER_BUILD_DIR}/config/includes.chroot/etc/ssh/sshd_config"
if [[ ${#handler_jumphost_unique[@]} -gt 0 ]]; then
declare file="${HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot"
sed -i "/^ufw allow in \"\${SSHPORT}\"\/tcp comment 'Incoming SSH (Custom-Port)'$/d" "${file}"
declare line
line=$(grep -n '^ufw default deny forward$' "${file}" | cut -d: -f1)
if [[ -z "${line}" ]]; then
printf "\e[91m❌ Error: 'ufw default deny forward' not found in: '%s'\e[0m\n" "${file}" >&2
exit 1
fi
declare host
for host in "${handler_jumphost_unique[@]}"; do
((line++))
sed -i "${line}a ufw allow from \"${host}\" to any port \"${sshport}\" proto tcp comment \"Incoming SSH ([${host}]:${sshport})\"" "$file"
done
fi
fi
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Updating SSH Keys, Ports done. \e[0m\n"
if [[ -f "${WORKDIR}/hosts.allow" ]]; then
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 SSH Hardening Ultra ... \e[0m\n"
cp -af "${WORKDIR}/hosts.allow" "${HANDLER_BUILD_DIR}/config/includes.chroot/etc"
cp -af "${WORKDIR}/hosts.deny" "${HANDLER_BUILD_DIR}/config/includes.chroot/etc"
chmod 0644 "${HANDLER_BUILD_DIR}/config/includes.chroot/etc/hosts.allow"
chmod 0644 "${HANDLER_BUILD_DIR}/config/includes.chroot/etc/hosts.deny"
rm -f "${WORKDIR}/hosts.allow"
rm -f "${WORKDIR}/hosts.deny"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ SSH Hardening Ultra done.\e[0m\n"
fi
if ((${#handler_jumphost[@]} > 0)); then
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Updating fail2ban Jumphosts IPs ... \e[0m\n"
# Join array entries with spaces, preserving any newlines
declare ips="${handler_jumphost[*]}"
# Flatten to a single line and strip literal brackets []
declare flat_ips
flat_ips=$(printf "%s" "${ips}" | tr '\n' ' ' | tr -d '[]')
# flat_ips now contains e.g., "123.128.111.42 2a03:ffff:0815:4711:... 2a03:.../64"
# Perform an in-place replacement of MUST_BE_SET with the cleaned list
sed -i -e "s|^\(ignoreip[[:space:]]*=[[:space:]]*127\.0\.0\.0/8 ::1[[:space:]]*\)MUST_BE_SET|\1${flat_ips}|" \
"${HANDLER_BUILD_DIR}/config/hooks/live/9950_fail2ban_hardening.chroot"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Updating fail2ban Jumphosts IPs done. \e[0m\n"
else
printf "\e[93m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 No jump hosts configured, removing placeholder ... \e[0m\n"
sed -i \
-e "s|^\(ignoreip[[:space:]]*=[[:space:]]*127\.0\.0\.0/8 ::1\)[[:space:]]*MUST_BE_SET|\1|" \
-e "s|\(ignoreip[[:space:]]*=[[:space:]]*127\.0\.0\.0/8 ::1\)[[:space:]]*$|\1|" \
"${HANDLER_BUILD_DIR}/config/hooks/live/9950_fail2ban_hardening.chroot"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Placeholder removed. \e[0m\n"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

36
lib/lib_helper_ip.sh Normal file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# IP Notation cleaner for pure IP output only
# Globals:
# handler_jumphost
# handler_jumphost_unique
# Arguments:
# None
#######################################
clean_ip() {
declare host
declare stripped
for host in "${handler_jumphost[@]}"; do
# Remove leading '[' and trailing ']'
stripped="${host#\[}"
stripped="${stripped%\]}"
# Skip if it contains a slash (CIDR range)
if [[ ${stripped} == */* ]]; then
continue
fi
# Directly append, no duplicate check
declare -ga handler_jumphost_unique+=("${stripped}")
done
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

44
lib/lib_lb_build_start.sh Normal file
View File

@@ -0,0 +1,44 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Wrapper to write a new 'lb config' environment.
# Globals:
# BUILD_LOG
# ERR_UNCRITICAL
# HANDLER_BUILD_DIR
# Arguments:
# None
#######################################
lb_build_start() {
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🔨 Start Build... Log file: %s \e[0m\n" "${BUILD_LOG}"
# sleep 1
# shellcheck disable=SC2164
cd "${HANDLER_BUILD_DIR}"
if lb build --color 2>&1 | tee "${BUILD_LOG}"; then
printf "\e[92m✅ Build successfully completed.\e[0m\n"
else
printf "\e[91m❌ Build failed!\e[0m\n" >&2
exit "${ERR_UNCRITICAL}"
fi
# shellcheck disable=SC2155
declare iso_file=$(find . -maxdepth 1 -type f -name "*.iso" | sort | tail -n1)
if [[ -z ${iso_file} || ! -f ${iso_file} ]]; then
printf "\e[91m❌ No ISO Image found.\e[0m\n" >&2
exit "${ERR_UNCRITICAL}"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,55 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Wrapper for 'lb config' - set up a build environment or deleting old build artifacts.
# Globals:
# HANDLER_BUILD_DIR
# Arguments:
# $0: Script-name
#######################################
lb_config_start() {
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 '%s' starting ... \e[0m\n" "${0}"
if [[ ! -d ${HANDLER_BUILD_DIR} ]]; then
mkdir -p "${HANDLER_BUILD_DIR}"
# shellcheck disable=SC2164
cd "${HANDLER_BUILD_DIR}"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ '%s' created. \e[0m\n" "${HANDLER_BUILD_DIR}"
else
# shellcheck disable=SC2164
cd "${HANDLER_BUILD_DIR}"
fi
if [[ ! -d "${HANDLER_BUILD_DIR}/.build" ]]; then
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Preparing environment ... \e[0m\n"
# Start lb config in a completely detached shell
bash -c "lb config" &
disown
sleep 1
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Preparing environment done.\e[0m\n"
else
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Deleting former config, binary and cache ... \e[0m\n"
rm -f ./config/binary
rm -f ./config/bootstrap
rm -f ./config/chroot
rm -f ./config/common
rm -f ./config/source
rm -f ./*.{contents,files,iso,bz2,packages}
# Start lb clean in a completely detached shell
bash -c "lb clean && lb clean --binary --cache" &
disown
sleep 1
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Deleting former config, binary and cache done.\e[0m\n"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

113
lib/lib_lb_config_write.sh Normal file
View File

@@ -0,0 +1,113 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Wrapper to write a new 'lb config' environment.
# Globals:
# HANDLER_ARCHITECTURE
# HANDLER_BUILD_DIR
# HANDLER_ISO_COUNTER
# VERSION
# WORKDIR
# kernel
# Arguments:
# None
#######################################
lb_config_write() {
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 Writing new config ... \e[0m\n"
lb config \
--apt apt \
--apt-indices true \
--apt-recommends true \
--apt-secure true \
--apt-source-archives true \
--architecture "${HANDLER_ARCHITECTURE}" \
--archive-areas main contrib non-free non-free-firmware \
--backports true \
--binary-filesystem fat32 \
--binary-image iso-hybrid \
--bootappend-install "auto=true priority=critical clock-setup/utc=true console-setup/ask_detect=false debian-installer/country=US debian-installer/language=en debian-installer/locale=en_US.UTF-8 keyboard-configuration/xkb-keymap=de keyboard-configuration/model=pc105 localechooser/supported-locales=en_US.UTF-8 time/zone=Europe/Lisbon splash audit_backlog_limit=8192 audit=1 cfi=kcfi debugfs=off efi=disable_early_pci_dma efi_no_storage_paranoia hardened_usercopy=1 ia32_emulation=0 init_on_alloc=1 init_on_free=1 iommu=force kfence.sample_interval=100 kvm.nx_huge_pages=force l1d_flush=on lockdown=confidentiality loglevel=0 mce=0 mitigations=auto,nosmt mmio_stale_data=full,nosmt oops=panic page_alloc.shuffle=1 page_poison=1 panic=-1 pti=on random.trust_bootloader=off random.trust_cpu=off randomize_kstack_offset=on randomize_va_space=2 retbleed=auto,nosmt rodata=on tsx=off vdso32=0 vsyscall=none" \
--bootappend-live "boot=live verify-checksums components nocomponents=cdi-starter locales=en_US.UTF-8 keyboard-layouts=de keyboard-model=pc105 keyboard-options= keyboard-variants= noeject nopersistence ramdisk-size=1024M splash swap=true timezone=Europe/Lisbon toram audit_backlog_limit=8192 audit=1 cfi=kcfi debugfs=off efi=disable_early_pci_dma efi_no_storage_paranoia hardened_usercopy=1 ia32_emulation=0 init_on_alloc=1 init_on_free=1 iommu=force kfence.sample_interval=100 kvm.nx_huge_pages=force l1d_flush=on lockdown=confidentiality loglevel=0 mce=0 mitigations=auto,nosmt mmio_stale_data=full,nosmt oops=panic page_alloc.shuffle=1 page_poison=1 panic=-1 pti=on random.trust_bootloader=off random.trust_cpu=off randomize_kstack_offset=on randomize_va_space=2 retbleed=auto,nosmt rodata=on tsx=off vdso32=0 vsyscall=none" \
--bootloaders grub-efi \
--cache true \
--checksums sha512 sha256 md5 \
--chroot-filesystem squashfs \
--chroot-squashfs-compression-level 22 \
--chroot-squashfs-compression-type zstd \
--color \
--compression bzip2 \
--debconf-frontend noninteractive \
--debconf-priority critical \
--debian-installer cdrom \
--debian-installer-distribution bookworm \
--debian-installer-gui true \
--debian-installer-preseedfile "preseed.cfg" \
--debug \
--distribution bookworm \
--distribution-binary bookworm \
--distribution-chroot bookworm \
--firmware-binary true \
--firmware-chroot true \
--hdd-label "CENTURIONLIVE" \
--image-name "ciss-debian-live-${HANDLER_ISO_COUNTER}" \
--initramfs "live-boot" \
--initramfs-compression gzip \
--initsystem systemd \
--iso-application "CISS.debian.live.builder: ${VERSION} - Debian-Live-Build: 20230502 - Debian-Installer: bookworm" \
--iso-preparer '(C) 2018-2025, Centurion Intelligence Consulting Agency (TM), Lisboa, Portugal' \
--iso-publisher '(P) 2018-2025, Centurion Press (TM) - powered by https://coresecret.eu/ - contact@coresecret.eu' \
--iso-volume 'CISS.debian.live' \
--linux-flavours "${kernel}" \
--linux-packages linux-image \
--loadlin true \
--memtest memtest86+ \
--mirror-binary 'https://deb/debian.org/debian/' \
--mirror-binary-security 'https://security.debian.org/' \
--mirror-bootstrap 'https://deb.debian.org/debian/' \
--mirror-chroot 'https://deb.debian.org/debian/' \
--mirror-chroot-security 'https://security.debian.org/' \
--mirror-debian-installer 'https://deb.debian.org/debian/' \
--mode debian \
--parent-archive-areas main contrib non-free non-free-firmware \
--parent-debian-installer-distribution bookworm \
--parent-distribution bookworm \
--parent-distribution-binary bookworm \
--parent-distribution-chroot bookworm \
--parent-mirror-binary 'https://deb.debian.org/debian/' \
--parent-mirror-binary-security 'https://security.debian.org/' \
--parent-mirror-bootstrap 'https://deb.debian.org/debian/' \
--parent-mirror-chroot 'https://deb.debian.org/debian/' \
--parent-mirror-chroot-security 'https://security.debian.org/' \
--parent-mirror-debian-installer 'https://deb.debian.org/debian/' \
--security true \
--system live \
--source false \
--source-images tar \
--uefi-secure-boot auto \
--updates true \
--utc-time true \
--verbose
sleep 1
sed -i 's/LB_CHECKSUMS="sha512 md5"/LB_CHECKSUMS="sha512 sha384 sha256"/1' ./config/binary
sed -i 's/LB_DM_VERITY=""/LB_DM_VERITY="false"/1' ./config/binary
mkdir -p "${HANDLER_BUILD_DIR}"/config/includes.chroot/usr/lib/live/boot
cp -a "${WORKDIR}/scripts/live-boot/0030-verify-checksums" "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/live/boot/0030-verify-checksums"
chmod 0755 "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/live/boot/0030-verify-checksums"
chown root:root "${HANDLER_BUILD_DIR}/config/includes.chroot/usr/lib/live/boot/0030-verify-checksums"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ Writing new config done.\e[0m\n"
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,45 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Notes Textbox
# Arguments:
# None
#######################################
provider_netcup() {
if "${handler_netcup_ipv6}"; then
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 %s starting ... \e[0m\n" "${BASH_SOURCE[0]}"
declare handler_netcup_ipv6_string="${handler_netcup_ipv6_array[*]}"
mkdir -p "${HANDLER_BUILD_DIR}"/config/includes.chroot/etc/network/interfaces.d
cat << EOF >| "${HANDLER_BUILD_DIR}"/config/includes.chroot/etc/network/interfaces.d/99-netcup-static
### Static IPv6 Address for Netcup Root Server
iface ens3 inet6 static
address ${handler_netcup_ipv6_string}/128
### dns01.eddns.eu dns02.eddns.de
dns-nameservers 2a01:4f9:c012:a813:135:181:207:105 2a0a:4cc0:1:e6:89:58:62:53
gateway fe80::1
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
sed -i "s|MUST_BE_REPLACED|${handler_netcup_ipv6_string}|g" "${WORKDIR}/scripts/etc/network/9999_interfaces_update_netcup.chroot"
rm -f "${HANDLER_BUILD_DIR}/config/hooks/live/9999_interfaces_update.chroot"
cp "${WORKDIR}/scripts/etc/network/9999_interfaces_update_netcup.chroot" "${HANDLER_BUILD_DIR}/config/hooks/live/9999_interfaces_update.chroot"
chmod 0755 "${HANDLER_BUILD_DIR}/config/hooks/live/9999_interfaces_update.chroot"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ %s successful applied. \e[0m\n" "${BASH_SOURCE[0]}"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

96
lib/lib_run_analysis.sh Normal file
View File

@@ -0,0 +1,96 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-07; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: ZIMNOL, André H.; Private Contributor
# SPDX-FileCopyrightText: 2025; ZIMNOL, André H.; <debian@zimnol.eu>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Wrapper for statistic functions of the final build.
# Globals:
# BUILD_LOG
# CHROOT_DIR
# ERR_UNCRITICAL
# HANDLER_BUILD_DIR
# PACKAGES_FILE
# Arguments:
# None
#######################################
run_analysis() {
# shellcheck disable=SC2164
cd "${HANDLER_BUILD_DIR}"
# shellcheck disable=SC2155
declare iso_file=$(find . -maxdepth 1 -name "*.iso" -printf "%f\n" | sort | tail -n1)
if [[ -z ${iso_file} || ! -f ${iso_file} ]]; then
printf "\e[91m❌ No ISO Image found.\e[0m\n" >&2
exit "${ERR_UNCRITICAL}"
fi
printf "\e[92m📊 Start analysis of : %s ... \e[0m\n" "${iso_file}"
# shellcheck disable=SC2155
declare iso_size_hr=$(du -h "${iso_file}" | awk '{print $1}')
# shellcheck disable=SC2155
declare iso_size_bytes=$(du -b "${iso_file}" | awk '{print $1}')
# shellcheck disable=SC2155
declare chroot_size_hr=$(du -sh "${CHROOT_DIR}" 2> /dev/null | awk '{print $1}')
# shellcheck disable=SC2155
declare chroot_size_bytes=$(du -sb "${CHROOT_DIR}" 2> /dev/null | awk '{print $1}')
# shellcheck disable=SC2155
declare compression=$(awk -v iso="${iso_size_bytes}" -v chroot="${chroot_size_bytes}" 'BEGIN { printf "%.2f%%", 100 * iso / chroot }')
# shellcheck disable=SC2155
declare package_count=$(wc -l < "${PACKAGES_FILE}" 2> /dev/null || echo "nicht gefunden")
# shellcheck disable=SC2155
declare squash_cpu_used="$(grep -m1 -oP 'Using \K[0-9]+' "${BUILD_LOG}")"
if [[ -f "${BUILD_LOG}" ]]; then
# shellcheck disable=SC2155
declare start_line=$(grep 'lb build' "${BUILD_LOG}" | head -n1 || true)
# shellcheck disable=SC2155
declare end_line=$(grep 'lb source' "${BUILD_LOG}" | tail -n1 || true)
if [[ -n "${start_line}" && -n "${end_line}" ]]; then
# shellcheck disable=SC2155
declare start_epoch=$(echo "${start_line}" | sed -E 's/^\[([0-9:-]+ [0-9:]+)\].*/\1/' | xargs -I{} date -d "{}" +%s)
# shellcheck disable=SC2155
declare end_epoch=$(echo "${end_line}" | sed -E 's/^\[([0-9:-]+ [0-9:]+)\].*/\1/' | xargs -I{} date -d "{}" +%s)
# shellcheck disable=SC2155
declare duration_sec=$((end_epoch - start_epoch))
# shellcheck disable=SC2155
declare duration_min=$((duration_sec / 60))
# shellcheck disable=SC2155
declare duration_rest=$((duration_sec % 60))
# shellcheck disable=SC2155
declare build_duration=$(printf "%02dm:%02ds" "${duration_min}" "${duration_rest}")
else
declare build_duration="(Timestamp not found)"
fi
else
declare build_duration="(No log file found)"
fi
# shellcheck disable=SC2155
declare sha_sum=$(sha256sum "$iso_file" | tee "$iso_file.sha256" | awk '{print $1}')
# shellcheck disable=SC2155
declare time=$(date '+%Y-%m-%d %H:%M:%S')
printf "\e[92m🧾 === Build summary === \e[0m\n"
printf "\e[92m────────────────────────────────────────────────────────────────────────────────────────\e[0m\n"
printf "\e[97m📦 ISO-File : %s \e[0m\n" "${iso_file}"
printf "\e[97m📀 ISO-Size : %s \e[0m\n" "${iso_size_hr}"
printf "\e[97m📂 Chroot-Size : %s \e[0m\n" "${chroot_size_hr}"
printf "\e[97m📉 Compression-level : %s \e[0m\n" "${compression}"
printf "\e[97m📦 Packages : %s \e[0m\n" "${package_count}"
printf "\e[97m⏱ Build Time : %s \e[0m\n" "${build_duration}"
printf "\e[97m🧠 CPUs for SquashFS : %s \e[0m\n" "${squash_cpu_used}"
printf "\e[97m🔐 SHA256SUM : %s \e[0m\n" "${sha_sum}"
printf "\e[92m────────────────────────────────────────────────────────────────────────────────────────\e[0m\n"
printf "\e[97m📅 Analysis Time : %s \e[0m\n" "${time}"
printf "\e[92m✅ Analysis completed.\e[0m\n"
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

85
lib/lib_sanitizer.sh Normal file
View File

@@ -0,0 +1,85 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.hardened.installer framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Argument Check Wrapper
# Arguments:
# $1: "$@" of ./ciss_live_builder.sh
#######################################
arg_check() {
declare a
declare sanitized_args=()
for a in "$@"; do
sanitized_args+=( "$(sanitize_arg "${a}")" )
done
set -- "${sanitized_args[@]}"
}
#######################################
# Function to sanitize a single argument
# Globals:
# ERROR_LOG
# ERR_INVLD_CHAR
# Arguments:
# $1: Argument to check
#######################################
sanitize_arg() {
declare input="$1"
# Define allowed characters:
# letters, digits, dot, underscore, slash, equals, [, ], colon, double-quote, hyphen, space.
declare allowed='a-zA-Z0-9._/=\[\]:"\- '
declare disallowed
disallowed=$(printf '%s' "${input}" | tr -d "${allowed}")
if [[ -n ${disallowed} ]]; then
{
printf "❌ Invalid character : '%s'. \n" "${disallowed//?/& }"
printf "❌ in argument : '%s'. \n" "${input}"
printf "❌ Allowed Characters : 'a-z A-Z 0-9 . _ / = [ ] : \" - ' \n"
printf "\n"
} >> "${ERROR_LOG}"
boot_screen_cleaner
printf "\e[91m❌ Invalid character : '%s'. \e[0m\n" "${disallowed//?/& }" >&2
printf "\e[91m❌ in argument : '%s'. \e[0m\n" "${input}" >&2
printf "\e[91m❌ Allowed Characters : 'a-z A-Z 0-9 . _ / = [ ] : \" - ' \e[0m\n" >&2
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_INVLD_CHAR}"
else
printf '%s' "${input}"
fi
}
#######################################
# Function to remove any character not in the allowed set
# Arguments:
# $1: String to Sanitize
#######################################
sanitize_string() {
declare input="$1"
# Define allowed characters:
# letters, digits, dot, underscore, slash, equals, [, ], colon, double-quote, hyphen, space.
declare allowed='a-zA-Z0-9._/=\[\]:"\- '
printf '%s' "${input}" | tr -cd "${allowed}"
}
#######################################
# Function to escape all shell metacharacters
# Arguments:
# $1: String to Sanitize
#######################################
sanitize_shell_literal() {
declare input="$1"
# %q quotes the string so that the shell re-reads it as the original literal
printf '%q' "${input}"
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

162
lib/lib_trap_on_err.sh Normal file
View File

@@ -0,0 +1,162 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Print Error Message for Trap on 'ERR' in ${ERROR_LOG}
# Globals:
# ARGUMENTS_COUNT
# ARG_STR_ORG_INPUT
# ARG_STR_SANITIZED
# DEBUG_LOG
# EARLY_DEBUG
# ERROR_LOG
# VAR_LOG
# VERSION
# errcmmd
# errcode
# errfunc
# errline
# errscrt
# Arguments:
# None
#######################################
print_file_err() {
{
printf "❌ CISS.debian.live.builder Script failed. \n"
printf "❌ Version : %s \n" "${VERSION}"
printf "❌ Environment : %s \n" "${SYSTEM_VAR}"
printf "❌ Error : %s \n" "${errcode}"
printf "❌ Line : %s \n" "${errline}"
printf "❌ Script : %s \n" "${errscrt}"
printf "❌ Function : %s \n" "${errfunc}"
printf "❌ Command : %s \n" "${errcmmd}"
printf "❌ Script Runtime : %s \n" "${SECONDS}"
printf "❌ Arguments Counter : %s \n" "${ARGUMENTS_COUNT}"
printf "❌ Arguments Original : %s \n" "${ARG_STR_ORG_INPUT}"
printf "❌ Arguments Sanitized : %s \n" "${ARG_STR_SANITIZED}"
if "${EARLY_DEBUG}"; then
printf "❌ Vars Dump saved at : %s \n" "${VAR_LOG}"
printf "❌ Debug Log saved at : %s \n" "${DEBUG_LOG}"
printf "❌ cat %s \n" "${DEBUG_LOG}"
fi
printf "\n"
} >> "${ERROR_LOG}"
}
#######################################
# Print Error Message for Trap on 'ERR' on Terminal
# Globals:
# ARGUMENTS_COUNT
# ARG_STR_ORG_INPUT
# ARG_STR_SANITIZED
# DEBUG_LOG
# EARLY_DEBUG
# ERROR_LOG
# VAR_LOG
# VERSION
# errcmmd
# errcode
# errfunc
# errline
# errscrt
# Arguments:
# None
#######################################
print_scr_err() {
printf "\e[91m❌ CISS.debian.live.builder Script failed. \e[0m\n" >&2
printf "\e[91m❌ Version : %s \e[0m\n" "${VERSION}" >&2
printf "\e[91m❌ Environment : %s \e[0m\n" "${SYSTEM_VAR}" >&2
printf "\e[91m❌ Error : %s \e[0m\n" "${errcode}" >&2
printf "\e[91m❌ Line : %s \e[0m\n" "${errline}" >&2
printf "\e[91m❌ Script : %s \e[0m\n" "${errscrt}" >&2
printf "\e[91m❌ Function : %s \e[0m\n" "${errfunc}" >&2
printf "\e[91m❌ Command : %s \e[0m\n" "${errcmmd}" >&2
printf "\e[91m❌ Script Runtime : %s \e[0m\n" "${SECONDS}" >&2
printf "\e[91m❌ Arguments Counter : %s \e[0m\n" "${ARGUMENTS_COUNT}" >&2
printf "\e[91m❌ Arguments Original : %s \e[0m\n" "${ARG_STR_ORG_INPUT}" >&2
printf "\e[91m❌ Arguments Sanitized : %s \e[0m\n" "${ARG_STR_SANITIZED}" >&2
printf "\e[91m❌ Error Log saved at : %s \e[0m\n" "${ERROR_LOG}" >&2
printf "\e[91m❌ cat %s \e[0m\n" "${ERROR_LOG}" >&2
if "${EARLY_DEBUG}"; then
printf "\e[91m❌ Vars Dump saved at : %s \e[0m\n" "${VAR_LOG}" >&2
printf "\e[91m❌ Debug Log saved at : %s \e[0m\n" "${DEBUG_LOG}" >&2
printf "\e[91m❌ cat %s \e[0m\n" "${DEBUG_LOG}" >&2
fi
printf "\n"
}
#######################################
# Trap function to be called on 'ERR'.
# Globals:
# EARLY_DEBUG
# Arguments:
# $1: $?
# $2: ${BASH_SOURCE[0]}
# $3: ${LINENO}
# $4: ${FUNCNAME[0]:-main}
# $5: ${BASH_COMMAND}
#######################################
trap_on_err() {
declare -g errcode="$1"
declare -g errscrt="$2"
declare -g errline="$3"
declare -g errfunc="$4"
declare -g errcmmd="$5"
trap - ERR
if "${EARLY_DEBUG}"; then dump_user_vars; fi
clean_up "${errcode}"
clean_screen
print_file_err
print_scr_err
}
#######################################
# Gather all user-defined variables (name and value)
# Globals:
# VAR_LOG
# VERSION
# dump_vars_initial
# var
# Arguments:
# None
#######################################
dump_user_vars() {
### Capture the final snapshot of all variables (excluding '^(BASH|_).*')
# shellcheck disable=SC2155
declare dump_vars_final=$(mktemp)
set +x
{
declare var
while IFS= read -r var; do
declare -p "${var}" 2>/dev/null
done < <(compgen -v | grep -Ev '^(BASH|_).*')
} | sort >| "${dump_vars_final}"
set -x
{
printf "✅ CISS.debian.live.builder Config Variable Dump. \n"
printf "✅ Version : %s \n" "${VERSION}"
printf "\n"
printf "===== Initial VAR Environment ===== \n"
} >> "${VAR_LOG}"
comm -23 "${dump_vars_initial}" "${dump_vars_final}" >> "${VAR_LOG}" || true
{
printf "\n"
printf "===== Final VAR Environment ===== \n"
} >> "${VAR_LOG}"
comm -13 "${dump_vars_initial}" "${dump_vars_final}" >> "${VAR_LOG}" || true
rm "${dump_vars_initial}" "${dump_vars_final}"
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

66
lib/lib_trap_on_exit.sh Normal file
View File

@@ -0,0 +1,66 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Trap function to be called on 'EXIT'.
# Globals:
# EARLY_DEBUG
# Arguments:
# $1: $?
#######################################
trap_on_exit() {
declare -r trap_on_exit_code="$1"
trap - EXIT
if (( trap_on_exit_code == 0 )); then
if "${EARLY_DEBUG}"; then dump_user_vars; fi
clean_up "${trap_on_exit_code}"
print_scr_exit "${trap_on_exit_code}"
exit 0
else
exit "${trap_on_exit_code}"
fi
}
#######################################
# Print Success Message for Trap on 'EXIT' on 'stdout'
# Globals:
# DEBUG
# DEBUG_LOG
# HANDLER_BUILD_DIR
# VAR_LOG
# handler_success
# Arguments:
# $1: ${trap_on_exit_code} of trap_on_exit()
#######################################
print_scr_exit() {
declare -r print_scr_exit_code="$1"
if (( print_scr_exit_code == 0 )); then
if [[ "${handler_success}" == "true" ]]; then
printf "\n"
printf "\e[92m✅ CISS.debian.live.builder Script successful. \e[0m\n"
printf "\e[92m✅ Aide Initial DB at: %s \e[0m\n" "${HANDLER_BUILD_DIR}/.integrity/"
printf "\e[92m✅ Exited with Status: %s \e[0m\n" "${print_scr_exit_code}"
printf "\n"
if [[ "${EARLY_DEBUG}" == "true" ]]; then
printf "\e[92m✅ Script Runtime : %s \e[0m\n" "${SECONDS}"
printf "\e[92m✅ Vars Dump saved at: %s \e[0m\n" "${VAR_LOG}"
printf "\e[92m✅ Debug Log saved at: %s \e[0m\n" "${DEBUG_LOG}"
printf "\e[92m✅ cat %s \e[0m\n" "${DEBUG_LOG}"
printf "\n"
fi
printf "\e[95m💷 Please consider donating to my work at: \e[0m\n"
printf "\e[95m🔗 https://coresecret.eu/spenden/ \e[0m\n"
printf "\n"
fi
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

141
lib/lib_usage.sh Normal file
View File

@@ -0,0 +1,141 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 20242025; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
#######################################
# Usage Wrapper CISS.debian.live.builder
# Globals:
# ERR_UNCRITICAL
# Arguments:
# $0: Script name
#######################################
usage() {
clear
cat << EOF
$(echo -e "\e[92mCISS.debian.live.builder\e[0m")
$(echo -e "\e[92mMaster V8.02.512.2025.05.30\e[0m")
$(echo -e "\e[97m(c) Marc S. Weidner, 2018 - 2025\e[0m")
$(echo -e "\e[97m(p) Centurion Press, 2024 - 2025\e[0m")
$(echo -e "\e[95mhttps://coresecret.eu/\e[0m")
$(echo -e "\e[97mA lightweight Shell Wrapper for building a hardened Debian Bookworm Live ISO Image.\e[0m")
"${0} <option>", where <option> is one or more of:
--help, -h
What you're looking at.
--architecture <STRING> one of <amd64 | arm64>
A string reflecting the architecture of the Live System.
MUST be provided.
--build-directory </path/to/build_directory>
Where the Debian Live Build Image should be generated.
MUST be provided.
--change-splash <STRING> one of <club | hexagon>
A string reflecting the GRub Boot Screen Splash you want to use.
If omitted defaults to "./.archive/background/club.png".
--cdi (Experimental Feature)
This option generates a boot menu entry to start the forthcoming
'CISS.debian.installer', which will be executed after
the system has successfully booted up.
--contact, -c
Displays contact information of the author.
--control <INTEGER>
An integer that reflects the version of your Live ISO Image.
MUST be provided.
--debug
Enables debug logging for the main program routine. Detailed logging
information are written to "/tmp/ciss_live_builder_$$.log"
--dhcp-centurion
If a DHCP lease is provided, the provider's nameserver will be overridden,
and only the hardened, privacy-focused Centurion DNS servers will be used:
- https://dns01.eddns.eu/
- https://dns02.eddns.de/
--jump-host <IP | IP | ... >
Provide up to 10 IPs for /etc/host.allow whitelisting of SSH access.
Could be either IPv4 and / or IPv6 addresses and / or CCDIR notation.
If provided, than it MUST be a <SPACE> separated list.
IPv6 addresses MUST be encapsulated with [], e.g., [1234::abcd/64].
--log-statistics-only
Provides statistic only after successful building a
CISS.debian.live-ISO. While enabling "--log-statistics-only"
the argument "--build-directory" MUST be provided while
all further options MUST be omitted.
--provider-netcup-ipv6
Activates IPv6 support for Netcup Root Server. One unique
IPv6 address MUST be provided in this case.
--renice-priority <PRIORITY>
Reset the nice priority value of the script and all its children
to the desired PRIORITY. MUST be an integer (between "-19" and 19).
Negative (higher) values MUST be enclosed in double quotes '"'.
--reionice-priority <CLASS> <PRIORITY>
Reset the ionice priority value of the script and all its children
to the desired CLASS. MUST be an integer:
1: realtime
2: best-effort
3: idle
defaults to "2".
PRIORITY MUST be an integer:
between 0 (highest) and 7 (lowest) priority.
defaults to "4".
A real-time I/O process can significantly slow down other processes
or even cause them to starve if it continuously requests I/O.
--root-password-file </path/to/password.txt>
Password file for 'root', if given, MUST be a string of 20 to 64 characters,
and MUST NOT contain the special character '"'.
If the argument is omitted, no further login authentication is required for
the local console. The root password is hashed with an 16 Byte '/dev/random'
generated SALT and SHA512 Hashing function and 8,388,608 rounds. Immediately
after Hash generation all Variables containing plain password fragments are
deleted. Password file SHOULD be 0400 and root:root and is deleted without
further prompt after password hash has been successfully generated via:
shred -vfzu 5 -f.
No tracing of any plain text password fragment in any debug log.
--ssh-port <INTEGER>
The desired Port SSH should listen to.
If not provided defaults to Port 22.
--ssh-pubkey </path/to/.ssh/>
Imports the SSH Public Key(s) from the FILE 'authorized_keys' of the
specified PATH into the Live ISO. MUST be provided.
--version, -v
Displays version of ${0}.
$(echo -e "\e[93mNOTES:\e[0m")
- You MUST be 'root' to run this script.
$(echo -e "\e[92mContact:\e[0m")
$(echo -e "\e[95m - https://coresecret.eu/ \e[0m")
$(echo -e "\e[95m - security@coresecret.eu \e[0m")
$(echo -e "\e[95m - PGP Key 2D98 07F4 1030 1776 597E BDC9 9F54 8853 35A3 C9AD \e[0m")
$(echo -e "\e[95m - https://keys.openpgp.org/vks/v1/by-fingerprint/2D9807F410301776597EBDC99F54885335A3C9AD \e[0m")
EOF
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh