V8.00.000.2025.06.17

Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
This commit is contained in:
2025-07-23 08:50:22 +02:00
parent 328e346c95
commit 080e04efa3
52 changed files with 35 additions and 37 deletions

View File

@@ -0,0 +1,37 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Install minimal Debian environment via 'debootstrap' command.
# Globals:
# TARGET
# architecture
# distribution
# Arguments:
# None
# Returns:
# ERR_DEBOOTSTRAP
# 0: on success
#######################################
func_debootstrap() {
# shellcheck disable=SC2154 # "${architecture}" "${distribution}"
if debootstrap --arch="${architecture}" "${distribution}" "${TARGET}" https://deb.debian.org/debian | tee "${LOG_DBS}"; then
do_log "info" "false" "Executing 'debootstrap --arch=${architecture} ${distribution} '${TARGET}' https://deb.debian.org/debian' successful."
return 0
else
do_log "emergency" "false" "Executing 'debootstrap --arch=${architecture} ${distribution} '${TARGET}' https://deb.debian.org/debian' NOT successful."
return "${ERR_DEBOOTSTRAP}"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,58 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Configure target system for chroot.
# Globals:
# ERR_CHRT_MOUNTS
# TARGET
# Arguments:
# None
# Returns:
# ERR_CHRT_MOUNTS
# 0: on success
#######################################
configure_system() {
### Notes
# --rbind: recursive binding.
# --make-rslave: In this case, the mount point is marked as 'slave'.
# This means changes to the source mount (e.g., /proc) are propagated to the target mount (e.g., "${TARGET}"/proc).
# Conversely, changes to the target mount are not propagated back to the source mount.
# This mode is necessary to avoid problems with double or erroneous propagation effects in chroot or container environments.
declare var_src var_dst
declare -a ary_mounts=(proc sys dev run)
for var_src in "${ary_mounts[@]}"; do
var_dst="${TARGET}/${var_src}"
mkdir -p "${var_dst}"
if ! mount --make-rslave --rbind "/${var_src}" "${var_dst}"; then
do_log "emergency" "false" "Failed: 'mount --make-rslave --rbind /${var_src} ${var_dst}'."
return "${ERR_CHRT_MOUNTS}"
fi
do_log "info" "true" "Success: 'mount --make-rslave --rbind /${var_src} ${var_dst}'."
done
if ! do_in_target "${TARGET}" mkdir -p /etc/systemd/system/multi-user.target.wants; then
return "${ERR_CHRT_MOUNTS}"
fi
do_log "info" "true" "Command: 'mkdir -p /etc/systemd/system/multi-user.target.wants' executed in: '${TARGET}'."
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,215 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# '/etc/fstab' entry writer and logger.
# Globals:
# TARGET
# Arguments:
# 1: UUID
# 2: Mount Path
# 3: Filesystem
# 4: Mount Options
# 5: Pass value, while Dump value is hardcoded always "0", e.g., "1"
# Returns:
# 0: on success
#######################################
write_fstab() {
declare _uuid="$1" _path="$2" _fs="$3" _opts="$4" _pass="$5"
printf "UUID=%s %s %s %s 0 %s\n" "${_uuid}" "${_path}" "${_fs}" "${_opts}" "${_pass}" >> "${TARGET}/etc/fstab"
do_log "info" "true" "fstab entry generated: 'UUID=${_uuid} ${_path} ${_fs} ${_opts} 0 ${_pass}'."
return 0
}
#######################################
# Generate target '/etc/fstab' entries.
# Globals:
# HMP_EPHEMERAL_ENCLABEL
# HMP_PATH_FSUUID
# MAP_MOUNTPATH_DEV
# TARGET
# VAR_RECIPE_STRING
# VAR_SETUP_PART
# Arguments:
# None
# Returns:
# 0: on success
#######################################
generate_fstab() {
### Generate '${TARGET}/etc/fstab' header.
: >| "${TARGET}/etc/fstab"
chmod 0600 "${TARGET}/etc/fstab"
cat << 'EOF' >> "${TARGET}/etc/fstab"
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# systemd generates mount units based on this file, see systemd.mount(5).
# Please run 'systemctl daemon-reload' after making changes here.
#
# <file system> <mount point> <type> <options> <dump> <pass>
# Secure tmpfs mounts for a hardened system
# Mount the proc filesystem to provide process and kernel information
proc /proc proc nodev,nosuid,noexec,hidepid=2 0 0
# Mount sysfs to expose kernel device information to user space
sysfs /sys sysfs defaults 0 0
# Mount the devpts filesystem to enable pseudo-terminal support for user sessions
devpts /dev/pts devpts gid=5,mode=620 0 0
# Restrict /dev/shm to shared memory, limit size, prevent code execution
tmpfs /dev/shm tmpfs rw,nodev,noexec,nosuid,relatime,size=1G 0 0
# System runtime directory in RAM; do not set noexec here for compatibility
tmpfs /run tmpfs mode=0755,nodev,nosuid 0 0
EOF
### Generate '${TARGET}/etc/fstab' special entries '/' '/boot' '/boot/efi'.
### Define the order of the special paths.
declare -a ary_path_order; ary_path_order=("/" "/boot" "/boot/efi")
declare -a ary_skip=("/" "/boot" "/boot/efi" "/recovery")
declare var_path var_entry var_part var_dev var_key var_uuid var_fs_btrfs_compress var_fs_btrfs_level var_fs_btrfs_subvolume \
var_fs_version var_mount_options var_mount_optsnap var_btrfs_compression
for var_path in "${ary_path_order[@]}"; do
var_entry=$(yq e -r '.recipe.*.dev.* | select(.mount.path == "'"${var_path}"'")' "${VAR_SETUP_PART}")
if [[ -z "${var_entry}" ]]; then
continue
fi
var_part=$(echo "${var_entry}" | yq e 'path | .[-2]' -)
var_dev=$(echo "${var_entry}" | yq e 'path | .[-3]' -)
var_key="UUID_${var_path}"
var_uuid="${HMP_PATH_FSUUID[${var_key}]}"
var_fs_btrfs_compress=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.filesystem.btrfs.compress" "${VAR_SETUP_PART}")
var_fs_btrfs_level=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.filesystem.btrfs.level" "${VAR_SETUP_PART}")
var_fs_btrfs_subvolume=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.filesystem.btrfs.subvolume" "${VAR_SETUP_PART}")
var_fs_version=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.filesystem.version" "${VAR_SETUP_PART}")
var_mount_options=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.mount.options" "${VAR_SETUP_PART}")
var_mount_optsnap=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.mount.optsnap" "${VAR_SETUP_PART}")
if [[ "${var_fs_version,,}" == btrfs ]]; then
if [[ "${var_fs_btrfs_level:-0}" == 0 ]]; then
var_btrfs_compression="compress=no"
else
var_btrfs_compression="compress=${var_fs_btrfs_compress}:${var_fs_btrfs_level}"
fi
write_fstab "${var_uuid}" "${var_path}" "${var_fs_version}" "${var_mount_options},${var_btrfs_compression}" "1"
if [[ -n "${var_fs_btrfs_subvolume}" ]]; then
if [[ "${var_path}" == "/" ]]; then
write_fstab "${var_uuid}" "/.snapshots" "${var_fs_version}" "${var_mount_optsnap}" "0"
else
write_fstab "${var_uuid}" "${var_path}/.snapshots" "${var_fs_version}" "${var_mount_optsnap}" "0"
fi
fi
continue
elif [[ "${var_fs_version,,}" == ext4 ]]; then
write_fstab "${var_uuid}" "${var_path}" "${var_fs_version}" "${var_mount_options}" "1"
continue
elif [[ "${var_fs_version,,}" == fat32 ]]; then
write_fstab "${var_uuid}" "${var_path}" "vfat" "${var_mount_options}" "2"
continue
fi
done
### Generate '${TARGET}/etc/fstab' remaining entries.
for var_path in "${!MAP_MOUNTPATH_DEV[@]}"; do
if validation_array "${var_path}" "${ary_skip[@]}"; then
continue
fi
var_entry=$(yq e -r '.recipe.*.dev.* | select(.mount.path == "'"${var_path}"'")' "${VAR_SETUP_PART}")
if [[ -z "${var_entry}" ]]; then
continue
fi
var_part=$(echo "${var_entry}" | yq e 'path | .[-2]' -)
var_dev=$(echo "${var_entry}" | yq e 'path | .[-3]' -)
var_key="UUID_${var_path}"
var_uuid="${HMP_PATH_FSUUID[${var_key}]}"
var_fs_btrfs_compress=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.filesystem.btrfs.compress" "${VAR_SETUP_PART}")
var_fs_btrfs_level=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.filesystem.btrfs.level" "${VAR_SETUP_PART}")
var_fs_btrfs_subvolume=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.filesystem.btrfs.subvolume" "${VAR_SETUP_PART}")
var_fs_version=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.filesystem.version" "${VAR_SETUP_PART}")
var_mount_options=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.mount.options" "${VAR_SETUP_PART}")
var_mount_optsnap=$(yq_val ".recipe.${VAR_RECIPE_STRING}.dev.${var_dev}.${var_part}.mount.optsnap" "${VAR_SETUP_PART}")
if [[ "${var_fs_version,,}" == btrfs ]]; then
if [[ "${var_fs_btrfs_level:-0}" == 0 ]]; then
var_btrfs_compression="compress=no"
else
var_btrfs_compression="compress=${var_fs_btrfs_compress}:${var_fs_btrfs_level}"
fi
write_fstab "${var_uuid}" "${var_path}" "${var_fs_version}" "${var_mount_options},${var_btrfs_compression}" "2"
if [[ -n "${var_fs_btrfs_subvolume}" ]]; then
write_fstab "${var_uuid}" "${var_path}/.snapshots" "${var_fs_version}" "${var_mount_optsnap}" "0"
fi
continue
elif [[ "${var_fs_version,,}" == ext4 ]]; then
write_fstab "${var_uuid}" "${var_path}" "${var_fs_version}" "${var_mount_options}" "2"
continue
elif [[ "${var_fs_version,,}" == fat32 ]]; then
write_fstab "${var_uuid}" "${var_path}" "vfat" "${var_mount_options}" "2"
continue
fi
done
cat << 'EOF' >> "${TARGET}/etc/fstab"
/dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0
EOF
do_log "info" "true" "fstab entry generated: '/dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0'."
### Add entry for 'SWAP' device.
var_path="SWAP"
write_fstab "/dev/mapper/${HMP_EPHEMERAL_ENCLABEL["${var_path}"]}" "none" "swap" "defaults" "0"
### Add entry for '/tmp' device.
var_path="/tmp"
write_fstab "/dev/mapper/${HMP_EPHEMERAL_ENCLABEL["${var_path}"]}" "/tmp" "ext4" "defaults,rw,nodev,nosuid,relatime" "0"
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,124 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# '/etc/crypttab' entry writer and logger.
# Globals:
# TARGET
# Arguments:
# 1: Encryption Label
# 2: LUKS Container UUID
# 3: Keyfile or none
# 4: LUKS Options
# Returns:
# 0: on success
#######################################
write_crypttab() {
declare _label="$1" _device="$2" _key_file="$3" _opts="$4"
printf "%s %s %s %s\n" "${_label}" "${_device}" "${_key_file}" "${_opts}" >> "${TARGET}/etc/crypttab"
do_log "info" "true" "crypttab entry generated: '${_label} ${_device} ${_key_file} ${_opts}'."
return 0
}
#######################################
# Generate target '/etc/crypttab' entries.
# Globals:
# HMP_EPHEMERAL_ENCLABEL
# HMP_EPHEMERAL_FS_LABEL
# HMP_PATH_ENCLABEL
# HMP_PATH_LUKSUUID
# TARGET
# VAR_NUKE
# dropbear_boot
# Arguments:
# None
# Returns:
# 0: on success
#######################################
generate_crypttab() {
declare var_key var_encryption_label var_luks_uuid
### Generate '${TARGET}/etc/crypttab' header.
install -d -m 0755 "${TARGET}/etc"
: >| "${TARGET}/etc/crypttab"
chmod 0600 "${TARGET}/etc/crypttab"
cat << 'EOF' >> "${TARGET}/etc/crypttab"
# /etc/crypttab: static file system information.
#
# Basic rule: 'discard' / 'nodiscard' are normally only set in '/etc/crypttab' when LUKS/dm-crypt is in use.
# Options like 'discard=async' or similar are typically only set in '/etc/fstab' (at the file system level).
# The crypttab determines whether the underlying encrypted device (LUKS/dm-crypt) passes TRIM commands to the
# physical drive or not. The fstab determines whether and how the file system itself generates the discard
# operations and sends them down through the LUKS layer.
#
# RECOMMENDED: 'discard' enables the TRIM commands to be forwarded by the dm-crypt layer to the SSD/physical
# device. If you do not specify discard in the crypttab, dm-crypt blocks TRIM by default. This would render a
# discard in the fstab ineffective.
#
# <name> <device> <password-file-or-none> <options>
EOF
### Generate '${TARGET}/etc/crypttab' entries.
declare var_ephemeral_enclabel var_ephemeral_fs_label
for var_key in "${!HMP_PATH_LUKSUUID[@]}"; do
var_encryption_label="${HMP_PATH_ENCLABEL["${var_key}"]}"
var_luks_uuid="${HMP_PATH_LUKSUUID["${var_key}"]}"
if [[ "${dropbear_boot,,}" == "true" ]]; then
if [[ "${VAR_NUKE,,}" == "true" && "${var_key,,}" == "/" ]]; then
write_crypttab "${var_encryption_label}" "UUID=${var_luks_uuid}" "none" "luks,discard,initramfs,keyscript=/lib/cryptsetup/scripts/unlock_wrapper.sh"
continue
fi
write_crypttab "${var_encryption_label}" "UUID=${var_luks_uuid}" "none" "luks,discard,initramfs"
else
write_crypttab "${var_encryption_label}" "UUID=${var_luks_uuid}" "none" "luks,discard"
fi
done
### Generate '${TARGET}/etc/crypttab' ephemeral entries.
for var_key in "${!HMP_EPHEMERAL_ENCLABEL[@]}"; do
var_ephemeral_enclabel="${HMP_EPHEMERAL_ENCLABEL["${var_key}"]}"
var_ephemeral_fs_label="${HMP_EPHEMERAL_FS_LABEL["${var_key}"]}"
case "${var_key}" in
SWAP)
write_crypttab "${var_ephemeral_enclabel}" "LABEL=${var_ephemeral_fs_label}" "/dev/random" "swap,offset=2048,cipher=aes-xts-plain64,size=512,sector-size=4096"
;;
/tmp)
write_crypttab "${var_ephemeral_enclabel}" "LABEL=${var_ephemeral_fs_label}" "/dev/random" "offset=2048,cipher=aes-xts-plain64,size=512,sector-size=4096,tmp=ext4"
;;
*)
do_log "error" "false" "Only 'SWAP' and '/tmp' are valid Partitions for Ephemeral Encryption. Given value was: '${var_key}'."
continue
;;
esac
done
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,166 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Generate target '/etc/apt/sources.list' entries.
# Globals:
# TARGET
# apt_contrib
# apt_deb_sources
# apt_mirror_directory
# apt_mirror_hostname
# apt_mirror_protocol
# apt_non_free
# apt_non_free_firmware
# apt_sec
# apt_updates_backports
# apt_updates_policy
# apt_updates_release
# apt_updates_security
# architecture
# distribution
# Arguments:
# None
# Returns:
# 0: on success
#######################################
generate_sources() {
declare -a ary_components
declare var_arch var_codename var_deb_src var_dir var_hostname var_hostsecure var_url var_surl
# shellcheck disable=SC2154 # "${architecture}"
var_arch="${architecture,,}"
# shellcheck disable=SC2154 # "${distribution}"
var_codename="${distribution,,}"
# shellcheck disable=SC2154 # "${apt_deb_sources}"
var_deb_src="${apt_deb_sources,,}"
# shellcheck disable=SC2154 # "${apt_mirror_directory}"
var_dir="${apt_mirror_directory,,}"
# shellcheck disable=SC2154 # "${apt_mirror_hostname}"
var_hostname="${apt_mirror_hostname,,}"
# shellcheck disable=SC2154 # "${apt_sec}"
var_hostsecure="${apt_sec,,}"
ary_components=(main)
[[ "${apt_contrib,,}" == true ]] && ary_components+=(contrib)
[[ "${apt_non_free,,}" == true ]] && ary_components+=(non-free)
[[ "${apt_non_free_firmware,,}" == true ]] && ary_components+=(non-free-firmware)
if [[ "${apt_mirror_protocol,,}" == "https" ]]; then
var_url="https://${var_hostname}${var_dir}"
var_surl="https://${var_hostsecure}/debian-security"
elif [[ "${apt_mirror_protocol,,}" == "http" ]]; then
var_url="http://${var_hostname}${var_dir}"
var_surl="http://${var_hostsecure}/debian-security"
else
var_url="https://${var_hostname}${var_dir}"
var_surl="https://${var_hostsecure}/debian-security"
fi
: >| "${TARGET}/etc/apt/sources.list"
chmod 0644 "${TARGET}/etc/apt/sources.list"
### Main Repository
cat << EOF >> "${TARGET}/etc/apt/sources.list"
# /etc/apt/sources.list : Generated by CISS.debian.installer
# Architecture : ${var_arch}
# Distribution : ${var_codename}
#------------------------------------------------------------------------------------------------------------------------------#
# OFFICIAL DEBIAN REPOS #
#------------------------------------------------------------------------------------------------------------------------------#
deb ${var_url} ${var_codename} ${ary_components[*]}
EOF
do_log "info" "true" "${TARGET}/etc/apt/sources.list entry generated: 'deb ${var_url} ${var_codename} ${ary_components[*]}'."
if [[ "${var_deb_src}" == "true" ]]; then
echo "deb-src ${var_url} ${var_codename} ${ary_components[*]}" >> "${TARGET}/etc/apt/sources.list"
do_log "info" "true" "${TARGET}/etc/apt/sources.list entry generated: 'deb-src ${var_url} ${var_codename} ${ary_components[*]}'."
fi
### Security Repository
if [[ "${apt_updates_security,,}" == "true" ]]; then
cat << EOF >> "${TARGET}/etc/apt/sources.list"
deb ${var_surl} ${var_codename}-security ${ary_components[*]}
EOF
do_log "info" "true" "${TARGET}/etc/apt/sources.list entry generated: 'deb ${var_surl} ${var_codename}-security ${ary_components[*]}'."
if [[ "${var_deb_src}" == "true" ]]; then
echo "deb-src ${var_surl} ${var_codename}-security ${ary_components[*]}" >> "${TARGET}/etc/apt/sources.list"
do_log "info" "true" "${TARGET}/etc/apt/sources.list entry generated: 'deb-src ${var_surl} ${var_codename}-security ${ary_components[*]}'."
fi
fi
### Updates Repository
if [[ "${apt_updates_release,,}" == "true" ]]; then
cat << EOF >> "${TARGET}/etc/apt/sources.list"
deb ${var_url} ${var_codename}-updates ${ary_components[*]}
EOF
do_log "info" "true" "${TARGET}/etc/apt/sources.list entry generated: 'deb ${var_url} ${var_codename}-updates ${ary_components[*]}'."
if [[ "${var_deb_src}" == "true" ]]; then
echo "deb-src ${var_url} ${var_codename}-updates ${ary_components[*]}" >> "${TARGET}/etc/apt/sources.list"
do_log "info" "true" "${TARGET}/etc/apt/sources.list entry generated: 'deb-src ${var_url} ${var_codename}-updates ${ary_components[*]}'."
fi
fi
### Backports Repository
if [[ "${apt_updates_backports,,}" == "true" ]]; then
cat << EOF >> "${TARGET}/etc/apt/sources.list"
deb ${var_url} ${var_codename}-backports ${ary_components[*]}
EOF
do_log "info" "true" "${TARGET}/etc/apt/sources.list entry generated: 'deb ${var_url} ${var_codename}-backports ${ary_components[*]}'."
if [[ "${var_deb_src,,}" == "true" ]]; then
echo "deb-src ${var_url} ${var_codename}-backports ${ary_components[*]}" >> "${TARGET}/etc/apt/sources.list"
do_log "info" "true" "${TARGET}/etc/apt/sources.list entry generated: 'deb-src ${var_url} ${var_codename}-backports ${ary_components[*]}'."
fi
fi
### Clean up 'sources.list'
sed -i '/^#/!s/[[:space:]]\+/ /g' "${TARGET}/etc/apt/sources.list"
cat << EOF >> "${TARGET}/etc/apt/sources.list"
# Copyright 2018-2025; WEIDNER, Marc S., <msw@coresecret.dev>
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
do_in_target "${TARGET}" apt-get update -y
if [[ "${apt_updates_policy,,}" == "unattended" ]]; then
do_in_target "${TARGET}" apt-get install -y unattended-upgrades
do_log "info" "true" "The update policy was set at installation time to '${apt_updates_policy}'."
elif [[ "${apt_updates_policy,,}" == "security" ]]; then
do_in_target "${TARGET}" apt-get install -y unattended-upgrades
# shellcheck disable=SC2016
sed -i 's/^[[:space:]]*"origin=Debian,codename=\${distro_codename},label=Debian";/\/\/ &/' "${TARGET}/etc/apt/apt.conf.d/50unattended-upgrades"
do_log "info" "true" "The update policy was set at installation time to '${apt_updates_policy}'."
elif [[ "${apt_updates_policy,,}" == "none" ]]; then
do_log "info" "true" "The update policy was set at installation time to: '${apt_updates_policy}'."
else
do_log "warning" "true" "Update policy '${apt_updates_policy}': is not supported. Using 'none' as default."
fi
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,58 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Check and set up the minimum required tools for the next installation steps.
# Globals:
# TARGET
# Arguments:
# None
# Returns:
# 0: on success
#######################################
minimal_toolset() {
declare var_bin
declare -A hmp_tool_pkg=(
["awk"]="gawk"
["busybox"]="busybox"
["cat"]="coreutils"
["chmod"]="coreutils"
["chown"]="coreutils"
["chpasswd"]="passwd"
["chsh"]="passwd"
["cp"]="coreutils"
["cryptsetup"]="cryptsetup-initramfs"
["echo"]="coreutils"
["grep"]="grep"
["ip"]="iproute2"
["ln"]="coreutils"
["mkdir"]="coreutils"
["ping"]="iputils-ping"
["sed"]="sed"
["sudo"]="sudo"
["update-initramfs"]="initramfs-tools"
["zsh"]="zsh"
)
for var_bin in "${!hmp_tool_pkg[@]}"; do
if ! do_in_target_script "${TARGET}" "command -v ${var_bin} >/dev/null"; then
do_in_target "${TARGET}" apt-get install -y "${hmp_tool_pkg[${var_bin}]}"
do_log "debug" "true" "Tool '${var_bin}' missing, installing '${hmp_tool_pkg[${var_bin}]}'."
fi
done
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,31 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Configure timezone.
# Globals:
# TARGET
# ntp_timezone
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_timezone() {
do_in_target "${TARGET}" ln -sf "/usr/share/zoneinfo/${ntp_timezone}" /etc/localtime
do_in_target_script "${TARGET}" "echo ${ntp_timezone} | tee /etc/timezone"
do_in_target "${TARGET}" dpkg-reconfigure -f noninteractive tzdata
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,53 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Set locale and configure keyboard layout.
# Globals:
# TARGET
# locale_country
# locale_keyboard_layout
# locale_keyboard_xkb_keymap
# locale_language
# locale_locale
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_locales() {
do_in_target "${TARGET}" apt-get install -y locales
### Give priority to '${locale_locale}' over separately configured variables '{$locale_country}' and '{$locale_language}'.
### If 'locale_locale' is not set, build it from 'locale_language' and 'locale_country'.
if [[ -n "${locale_language:-}" && -n "${locale_country:-}" && -z "${locale_locale:-}" ]]; then
declare locale_locale="${locale_language}_${locale_country}.UTF-8"
fi
### Generate the specified locale
do_in_target "${TARGET}" locale-gen "${locale_locale}"
### Set the standard locale
do_in_target "${TARGET}" update-locale LANG="${locale_locale}" LC_ALL="${locale_locale}"
### Set the keyboard layout for the system (for consoles)
sed -i "s/^KEYMAP=.*/KEYMAP=${locale_keyboard_layout}/" "${TARGET}/etc/default/keyboard"
do_log "info" "false" "Keyboard layout updated: 'KEYMAP=${locale_keyboard_layout}' -> '${TARGET}/etc/default/keyboard'."
### Set the X11 keyboard layout (for graphical environments)
do_in_target "${TARGET}" localectl set-x11-keymap "${locale_keyboard_xkb_keymap}"
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,31 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Installation of the specified kernel.
# Globals:
# TARGET
# image
# Arguments:
# None
# Returns:
# 0: on success
#######################################
installation_kernel() {
# Installing the chosen Kernel Image according to preseed.yaml
# shellcheck disable=SC2154 # "${image}"
do_in_target "${TARGET}" apt-get install -y "${image}"
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,406 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Setup network.
# Globals:
# DIR_BAK
# TARGET
# VAR_FINAL_FQDN
# VAR_FINAL_IPV4
# VAR_FINAL_IPV4_GW
# VAR_FINAL_IPV4_SUBNET
# VAR_FINAL_IPV6
# VAR_FINAL_NIC
# VAR_LINK_IPV6
# network_autoconfig_enable
# network_choose_interface_auto
# network_choose_interface_static
# network_hostname
# network_static_ipv4address
# network_static_ipv4gateway
# network_static_ipv4nameserver_0
# network_static_ipv4nameserver_1
# network_static_ipv4nameserver_2
# network_static_ipv4nameserver_fallback_0
# network_static_ipv4nameserver_fallback_1
# network_static_ipv4netmask
# network_static_ipv6address
# network_static_ipv6gateway
# network_static_ipv6nameserver_0
# network_static_ipv6nameserver_1
# network_static_ipv6nameserver_2
# network_static_ipv6nameserver_fallback_0
# network_static_ipv6nameserver_fallback_1
# network_static_ipv6netmask
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_network() {
do_in_target "${TARGET}" apt-get install -y isc-dhcp-client ifupdown
mkdir -p "${TARGET}/etc/network/interfaces/interfaces.d"
declare var_auto_nic="" var_auto_ipv4_ccidr="" var_auto_ipv4_subnet="" var_auto_ipv4="" var_auto_ipv4_gw="" \
var_auto_ipv6_ccidr="" var_auto_ipv6="" var_auto_ipv6_gw="" var_link_ipv4="" var_link_ipv6="" var_auto_fqdn="" ns=""
declare -a ary_ipv4_ns ary_ipv6_ns
ary_ipv4_ns+=("${network_static_ipv4nameserver_0}")
[[ -v network_static_ipv4nameserver_1 ]] && ary_ipv4_ns+=("${network_static_ipv4nameserver_1}")
[[ -v network_static_ipv4nameserver_2 ]] && ary_ipv4_ns+=("${network_static_ipv4nameserver_2}")
[[ -v network_static_ipv4nameserver_fallback_0 ]] && ary_ipv4_ns+=("${network_static_ipv4nameserver_fallback_0}")
[[ -v network_static_ipv4nameserver_fallback_1 ]] && ary_ipv4_ns+=("${network_static_ipv4nameserver_fallback_1}")
ary_ipv6_ns+=("${network_static_ipv6nameserver_0}")
[[ -v network_static_ipv6nameserver_1 ]] && ary_ipv6_ns+=("${network_static_ipv6nameserver_1}")
[[ -v network_static_ipv6nameserver_2 ]] && ary_ipv6_ns+=("${network_static_ipv6nameserver_2}")
[[ -v network_static_ipv6nameserver_fallback_0 ]] && ary_ipv6_ns+=("${network_static_ipv6nameserver_fallback_0}")
[[ -v network_static_ipv6nameserver_fallback_1 ]] && ary_ipv6_ns+=("${network_static_ipv6nameserver_fallback_1}")
### Check current network connection and configure variables
var_auto_nic=$(ip -o link show | awk -F': ' '/state UP/ && $2!="lo" {print $2; exit}')
var_auto_ipv4_ccidr=$(ip -4 -o addr show "${var_auto_nic}" | awk '{print $4; exit}')
var_auto_ipv4_subnet=$(generate_subnetmask "${var_auto_ipv4_ccidr}")
var_auto_ipv4=$(echo "${var_auto_ipv4_ccidr}" | awk -F'/' '{print $1}')
var_auto_ipv4_gw=$(ip route show default dev "${var_auto_nic}" | awk '/^default/ {print $3; exit}')
var_auto_ipv6_ccidr=$(ip -6 -o addr show "${var_auto_nic}" | awk '/scope global/ {print $4; exit}')
if [[ -n "${var_auto_ipv6_ccidr}" ]]; then
var_auto_ipv6=$(echo "${var_auto_ipv6_ccidr}" | awk -F'/' '{print $1}')
var_auto_ipv6_gw=$(ip -6 route show default dev "${var_auto_nic}" | awk '/^default/ {print $3; exit}')
fi
var_link_ipv4=$(ping -q -c 1 -W 1 -4 debian.org > /dev/null 2>&1 && echo "true" || echo "false")
var_link_ipv6=$(ping -q -c 1 -W 1 -6 debian.org > /dev/null 2>&1 && echo "true" || echo "false")
if [[ -f "/var/lib/dhcp/dhclient.${var_auto_nic}.leases" ]]; then
var_auto_fqdn=$(grep -m1 'option host-name' "/var/lib/dhcp/dhclient.${var_auto_nic}.leases" | sed -E 's/.*"([^"]+)".*/\1/')
else
var_auto_fqdn=""
fi
do_log "info" "false" "Live environment network check: Auto NIC ='${var_auto_nic}'."
do_log "info" "false" "Live environment network check: Auto IPv4 ='${var_auto_ipv4}'."
do_log "info" "false" "Live environment network check: Auto IPv4 CCIDR ='${var_auto_ipv4_ccidr}'."
do_log "info" "false" "Live environment network check: Auto IPv4 Subnet ='${var_auto_ipv4_subnet}'."
do_log "info" "false" "Live environment network check: Auto IPv4 Gateway ='${var_auto_ipv4_gw}'."
do_log "info" "false" "Live environment network check: Auto IPv6 ='${var_auto_ipv6}'."
do_log "info" "false" "Live environment network check: Auto IPv6 CCIDR ='${var_auto_ipv6_ccidr}'."
do_log "info" "false" "Live environment network check: Auto IPv6 Gateway ='${var_auto_ipv6_gw}'."
do_log "info" "false" "Live environment network check: Auto IPv4 Link ='${var_link_ipv4}'."
do_log "info" "false" "Live environment network check: Auto IPv6 Link ='${var_link_ipv6}'."
do_log "info" "false" "Live environment network check: Auto FQDN ='${var_auto_fqdn}'."
### Create network configuration file header.
if [[ -f "${TARGET}/etc/network/interfaces" ]]; then
mkdir -p "${DIR_BAK}/etc/network"
mv "${TARGET}/etc/network/interfaces" "${DIR_BAK}/etc/network/interfaces.bak"
do_log "info" "false" "Existing '${TARGET}/etc/network/interfaces' moved."
fi
cat << EOF >| "${TARGET}/etc/network/interfaces"
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
chmod 0644 "${TARGET}/etc/network/interfaces"
do_log "info" "false" "Header '${TARGET}/etc/network/interfaces' created."
### Configure network interfaces based on 'preseed.yaml' and create network configuration files for IPv4.
if [[ "${network_autoconfig_enable,,}" == "true" && "${network_choose_interface_auto,,}" == "true" ]]; then
### Reminder ###
# auto:
# For servers or systems with static interfaces that should always be available (e.g., eth0 on a server).
# For configurations where the interface should be active regardless of the cable status.
# allow-hotplug:
# For systems with dynamic or removable network devices (e.g., laptops or USB adapters).
# To avoid boot delays when interfaces are unavailable.
cat << EOF >| "${TARGET}/etc/network/interfaces/interfaces.d/10-ipv4-dhcp"
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
# The primary network interface IPv4
auto ${var_auto_nic}
iface ${var_auto_nic} inet dhcp
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
chmod 0644 "${TARGET}/etc/network/interfaces/interfaces.d/10-ipv4-dhcp"
do_log "info" "false" "IPv4 on the primary NIC: '${var_auto_nic}' configured with DHCP."
elif [[ "${network_autoconfig_enable,,}" == "true" && "${network_choose_interface_auto,,}" == "false" ]]; then
cat << EOF >| "${TARGET}/etc/network/interfaces/interfaces.d/10-ipv4-dhcp"
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
# The primary network interface IPv4
auto ${network_choose_interface_static}
iface ${network_choose_interface_static} inet dhcp
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
chmod 0644 "${TARGET}/etc/network/interfaces/interfaces.d/10-ipv4-dhcp"
do_log "info" "false" "IPv4 on the primary NIC: '${network_choose_interface_static}' configured with DHCP."
fi
if [[ "${network_autoconfig_enable,,}" == "false" ]]; then
cat << EOF >| "${TARGET}/etc/network/interfaces/interfaces.d/10-ipv4-static"
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
# The primary network interface IPv4
auto ${network_choose_interface_static}
iface ${network_choose_interface_static} inet static
address ${network_static_ipv4address}
netmask ${network_static_ipv4netmask}
gateway ${network_static_ipv4gateway}
dns-nameservers ${ary_ipv4_ns[*]}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
chmod 0644 "${TARGET}/etc/network/interfaces/interfaces.d/10-ipv4-static"
do_log "info" "false" "IPv4 on the primary NIC: '${network_choose_interface_static}' configured statically."
fi
### Configure network interfaces based on 'preseed.yaml' and create network configuration files for IPv6.
if [[ "${network_autoconfig_enable,,}" == "true" && "${var_link_ipv6,,}" == "true" ]]; then
cat << EOF >| "${TARGET}/etc/network/interfaces/interfaces.d/10-ipv6-dhcp"
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
# The primary network interface IPv6
auto ${var_auto_nic}
iface ${var_auto_nic} inet6 dhcp
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
chmod 0644 "${TARGET}/etc/network/interfaces/interfaces.d/10-ipv6-dhcp"
do_log "info" "false" "IPv6 on the primary NIC: '${var_auto_nic}' configured with DHCP."
fi
if [[ "${network_autoconfig_enable,,}" == "false" && -n "${network_static_ipv6address}" ]]; then
cat << EOF >| "${TARGET}/etc/network/interfaces/interfaces.d/10-ipv6-static"
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
# The primary network interface IPv6
auto ${network_choose_interface_static}
iface ${network_choose_interface_static} inet6 static
address ${network_static_ipv6address}/${network_static_ipv6netmask}
gateway ${network_static_ipv6gateway}
dns-nameservers ${ary_ipv6_ns[*]}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
chmod 0644 "${TARGET}/etc/network/interfaces/interfaces.d/10-ipv6-static"
do_log "info" "false" "IPv6 on the primary NIC: '${network_choose_interface_static}' configured statically."
fi
if [[ -f "${TARGET}/etc/resolv.conf" ]]; then
mkdir -p "${DIR_BAK}/etc"
mv "${TARGET}/etc/resolv.conf" "${DIR_BAK}/etc/resolv.conf.bak"
do_log "info" "false" "Existing '${TARGET}/etc/resolv.conf' moved."
fi
touch "${TARGET}/etc/resolv.conf"
chmod 0644 "${TARGET}/etc/resolv.conf"
### Create '/etc/resolv.conf' IPv4 entries for static configuration.
if [[ "${network_autoconfig_enable,,}" == "false" ]]; then
cat << EOF >> "${TARGET}/etc/resolv.conf"
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
# Custom DNS IPv4 configuration
EOF
for ns in "${ary_ipv4_ns[@]}"; do
echo "nameserver ${ns}" >> "${TARGET}/etc/resolv.conf"
done
echo "" >> "${TARGET}/etc/resolv.conf"
do_log "info" "false" "IPv4 nameserver at: '${TARGET}/etc/resolv.conf' configured manually."
fi
### Create '/etc/resolv.conf' IPv6 entries for static configuration.
if [[ "${network_autoconfig_enable,,}" == "false" && -n "${network_static_ipv6address}" ]]; then
cat << EOF >> "${TARGET}/etc/resolv.conf"
# Custom DNS IPv6 configuration
EOF
for ns in "${ary_ipv6_ns[@]}"; do
echo "nameserver ${ns}" >> "${TARGET}/etc/resolv.conf"
done
echo "" >> "${TARGET}/etc/resolv.conf"
do_log "info" "false" "IPv6 nameserver at: '${TARGET}/etc/resolv.conf' configured manually."
fi
cat << EOF >> "${TARGET}/etc/resolv.conf"
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
### Ensure Internet Systems Consortium DHCP Client is not overwriting the static nameserver settings.
if [[ -f "${TARGET}/etc/dhcp/dhclient.conf" ]]; then
mkdir -p "${DIR_BAK}/etc/dhcp"
cp "${TARGET}/etc/dhcp/dhclient.conf" "${DIR_BAK}/etc/dhcp/dhclient.conf.bak"
do_log "info" "false" "Existing '${TARGET}/etc/dhcp/dhclient.conf' saved."
fi
if [[ "${network_autoconfig_enable,,}" == "true" && -n "${network_static_ipv4nameserver_0}" ]]; then
cat << EOF >> "${TARGET}/etc/dhcp/dhclient.conf"
# Custom dhclient config to override DHCP DNS
EOF
declare var_supersede; var_supersede=$(printf "%s, " "${ary_ipv4_ns[@]}")
var_supersede="${var_supersede%, }"
echo "supersede domain-name-servers ${var_supersede};" >> "${TARGET}/etc/dhcp/dhclient.conf"
do_log "info" "false" "DHCP client configuration for IPv4: '${TARGET}/etc/dhcp/dhclient.conf' configured."
fi
if [[ "${network_autoconfig_enable,,}" == "false" && -n "${network_static_ipv6nameserver_0}" ]]; then
declare var_supersede_ipv6; var_supersede_ipv6=$(printf "%s, " "${ary_ipv6_ns[@]}")
var_supersede_ipv6="${var_supersede_ipv6%, }"
echo "supersede domain-name-servers ${var_supersede_ipv6};" >> "${TARGET}/etc/dhcp/dhclient.conf"
do_log "info" "false" "DHCP client configuration for IPv6: '${TARGET}/etc/dhcp/dhclient.conf' configured."
fi
if [[ "${network_autoconfig_enable,,}" == "true" && -n "${network_static_ipv4nameserver_0}" ]]; then
cat << EOF >> "${TARGET}/etc/dhcp/dhclient.conf"
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
fi
### Export hostname and IPv4 and IPv6 addresses for further processing according to dynamic results and preseed.yaml settings.
if [[ "${network_autoconfig_enable,,}" == "true" ]]; then
declare -grx VAR_FINAL_NIC="${var_auto_nic}"
declare -grx VAR_FINAL_FQDN="${var_auto_fqdn}"
declare -grx VAR_FINAL_IPV4="${var_auto_ipv4}"
declare -grx VAR_FINAL_IPV4_GW="${var_auto_ipv4_gw}"
declare -grx VAR_FINAL_IPV4_SUBNET="${var_auto_ipv4_subnet}"
else
declare -grx VAR_FINAL_NIC="${network_choose_interface_static}"
declare -grx VAR_FINAL_FQDN="${network_hostname}"
declare -grx VAR_FINAL_IPV4="${network_static_ipv4address}"
declare -grx VAR_FINAL_IPV4_GW="${network_static_ipv4gateway}"
declare -grx VAR_FINAL_IPV4_SUBNET="${network_static_ipv4netmask}"
fi
if [[ "${network_autoconfig_enable,,}" == "true" && "${var_link_ipv6,,}" == "true" ]]; then
declare -grx VAR_FINAL_IPV6="${var_auto_ipv6}"
declare -grx VAR_LINK_IPV6="${var_link_ipv6}"
elif [[ "${network_autoconfig_enable,,}" == "false" && -n "${network_static_ipv6address}" ]]; then
declare -grx VAR_FINAL_IPV6="${network_static_ipv6address}"
else
declare -grx VAR_FINAL_IPV6=""
fi
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,74 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Generate files: '/etc/hostname' | '/etc/hosts' | '/etc/mailname'
# Globals:
# TARGET
# VAR_FINAL_FQDN
# VAR_FINAL_IPV4
# VAR_FINAL_IPV6
# VAR_LINK_IPV6
# network_ipv6
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_hostname() {
### Create '${TARGET}/etc/hostname' file.
cat << EOF >| "${TARGET}/etc/hostname"
${VAR_FINAL_FQDN}
EOF
chmod 0644 "${TARGET}/etc/hostname"
do_log "info" "true" "File generated: '${TARGET}/etc/hostname' | hostname '${VAR_FINAL_FQDN}'."
### Create '${TARGET}/etc/mailname' file.
cat << EOF >| "${TARGET}/etc/mailname"
${VAR_FINAL_FQDN}
EOF
chmod 0644 "${TARGET}/etc/mailname"
do_log "info" "true" "File generated: '${TARGET}/etc/mailname' | mailname '${VAR_FINAL_FQDN}'."
### Generate '${TARGET}/etc/hosts' basic IPv4 entries
cat << EOF >| "${TARGET}/etc/hosts"
127.0.0.1 localhost
${VAR_FINAL_IPV4} ${VAR_FINAL_FQDN}
EOF
chmod 0644 "${TARGET}/etc/hosts"
do_log "info" "true" "File generated: '${TARGET}/etc/hosts' with basic IPv4 entries."
### Generate '${TARGET}/etc/hosts' basic IPv6 entries
if [[ "${VAR_LINK_IPV6,,}" == "true" || "${network_ipv6,,}" == "true" ]]; then
cat << EOF >> "${TARGET}/etc/hosts"
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
${VAR_FINAL_IPV6} ${VAR_FINAL_FQDN}
EOF
do_log "info" "true" "File updated: '${TARGET}/etc/hosts' with basic IPv6 entries."
fi
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,38 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Updating 'machine-id' to 'whonix id'.
# Globals:
# TARGET
# VAR_SETUP_PATH
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_machineid() {
if [[ -f "${TARGET}/var/lib/dbus/machine-id" ]]; then
rm -f "${TARGET}/var/lib/dbus/machine-id"
fi
install -m 0644 -o root -g root "${VAR_SETUP_PATH}/includes/etc/machine-id" "${TARGET}/var/lib/dbus/machine-id"
if [[ -f "${TARGET}/etc/machine-id" ]]; then
rm -f "${TARGET}/etc/machine-id"
fi
install -m 0644 -o root -g root "${VAR_SETUP_PATH}/includes/etc/machine-id" "${TARGET}/etc/machine-id"
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,176 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Installation and setup of the GRUB2 (backported) version.
# The backported version MUST be installed for LUKS2 '/boot' encryption.
# Globals:
# ERR_GRUB_BACKGROUND
# ERR_GRUB_EFI_FORCE
# TARGET
# VAR_RECIPE_FIRMWARE
# VAR_RECIPE_TABLE
# grub_background_enable
# grub_background_path
# grub_bootdev
# grub_force_efi
# grub_latest
# grub_prober
# grub_skip
# Arguments:
# None
# Returns:
# ERR_GRUB_BACKGROUND
# ERR_GRUB_EFI_FORCE
# 0: on success
#######################################
setup_grub() {
declare var_update_grub_required="false"
if [[ "${grub_skip,,}" != "true" ]]; then
### Install GRUB2 package
if [[ "${grub_latest,,}" == "true" ]]; then
### Install the GRUB2 backported version from the Bookworm backports repository.
do_in_target "${TARGET}" apt-get install -y -t bookworm-backports grub2 grub2-common
else
### Install the GRUB2 stable version.
do_in_target "${TARGET}" apt-get install -y grub2 grub2-common
fi
### Install grub on the specific device.
if [[ "${grub_force_efi,,}" == "false" ]]; then
if [[ "${VAR_RECIPE_TABLE,,}" == "gpt" && "${VAR_RECIPE_FIRMWARE,,}" == "uefi" ]]; then
do_in_target "${TARGET}" grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Debian --modules="btrfs cryptodisk luks2 gcry_rijndael gcry_sha256 gcry_sha512 part_gpt"
var_update_grub_required="true"
elif [[ "${VAR_RECIPE_TABLE,,}" == "gpt" && "${VAR_RECIPE_FIRMWARE,,}" == "bios" ]]; then
do_in_target "${TARGET}" grub-install --target=i386-pc --boot-directory=/boot --modules="btrfs cryptodisk luks2 gcry_rijndael gcry_sha256 gcry_sha512 part_gpt" --recheck "${grub_bootdev}"
var_update_grub_required="true"
elif [[ "${VAR_RECIPE_TABLE,,}" == "msdos" && "${VAR_RECIPE_FIRMWARE,,}" == "uefi" ]]; then
do_in_target "${TARGET}" grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Debian --modules="btrfs cryptodisk luks2 gcry_rijndael gcry_sha256 gcry_sha512 part_msdos"
var_update_grub_required="true"
elif [[ "${VAR_RECIPE_TABLE,,}" == "msdos" && "${VAR_RECIPE_FIRMWARE,,}" == "bios" ]]; then
do_in_target "${TARGET}" grub-install --target=i386-pc --boot-directory=/boot --modules="btrfs cryptodisk luks2 gcry_rijndael gcry_sha256 gcry_sha512 part_msdos" --recheck "${grub_bootdev}"
var_update_grub_required="true"
fi
elif [[ "${grub_force_efi,,}" == "true" ]]; then
if [[ "${VAR_RECIPE_TABLE,,}" == "gpt" && "${VAR_RECIPE_FIRMWARE,,}" == "uefi" ]]; then
do_in_target "${TARGET}" grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Debian --modules="btrfs cryptodisk luks2 gcry_rijndael gcry_sha256 gcry_sha512 part_gpt" --force-extra-removable
var_update_grub_required="true"
else
do_log "emergency" "true" "Unsupported combination of partition table: '${VAR_RECIPE_TABLE,,}' and setting: grub_force_efi '${grub_force_efi,,}'."
return "${ERR_GRUB_EFI_FORCE}"
fi
fi
### Enable booting from LUKS encrypted devices by default.
cat << EOF >> "${TARGET}/etc/default/grub"
# Enable booting from LUKS encrypted devices by default.
GRUB_ENABLE_CRYPTODISK=y
EOF
var_update_grub_required="true"
### Install a boot menu background.
if [[ "${grub_background_enable,,}" == "true" ]]; then
declare var_background
var_background=$(basename "${grub_background_path}")
cp --no-preserve=ownership "${grub_background_path}" "${TARGET}/etc/default/grub.d/${var_background}" || return "${ERR_GRUB_BACKGROUND}"
chmod 0640 "${TARGET}/etc/default/grub.d/${var_background}" || return "${ERR_GRUB_BACKGROUND}"
cat << EOF >> "${TARGET}/etc/default/grub"
# Enable boot menu background.
GRUB_BACKGROUND="/etc/default/grub.d/${var_background}"
# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command 'vbeinfo'
GRUB_GFXMODE=1920x1080,1280x1024,1024x768,800x600
GRUB_GFXPAYLOAD_LINUX=keep
EOF
var_update_grub_required="true"
fi
### Change GRUB OS detection configuration accordingly.
if [[ "${grub_prober,,}" == "true" ]]; then
cat << EOF >> "${TARGET}/etc/default/grub"
# If your computer has multiple operating systems installed, then you
# probably want to run os-prober. However, if your computer is a host
# for guest OSes installed via LVM or raw disk devices, running
# os-prober can cause damage to those guest OSes as it mounts
# filesystems to look for things.
GRUB_DISABLE_OS_PROBER=false
EOF
var_update_grub_required="true"
elif [[ "${grub_prober,,}" == "false" ]]; then
cat << EOF >> "${TARGET}/etc/default/grub"
# If your computer has multiple operating systems installed, then you
# probably want to run os-prober. However, if your computer is a host
# for guest OSes installed via LVM or raw disk devices, running
# os-prober can cause damage to those guest OSes as it mounts
# filesystems to look for things.
GRUB_DISABLE_OS_PROBER=true
EOF
var_update_grub_required="true"
fi
else
do_log "info" "true" "GRUB2 setup skipped."
fi
[[ "${var_update_grub_required}" == "true" ]] && do_in_target "${TARGET}" update-grub
### Setting the permissions to read and write for root only prevents non-root users from seeing the boot parameters or changing them.
chown root:root "${TARGET}/boot/grub/grub.cfg"
chmod 0600 "${TARGET}/boot/grub/grub.cfg"
chmod -R 0700 "${TARGET}/etc/grub.d"
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,95 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Append GRUB superuser block to 40_custom.
# Arguments:
# 1: Username
# 2: Password
#######################################
#######################################
# Append GRUB superuser block to '/etc/grub.d/40_custom'.
# Globals:
# DIR_CNF
# ERR_READ_GRUB_FILE
# TARGET
# VAR_DEBUG_TRACE
# Arguments:
# None
# Returns:
# 0: on success
# ERR_READ_GRUB_FILE
#######################################
setup_grub_password() {
declare var_username="superadmin"
declare var_password=""
declare var_password_file="${DIR_CNF}/password_grub.txt"
declare var_of="${TARGET}/etc/grub.d/40_custom"
declare var_grub_entry
### No tracing for security reasons
[[ "${VAR_DEBUG_TRACE,,}" == "true" ]] && set +x
if [[ ! -f "${var_password_file}" ]] || ! IFS= read -r var_password < "${var_password_file}"; then
return "${ERR_READ_GRUB_FILE}"
fi
### Turn on tracing again
[[ "${VAR_DEBUG_TRACE,,}" == "true" ]] && set -x
var_grub_entry=$(generate_grub_password_pbkdf2 "${var_username}" "${var_password}")
### Append if not already present
if ! grep -q "set superusers=" "${var_of}"; then
{
echo ""
echo "### Added by CISS.debian.installer ###"
echo "$var_grub_entry"
echo "### End by CISS.debian.installer ###"
} >> "$var_of"
fi
do_in_target "${TARGET}" update-grub
return 0
}
#######################################
# Generate PBKDF2 password hash for GRUB.
# Arguments:
# 1: Username (default to superadmin).
# 2: User password.
# Returns:
# 0: on success
#######################################
generate_grub_password_pbkdf2() {
declare var_user="${1:-superadmin}"
declare var_pass="${2:?error: password required}"
expect <<EOF
log_user 0
spawn grub-mkpasswd-pbkdf2 --iteration-count=131072 --salt=64 --buflen=64
expect "Enter password:"
send "$var_pass\r"
expect "Reenter password:"
send "$var_pass\r"
expect {
-re {PBKDF2 hash of your password is (\S+)} {
puts "set superusers=\"$var_user\"\npassword_pbkdf2 $var_user \$expect_out(1,string)"
}
}
EOF
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,63 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
### Options in "GRUB_CMDLINE_LINUX" are always effective.
### Options in "GRUB_CMDLINE_LINUX_DEFAULT" are effective ONLY during normal boot (NOT during recovery mode).
guard_sourcing
#######################################
# Hardening Grub boot parameter.
# Globals:
# ARY_BOOTPARAM
# TARGET
# VAR_GRUB_CMDLINE_LINUX_DEFAULT
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_grub_bootparameter() {
declare var_nuke_string="" var_param=""
grub_extract_current_string
for var_param in "${ARY_BOOTPARAM[@]}"; do
if [[ -z "${var_param}" ]]; then
do_log "warn" "true" "Empty GRUB parameter detected and skipped."
continue
fi
if grep -q --word-regexp "${var_param%%=*}" <<< "${VAR_GRUB_CMDLINE_LINUX_DEFAULT}"; then
do_log "info" "true" "Skipping duplicate kernel parameter: '${var_param}'."
continue
fi
VAR_GRUB_CMDLINE_LINUX_DEFAULT+=" ${var_param}"
done
if [[ "${VAR_NUKE}" == "true" ]]; then
var_nuke_string="nuke=${VAR_NUKE_HASH}"
VAR_GRUB_CMDLINE_LINUX+=" ${var_nuke_string}"
fi
grub_finalize_string
do_in_target "${TARGET}" update-grub
do_log "info" "true" "Setting GRUB kernel parameters: ${VAR_GRUB_CMDLINE_LINUX_DEFAULT}"
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,61 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Entropy collection improvements '/usr/lib/modules-load.d/30_security-misc.conf'.
# Globals:
# TARGET
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_kernel_modules() {
### Entropy collection improvements
mkdir -p "${TARGET}/usr/lib/modules-load.d"
cat << EOF >| "${TARGET}/usr/lib/modules-load.d/30_security-misc.conf"
## The jitterentropy_rng kernel module provides a reliable and hardware-independent source of cryptographic entropy by measuring
## minute variations in CPU execution timing (jitter). These microsecond-level differences are unpredictable and rooted in
## physical randomness, making them suitable for high-quality entropy generation. Unlike other RNG methods that rely on hardware
## features like TPMs or Intel's RDRAND, which may not be available or trusted, jitterentropy_rng works across all platforms,
## including virtual machines and air-gapped systems. It is compliant with NIST SP 800-90B and BSI TR-02102-4, ensuring secure
## entropy even during early boot stages, such as in initramfs or before full userland is available. It is the most secure,
## standards-compliant, and universally applicable entropy source for hardened Linux environments.
## https://www.whonix.org/wiki/Dev/Entropy
## https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=927972
## https://forums.whonix.org/t/jitterentropy-rngd/7204
jitterentropy_rng
EOF
chmod 0644 "${TARGET}/usr/lib/modules-load.d/30_security-misc.conf"
do_log "info" "true" "Installed: '/usr/lib/modules-load.d/30_security-misc.conf'."
return 0
}
#######################################
# Blacklist some kind of potential hazardous modules via '/etc/modprobe.d/0000_ciss_debian_installer.conf'.
# Globals:
# TARGET
# VAR_SETUP_PATH
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_modprobe() {
install -D -m 0755 -o root -g root "${VAR_SETUP_PATH}/includes/etc/modprobe.d/0000_ciss_debian_installer.cnf" \
"${TARGET}/etc/modprobe.d/0000_ciss_debian_installer.conf"
do_log "info" "true" "Installed: '/etc/modprobe.d/0000_ciss_debian_installer.conf'."
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,31 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Install Kernel Hardening-Presets '/etc/sysctl.d/99_local.hardened'.
# Globals:
# TARGET
# VAR_SETUP_PATH
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_kernel_sysctl() {
install -D -m 0644 -o root -g root "${VAR_SETUP_PATH}/includes/etc/sysctl.d/99_local.hardened.ini" \
"${TARGET}/etc/sysctl.d/99_local.hardened"
do_log "info" "true" "Installed: '/etc/sysctl.d/99_local.hardened'."
return 0
}
# 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-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Install microcode updates depending on architecture (amd64, arm64, intel64) and environment (Baremetal, VM).
# Globals:
# TARGET
# Arguments:
# None
# Returns:
# 0: on success
#######################################
installation_microcode() {
declare var_microcode_pkgs=""
declare var_whereiam; var_whereiam=$(virt-what | head -n1)
[[ -z "${var_whereiam}" ]] && var_whereiam="baremetal"
declare var_cpu_vendor; var_cpu_vendor=$(lscpu | awk -F: '/Vendor ID/ {print $2}' | xargs)
case "${var_cpu_vendor}" in
*AuthenticAMD*) var_microcode_pkgs="amd64-microcode" ;;
*GenuineIntel*) var_microcode_pkgs="intel-microcode" ;;
""|*ARM*|*arm*|*) var_microcode_pkgs=""; do_log "info" "true" "ARM or unknown CPU detected, skipping microcode installation." ;;
esac
###########################################################################################
# Generally, it is best to let the hypervisor handle CPU microcode updates. #
###########################################################################################
if [[ "${var_whereiam}" != "kvm" && -n "${var_microcode_pkgs}" ]]; then
if ! do_in_target_script "${TARGET}" "dpkg -l ${var_microcode_pkgs} >/dev/null 2>&1"; then
do_in_target "${TARGET}" apt-get install -y "${var_microcode_pkgs}"
fi
else
do_log "info" "true" "Skipping microcode install (${var_whereiam}, ${var_microcode_pkgs:-none})"
fi
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,112 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Setup ssh server.
# Globals:
# BASH_REMATCH
# DIR_BAK
# DIR_LOG
# TARGET
# VAR_FINAL_FQDN
# VAR_FINAL_IPV4
# VAR_FINAL_IPV6
# VAR_SETUP_PATH
# ssh_port
# ssh_root_ca
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_ssh() {
do_in_target "${TARGET}" apt-get install -y ssh
#######################################
# Variable declaration
#######################################
declare -a ary_user=()
declare -i i
declare var_auth="" var_name=""
install -D -m 0644 -o root -g root "${VAR_SETUP_PATH}/includes/etc/banner" "${TARGET}/etc/"
install -D -m 0644 -o root -g root "${VAR_SETUP_PATH}/includes/etc/motd" "${TARGET}/etc/"
do_log "info" "true" "Installed SSH banner and motd to '${TARGET}/etc/'."
### Only process those for which both *_name and *_authentication_access_ssh are set.
for ((i = 0; i <= VAR_USER_MAX; i++)); do
var_auth="user_user${i}_authentication_access_ssh"
var_name="user_user${i}_name"
if [[ -v "${var_auth}" && -v "${var_name}" && "${!var_auth}" == "true" ]]; then
ary_user+=("${!var_name}")
fi
done
rm -rf "${TARGET}"/etc/ssh/ssh_host_*key*
#shellcheck disable=SC2312
do_in_target "${TARGET}" ssh-keygen -o -N "" -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -C "root@${VAR_FINAL_FQDN}-$(date -I)"
#shellcheck disable=SC2312
do_in_target "${TARGET}" ssh-keygen -o -N "" -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -C "root@${VAR_FINAL_FQDN}-$(date -I)"
mkdir -p "${DIR_BAK}/etc/ssh"
cp "${TARGET}/etc/ssh/sshd_config" "${DIR_BAK}/etc/ssh/sshd_config.bak"
chmod 0644 "${DIR_BAK}/etc/ssh/sshd_config.bak"
cp "${TARGET}/etc/ssh/ssh_config" "${DIR_BAK}/etc/ssh/ssh_config.bak"
chmod 0644 "${DIR_BAK}/etc/ssh/ssh_config.bak"
rm -f "${TARGET}/etc/ssh/sshd_config"
install -D -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/etc/ssh/sshd_config" "${TARGET}/etc/ssh/sshd_config"
chmod 0600 "${TARGET}/etc/ssh/ssh_config"
# shellcheck disable=SC2153
sed -i -E "s|^\s*ListenAddress\s+.*$|$(printf '%-30s%s' 'ListenAddress' "${VAR_FINAL_IPV4}")|" "${TARGET}/etc/ssh/sshd_config"
if [[ -n "${VAR_FINAL_IPV6}" ]]; then
sed -i -E "s|^\s*ListenAddress\s+::.*$|$(printf '%-30s%s' 'ListenAddress' "${VAR_FINAL_IPV6}")|" "${TARGET}/etc/ssh/sshd_config"
else
sed -i "/^\s*ListenAddress\s*::/d" "${TARGET}/etc/ssh/sshd_config"
fi
sed -i -E "s|^\s*Port\s+.*$|$(printf '%-30s%s' 'Port' "${ssh_port}")|" "${TARGET}/etc/ssh/sshd_config"
if (( ${#ary_user[@]} > 0 )); then
sed -i -E "s|^\s*AllowUsers\s+.*$|$(printf '%-30s%s' 'AllowUsers' "root ${ary_user[*]}")|" "${TARGET}/etc/ssh/sshd_config"
fi
if [[ -n "${ssh_root_ca}" ]]; then
install -D -m 0644 -o root -g root "${VAR_SETUP_PATH}${ssh_root_ca}" "${TARGET}/etc/ssh/"
sed -i -E "s|^\s*TrustedUserCAKeys\s+.*$|$(printf '%-30s%s' 'TrustedUserCAKeys' "/etc/ssh/${ssh_root_ca}")|" "${TARGET}/etc/ssh/sshd_config"
fi
do_in_target_script "${TARGET}" "sshd -T >| ${DIR_LOG}/sshd_config.log"
do_in_target_script "${TARGET}" "ssh-keygen -r ${VAR_FINAL_FQDN}. >| ${DIR_LOG}/ssh.log"
###########################################################################################
# The file /etc/profile.d/idle-users.sh is created to set two read-only #
# environment variables: TMOUT and HISTFILE. #
# TMOUT=14400 ensures that users are automatically logged out after 4 hours of inactivity.#
# readonly HISTFILE ensures that the command history cannot be changed. #
# The chmod +x command ensures that the file is executed in every shell session. #
###########################################################################################
echo "readonly TMOUT=14400" >| "${TARGET}/etc/profile.d/idle-users.sh"
# TODO: Decide: set HISTFILE=/dev/null or leave unset (readonly var requires value!)
#echo "readonly HISTFILE" >> "${TARGET}/etc/profile.d/idle-users.sh"
chmod +x "${TARGET}/etc/profile.d/idle-users.sh"
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,60 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Build Ultra Hardened dropbear-2025.88 from sources.
# Globals:
# DIR_TMP
# ERR_PATH_NOT_VALID
# VAR_SETUP_PATH
# Arguments:
# None
# Returns:
# ERR_PATH_NOT_VALID
# 0: on success
#######################################
build_dropbear() {
declare var_dropbear_version="2025.88"
declare var_tar="${VAR_SETUP_PATH}/upgrades/dropbear/dropbear-${var_dropbear_version}.tar.bz2"
declare var_build_dir="${DIR_TMP}/build/dropbear-${var_dropbear_version}"
mkdir -p "${DIR_TMP}/build"
cp "${var_tar}" "${DIR_TMP}/build"
tar xjf "${DIR_TMP}/build/dropbear-${var_dropbear_version}.tar.bz2" -C "${DIR_TMP}/build" || return "${ERR_PATH_NOT_VALID}"
cp "${VAR_SETUP_PATH}/upgrades/dropbear/localoptions.h" "${var_build_dir}"
cd "${var_build_dir}" || return "${ERR_PATH_NOT_VALID}"
# Flag Purpose
# -fPIE: Generate position-independent executable code
# -pie: Link the executable as PIE (so that ASLR works)
# -static: Fully statically linked against musl
# -s: Strip unnecessary symbols directly during linking
# -Wl,-z,relro,-z,now: Enables full RELRO (symbol resolution at program startup)
CC=musl-gcc \
CFLAGS="-Os -fPIE -Wno-undef -fstack-protector-strong -D_FORTIFY_SOURCE=2" \
LDFLAGS="-static -pie -s -Wl,-z,relro,-z,now" \
./configure \
--enable-static \
--enable-openpty \
--disable-pam \
--disable-zlib
make -j"$(nproc)"
do_log "info" "true" "Ultra Hardened dropbear-2025.88 build successfully from sources."
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,40 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Install Dropbear Initramfs and replace the binaries with the previous Ultra Hardened build.
# Globals:
# DIR_TMP
# TARGET
# Arguments:
# None
# Returns:
# 0: on success
#######################################
install_dropbear_initramfs() {
declare var_file
do_in_target "${TARGET}" apt-get install -y dropbear-initramfs
do_in_target "${TARGET}" apt-mark hold -y dropbear dropbear-initramfs
mv "${TARGET}/usr/sbin/dropbear" "${TARGET}/usr/sbin/dropbear.2022.83"
install -D -m 0755 -o root -g root "${DIR_TMP}/build/dropbear-2025.88/dropbear" "${TARGET}/usr/sbin/"
for var_file in dbclient dropbearconvert dropbearkey; do
mv "${TARGET}/usr/bin/${var_file}" "${TARGET}/usr/bin/${var_file}.2022.83"
install -D -m 0755 -o root -g root "${DIR_TMP}/build/dropbear-2025.88/${var_file}" "${TARGET}/usr/bin/"
done
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,250 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Setup Dropbear Initramfs Environment.
# Globals:
# HMP_PATH_ENCLABEL
# TARGET
# VAR_CRYPT_ROOT
# VAR_FINAL_FQDN
# VAR_FINAL_IPV4
# VAR_FINAL_IPV4_GW
# VAR_FINAL_IPV4_SUBNET
# VAR_FINAL_NIC
# VAR_GRUB_CMDLINE_LINUX
# VAR_SETUP_PATH
# dropbear_dhcp
# dropbear_firewall
# dropbear_port
# network_static_ipv4nameserver_0
# network_static_ipv4nameserver_1
# ssh_allow_ipv4_0
# user_root_ssh_pubkeys_0
# user_root_ssh_pubkeys_1
# user_root_ssh_pubkeys_2
# user_root_ssh_pubkeys_3
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_dropbear() {
### Prepare strong dropbear host keys
rm -f "${TARGET}"/etc/dropbear/initramfs/dropbear*key
do_in_target "${TARGET}" /usr/bin/dropbearkey -t rsa -s 4096 -f /etc/dropbear/initramfs/dropbear_rsa_host_key
do_in_target "${TARGET}" /usr/bin/dropbearkey -t ed25519 -f /etc/dropbear/initramfs/dropbear_ed25519_host_key
chmod 0600 "${TARGET}"/etc/dropbear/initramfs/dropbear*key
chown root:root "${TARGET}"/etc/dropbear/initramfs/dropbear*key
### Prepare dropbear authorized_keys
touch "${TARGET}/etc/dropbear/initramfs/authorized_keys" && chmod 0600 "${TARGET}/etc/dropbear/initramfs/authorized_keys"
printf "%s\n" "${user_root_sshpubkey}" > "${TARGET}/etc/dropbear/initramfs/authorized_keys"
install -D -m 0755 -o root -g root "${VAR_SETUP_PATH}/includes/etc/banner" "${TARGET}/etc/dropbear/initramfs/"
### Check for initramfs "IP"-variable: static or dynamic configuration vai dhcp.
if [[ "${dropbear_dhcp,,}" != "true" ]]; then
declare network_static_ipv4ntpserver_0="192.53.103.108"
### "IP=<HOST IP>::<GATEWAY IP>:<SUBNET MASK>:<FQDN>:<NIC>:none:<DNS 0 IP>:<DNS 1 IP>:<NTP IP>"
printf "IP=%s::%s:%s:%s:%s:none:%s:%s:%s\n" \
"${VAR_FINAL_IPV4}" \
"${VAR_FINAL_IPV4_GW}" \
"${VAR_FINAL_IPV4_SUBNET}" \
"${VAR_FINAL_FQDN}" \
"${VAR_FINAL_NIC}" \
"${network_static_ipv4nameserver_0:-135.181.207.105}" \
"${network_static_ipv4nameserver_1:-89.58.62.53}" \
"${network_static_ipv4ntpserver_0:-192.53.103.104}" \
>| "${TARGET}/etc/initramfs-tools/conf.d/ip"
else
### "IP=:::::<NIC>:dhcp"
printf "IP=:::::%s:dhcp\n" "${VAR_FINAL_NIC}" >| "${TARGET}/etc/initramfs-tools/conf.d/ip"
fi
### Generate dropbear configuration file
write_dropbear_conf
### Prepare Grub Bootparameter for LUKS decryption of '/root' and '/recovery'.
# Options in "GRUB_CMDLINE_LINUX" are always effective.
# Options in "GRUB_CMDLINE_LINUX_DEFAULT" are effective ONLY during normal boot (NOT during recovery mode).
grub_extract_current_string
declare var_label="${HMP_PATH_ENCLABEL["LABEL_/"]}"
VAR_GRUB_CMDLINE_LINUX="${VAR_GRUB_CMDLINE_LINUX} cryptdevice=${VAR_CRYPT_ROOT}:cryptroot root=/dev/mapper/${var_label}"
grub_finalize_string
### Install the script to be called by 'update-initramfs' for updating 'PATH'-variable inside initramfs.
install -D -m 0755 -o root -g root "${VAR_SETUP_PATH}/includes/initramfs-tools/scripts/init-top/fixpath.sh" \
"${TARGET}/includes/initramfs-tools/scripts/init-top/"
### Install the script to be called by 'update-initramfs' for customizing dropbear inside initramfs.
install -D -m 0755 -o root -g root "${VAR_SETUP_PATH}/includes/initramfs-tools/hooks/custom-initramfs.sh" \
"${TARGET}/includes/initramfs-tools/hooks/"
### Install the script to be called by 'update-initramfs' for customizing prompt inside initramfs environment.
install -D -m 0755 -o root -g root "${VAR_SETUP_PATH}/includes/initramfs-tools/hooks/custom-prompt.sh" \
"${TARGET}/includes/initramfs-tools/hooks/"
### Install the script to be called inside initramfs environment for unlocking LUKS and NUKE Devices.
install -D -m 0755 -o root -g root "${VAR_SETUP_PATH}/includes/initramfs-tools/files/unlock_wrapper.sh" \
"${TARGET}/includes/initramfs-tools/files/"
install -D -m 0755 -o root -g root "${VAR_SETUP_PATH}/includes/initramfs-tools/files/unlock_wrapper.sh" \
"${TARGET}/usr/lib/cryptsetup/scripts/"
### Install the script to be called inside Host environment for signing 'unlock_wrapper.sh'-script.
install -D -m 0700 -o root -g root "${VAR_SETUP_PATH}/includes/initramfs-tools/files/unlock_wrapper_signer.sh" \
"${TARGET}/includes/initramfs-tools/files/"
### Install the script to be called by 'update-initramfs' for installing the necessary modules to load into initramfs environment.
install -D -m 0644 -o root -g root "${VAR_SETUP_PATH}/includes/initramfs-tools/modules" \
"${TARGET}/includes/initramfs-tools/"
declare var_modules; var_modules=$(grep_nic_driver_modules)
cat << EOF >> "${TARGET}/includes/initramfs-tools/modules"
### Custom NIC driver
${var_modules}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
### Install the script to be called inside initramfs environment for preparing dropbear execution.
do_in_target "${TARGET}" mv /usr/share/initramfs-tools/scripts/init-premount/dropbear /usr/share/initramfs-tools/scripts/init-premount/dropbear.2022.83
install -D -m 0755 -o root -g root "${VAR_SETUP_PATH}/includes/usr/share/initramfs-tools/scripts/init-premount/dropbear" \
"${TARGET}/includes/usr/share/initramfs-tools/scripts/init-premount/"
### Install the variable file to be called inside initramfs environment for setting up dropbear firewall.
install -D -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/initramfs-tools/files/dropbear_fw.cnf" \
"${TARGET}/includes/initramfs-tools/files/dropbear_fw.conf"
### Install the firewall script to be called inside initramfs environment for setting up dropbear firewall.
install -D -m 0755 -o root -g root "${VAR_SETUP_PATH}/includes/initramfs-tools/files/dropbear_fw.sh" \
"${TARGET}/includes/initramfs-tools/files/"
if [[ "${dropbear_firewall,,}" == "true" && -n "${ssh_allow_ipv4_0}" ]]; then
sed -i 's/^DROPBEAR_FIREWALL_ENABLED=0$/DROPBEAR_FIREWALL_ENABLED=1/' "${TARGET}/includes/initramfs-tools/files/dropbear_fw.cnf"
sed -i '/^# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh$/d' "${TARGET}/includes/initramfs-tools/files/dropbear_fw.cnf"
cat << EOF >> "${TARGET}/includes/initramfs-tools/files/dropbear_fw.cnf"
DROPBEAR_PORT=${dropbear_port}
DROPBEAR_JUMP_SERVER_IP=${ssh_allow_ipv4_0}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
fi
### Finally, deploy all changes done via 'update-grub' and 'update-initramfs'.
do_in_target "${TARGET}" update-grub
do_in_target "${TARGET}" update-initramfs -u -v -k all
return 0
}
#######################################
# Write '/etc/dropbear/initramfs/dropbear.conf'.
# Globals:
# TARGET
# ssh_port
# Arguments:
# None
# Returns:
# 0: on success
#######################################
write_dropbear_conf() {
[[ -z "${dropbear_port:-}" ]] && dropbear_port="2222"
cat << EOF >| "${TARGET}/etc/dropbear/initramfs/dropbear.conf"
#
# Configuration options for the dropbear-initramfs boot scripts.
# Variable assignment follow shell semantics and escaping/quoting rules.
# You must run update-initramfs(8) to effect changes to this file (like
# for other files in the '/etc/dropbear/initramfs' directory).
#
# Command line options to pass to dropbear(8)
# Dropbear options for 2025+:
# -b: Display the contents of bannerfile before user login
# -E: Log to stderr
# -I: Idle timeout in seconds
# -K: Keepalive interval in seconds
# -p: Specify port (and optionally address)
# -w: Disable root login (SHOULD NOT be implemented for initramfs)
DROPBEAR_OPTIONS="-b /etc/dropbear/banner -c /usr/local/bin/unlock_wrapper.sh -E -I 300 -K 60 -p ${dropbear_port}"
#
# On local (non-NFS) mounts, interfaces matching this pattern are
# brought down before exiting the ramdisk to avoid dirty network
# configuration in the normal kernel.
# The special value 'none' keeps all interfaces up and preserves routing
# tables and addresses.
#
#IFDOWN="*"
#
# On local (non-NFS) mounts, the network stack and dropbear are started
# asynchronously at init-premount stage. This value specifies the
# maximum number of seconds to wait (while the network/dropbear are
# being configured) at init-bottom stage before terminating dropbear and
# bringing the network down.
# If the timeout is too short, and if the boot process is not blocking
# on user input supplied via SSHd (ie no remote unlocking), then the
# initrd might pivot to init(1) too early, thereby causing a race
# condition between network configuration from initramfs vs from the
# normal system.
#
#DROPBEAR_SHUTDOWN_TIMEOUT=60
EOF
do_log "info" "true" "Written: '${TARGET}/etc/dropbear/initramfs/dropbear.conf'."
return 0
}
#######################################
# Collect NIC driver modules for initramfs installation.
# Arguments:
# None
# Returns:
# 0: on success
#######################################
grep_nic_driver_modules() {
### Collect all ethernet driver names and sort them uniquely.
declare -a _mods
declare var_nic_module var_nic_modules
readarray -t _mods < <(
lspci -k \
| grep -A2 -i ethernet \
| grep 'Kernel driver in use' \
| awk '{print $5}' \
| sort -u
)
### If only one entry remains, save it in 'var_nic_module', otherwise save all modules in 'var_nic_modules'.
if [[ "${#_mods[@]}" -eq 1 ]]; then
var_nic_module="${_mods[0]}"
else
var_nic_modules="${_mods[*]}"
fi
if [[ -n "$var_nic_module" ]]; then
echo "${var_nic_module}"
else
echo "${var_nic_modules}"
fi
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,153 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Updating user accounts.
# Globals:
# TARGET
# VAR_SETUP_PATH
# VAR_USER_MAX
# user_root_authentication_access_ssh
# user_root_password
# user_root_shell
# user_root_sshpubkey
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_accounts() {
#######################################
# Declare Variables
#######################################
declare -i i
declare tmp_username="" tmp_fullname="" tmp_uid="" tmp_gid="" tmp_shell="" tmp_password="" tmp_sshpubkey="" tmp_sudo="" \
tmp_restricted=""
declare var_username="" var_fullname="" var_uid="" var_gid="" var_shell="" var_password="" var_sshpubkey="" var_sudo="" \
var_restricted="" var_chpasswd="" var_sshdir=""
### Hardening '/etc/login.defs'
rm -f "${TARGET}/etc/login.defs"
install -D -m 0644 -o root -g root "${VAR_SETUP_PATH}/includes/etc/login.defs" "${TARGET}/etc/"
### Hardening '/etc/security/pwquality.conf'
rm -f "${TARGET}/etc/security/pwquality.conf"
install -D -m 0644 -o root -g root "${VAR_SETUP_PATH}/includes/etc/security/pwquality.cnf" "${TARGET}/etc/security/pwquality.conf"
### Preparing the root account
chown root:root "${TARGET}/etc/passwd" "${TARGET}/etc/shadow" "${TARGET}/etc/group" "${TARGET}/etc/gshadow"
chmod 0644 "${TARGET}/etc/passwd" "${TARGET}/etc/group"
chmod 0600 "${TARGET}/etc/shadow" "${TARGET}/etc/gshadow"
if [[ -x "${TARGET}${user_root_shell}" ]]; then
do_in_target "${TARGET}" chsh -s "${user_root_shell}" root
else
do_log "warn" "true" "Shell: '${user_root_shell}' not found for: 'root'. Using '/bin/bash' instead."
fi
var_chpasswd="root:${user_root_password}"
do_in_target_script "${TARGET}" "echo \"${var_chpasswd}\" | chpasswd -e"
var_chpasswd=""
install -d -m 0700 -o root -g root "${TARGET}/root/.ssh"
install -m 0600 -o root -g root /dev/null "${TARGET}/root/.ssh/authorized_keys"
grep -qxF "${user_root_sshpubkey}" "${TARGET}/root/.ssh/authorized_keys" || \
printf "%s\n" "${user_root_sshpubkey}" >> "${TARGET}/root/.ssh/authorized_keys"
if [[ "${user_root_authentication_access_ssh}" == "false" ]]; then
if grep -q '^\s*PermitRootLogin' "${TARGET}/etc/ssh/sshd_config"; then
sed -i 's/^\s*PermitRootLogin\s\+.*/PermitRootLogin no/' "${TARGET}/etc/ssh/sshd_config"
else
echo 'PermitRootLogin no' >> "${TARGET}/etc/ssh/sshd_config"
fi
fi
### Install all user accounts.
for ((i = 0; i <= VAR_USER_MAX; i++)); do
tmp_username="user_user${i}_name"
tmp_fullname="user_user${i}_fullname"
tmp_uid="user_user${i}_uid"
tmp_gid="user_user${i}_gid"
tmp_shell="user_user${i}_shell"
tmp_password="user_user${i}_password"
tmp_sshpubkey="user_user${i}_sshpubkey"
tmp_sudo="user_user${i}_privileges_sudo"
tmp_restricted="user_user${i}_privileges_restricted"
var_username="${!tmp_username}"
var_fullname="${!tmp_fullname}"
var_uid="${!tmp_uid}"
var_gid="${!tmp_gid}"
var_shell="${!tmp_shell}"
var_password="${!tmp_password}"
var_sshpubkey="${!tmp_sshpubkey}"
var_sudo="${!tmp_sudo}"
var_restricted="${!tmp_restricted}"
do_in_target "${TARGET}" getent group "${var_username}" >/dev/null || \
do_in_target "${TARGET}" groupadd --gid "${var_gid}" "${var_username}"
if [[ "${var_restricted}" == "false" ]]; then
do_in_target "${TARGET}" useradd \
--comment "${var_fullname}" \
--create-home \
--expiredate 2102-12-31 \
--gid "${var_gid}" \
--home-dir /home/"${var_username}" \
--inactive 0 \
--shell "${var_shell}" \
--uid "${var_uid}" \
"${var_username}"
else
do_in_target "${TARGET}" useradd \
--comment "${var_fullname}" \
--expiredate 2102-12-31 \
--gid "${var_gid}" \
--home-dir /home/"${var_username}" \
--inactive 0 \
--no-create-home \
--shell "${var_shell}" \
--uid "${var_uid}" \
"${var_username}"
fi
var_chpasswd="${var_username}:${var_password}"
do_in_target_script "${TARGET}" "echo \"${var_chpasswd}\" | chpasswd -e"
var_chpasswd=""
if [[ "${var_sudo}" == "true" ]]; then
do_in_target "${TARGET}" usermod -aG sudo "${var_username}"
fi
if [[ -n "${var_sshpubkey}" ]]; then
var_sshdir="${TARGET}/home/${var_username}/.ssh"
install -d -m 0700 -o "${var_username}" -g "${var_username}" "${var_sshdir}"
install -m 0600 -o "${var_username}" -g "${var_username}" /dev/null "${var_sshdir}/authorized_keys"
grep -qxF "${var_sshpubkey}" "${var_sshdir}/authorized_keys" || \
printf "%s\n" "${var_sshpubkey}" >> "${var_sshdir}/authorized_keys"
fi
do_log "info" "true" "Created user: [${var_username}] UID: [${var_uid}], GID: [${var_gid}]"
done
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,36 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Install Debian Packages as specified in 'preseed.yaml'.
# Globals:
# ARY_PACKAGES
# TARGET
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_packages() {
do_in_target_script "${TARGET}" "apt-get update -y > /dev/null"
declare var_install_candidate=""
for var_install_candidate in "${ARY_PACKAGES[@]}"; do
do_in_target "${TARGET}" apt-get install -y "${var_install_candidate}"
done
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,23 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Setup sudo.
# Arguments:
# None
#######################################
setup_sudo() {
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,58 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# 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.; <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.installer
# SPDX-Security-Contact: security@coresecret.eu
guard_sourcing
#######################################
# Setup chrony NTPSec client.
# Globals:
# ARY_NTPSRVR
# DIR_BAK
# NL
# TARGET
# VAR_SETUP_PATH
# Arguments:
# None
# Returns:
# 0: on success
#######################################
setup_chrony() {
# shellcheck disable=SC2155
declare var_of="$(mktemp --tmpdir --mode=0600 /tmp/var_of.XXXXXXXX)"
declare var_ntp_server
for var_ntp_server in "${ARY_NTPSRVR[@]}"; do
printf "server %s iburst nts minpoll 5 maxpoll 9 %s" "${var_ntp_server}" "${NL}" >> "${var_of}"
done
printf "# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh %s" "${NL}" >> "${var_of}"
mkdir -p "${TARGET}/var/log/chrony"
do_in_target "${TARGET}" apt-get install chrony -y
if [[ ! -e "${TARGET}/etc/systemd/system/multi-user.target.wants/chrony.service" ]]; then
ln -s "${TARGET}/lib/systemd/system/chrony.service" "${TARGET}/etc/systemd/system/multi-user.target.wants/chrony.service"
fi
mkdir -p "${DIR_BAK}/etc/chrony"
mv "${TARGET}/etc/chrony/chrony.conf" "${DIR_BAK}/etc/chrony/chrony.conf.bak"
install -D -m 0644 -o root -g root "${VAR_SETUP_PATH}/includes/etc/chrony/chrony.cnf" "${TARGET}/etc/chrony/chrony.conf"
cat "${var_of}" >> "${TARGET}/etc/chrony/chrony.conf"
do_log "info" "false" "Chrony NTPsec client installed."
rm -f "${var_of}"
unset var_of
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh