#!/bin/bash # SPDX-Version: 3.0 # SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; # SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git # SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency # SPDX-FileCopyrightText: 2024-2025; WEIDNER, Marc S.; # SPDX-FileType: SOURCE # SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0 # SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework. # SPDX-PackageName: CISS.debian.live.builder # SPDX-Security-Contact: security@coresecret.eu guard_sourcing ####################################### # Wrapper for accompanying all CISS.debian.hardening features into the Live ISO image. # Globals: # ARY_HANDLER_JUMPHOST # ARY_HANDLER_JUMPHOST_UNIQUE # VAR_ARCHITECTURE # VAR_HANDLER_BUILD_DIR # VAR_SSHPORT # VAR_SSHPUBKEY # VAR_WORKDIR # Arguments: # None ####################################### hardening_ultra() { # shellcheck disable=SC2164 cd "${VAR_WORKDIR}" ### ./config/bootloaders printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช Copying ./config/bootloaders ... \e[0m\n" if [[ ! -d "${VAR_HANDLER_BUILD_DIR}/config/bootloaders" ]]; then mkdir -p "${VAR_HANDLER_BUILD_DIR}/config/bootloaders" cp -af ./config/bootloaders "${VAR_HANDLER_BUILD_DIR}/config" else cp -af ./config/bootloaders "${VAR_HANDLER_BUILD_DIR}/config" fi printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… Copying ./config/bootloaders done.\e[0m\n" ### ./config/includes.binary printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช Copying ./config/includes.binary ... \e[0m\n" if [[ ! -d "${VAR_HANDLER_BUILD_DIR}/config/includes.binary/boot/grub" ]]; then mkdir -p "${VAR_HANDLER_BUILD_DIR}/config/includes.binary/boot/grub" cp -af ./config/includes.binary "${VAR_HANDLER_BUILD_DIR}/config" else cp -af ./config/includes.binary "${VAR_HANDLER_BUILD_DIR}/config" fi printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… Copying ./config/includes.binary done.\e[0m\n" ### ./config/includes.chroot printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช Copying ./config/includes.chroot ... \e[0m\n" if [[ ! -d "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot" ]]; then mkdir -p "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot" cp -af ./config/includes.chroot "${VAR_HANDLER_BUILD_DIR}/config" else cp -af ./config/includes.chroot "${VAR_HANDLER_BUILD_DIR}/config" fi printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… Copying ./config/includes.chroot done.\e[0m\n" ### ./config/hooks/early if [[ -d "${VAR_WORKDIR}/config/hooks/early" ]]; then printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช Copying ./config/hooks/early ... \e[0m\n" if [[ ! -d "${VAR_HANDLER_BUILD_DIR}/config/hooks/early" ]]; then mkdir -p "${VAR_HANDLER_BUILD_DIR}/config/hooks/early" cp -af ./config/hooks/early "${VAR_HANDLER_BUILD_DIR}/config/hooks" else cp -af ./config/hooks/early "${VAR_HANDLER_BUILD_DIR}/config/hooks" fi printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… Copying ./config/hooks/early done.\e[0m\n" fi ### ./config/hooks/live printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช Copying ./config/hooks/live ... \e[0m\n" if [[ ! -d "${VAR_HANDLER_BUILD_DIR}/config/hooks/live" ]]; then mkdir -p "${VAR_HANDLER_BUILD_DIR}/config/hooks/live" cp -af ./config/hooks/live "${VAR_HANDLER_BUILD_DIR}/config/hooks" else cp -af ./config/hooks/live "${VAR_HANDLER_BUILD_DIR}/config/hooks" fi printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… Copying ./config/hooks/live done.\e[0m\n" printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช Copying ./config/package-lists ... \e[0m\n" if [[ ! -d "${VAR_HANDLER_BUILD_DIR}/config/package-lists" ]]; then mkdir -p "${VAR_HANDLER_BUILD_DIR}/config/package-lists" fi cp -af ./config/package-lists/live.list.common.chroot "${VAR_HANDLER_BUILD_DIR}/config/package-lists/live.list.chroot" case "${VAR_ARCHITECTURE}" in amd64) declare arch_list="./config/package-lists/live.list.amd64.chroot" declare arch_comment="# amd64 specific packages" ;; arm64) declare arch_list="./config/package-lists/live.list.arm64.chroot" declare arch_comment="# arm64 specific packages" ;; *) printf "\e[91m++++ ++++ ++++ ++++ ++++ ++++ ++ โŒ Unsupported architecture '%s'.\e[0m\n" "${VAR_ARCHITECTURE}" exit 1 ;; esac declare pkgs # shellcheck disable=SC2312 mapfile -t pkgs < <( grep -v '^\s*#' "${arch_list}" | sed '/^\s*$/d' ) awk -v comment="${arch_comment}" -v n_pkgs="${#pkgs[@]}" -v pkgs="$(printf '%s\n' "${pkgs[@]}")" ' BEGIN { split(pkgs, pkg_arr, "\n") inserted = 0 } { # Detect the vim-modeline (last line marker) if ($0 ~ /^# vim:.*$/ && !inserted) { print comment for (i = 1; i <= length(pkg_arr); i++) { print pkg_arr[i] } inserted = 1 } print } ' "${VAR_HANDLER_BUILD_DIR}/config/package-lists/live.list.chroot" > temp && mv temp "${VAR_HANDLER_BUILD_DIR}/config/package-lists/live.list.chroot" printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… Copying ./config/package-lists done.\e[0m\n" ### Updating SSH Keys, Ports. printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช Updating SSH Keys, Ports ... \e[0m\n" ### Check for static SSHFP key material via Gitea Actions Runner Secrets injection. if [[ "${VAR_SSHFP}" == "true" ]]; then rm -f "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/9930_hardening_ssh.chroot" rm -f "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/9935_hardening_ssh.chroot.tmpl" else rm -f "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/9935_hardening_ssh.chroot" rm -f "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/9935_hardening_ssh.chroot.tmpl" fi ### /config/includes.chroot/root/.ssh if [[ ! -d "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh" ]]; then mkdir -p "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh" cp -af "${VAR_SSHPUBKEY}/authorized_keys" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh" chmod 0600 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/authorized_keys" chown root:root "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/authorized_keys" declare -r sshport="${VAR_SSHPORT:-22}" ### /config/includes.chroot/etc/ssh/sshd_config # shellcheck disable=SC2155 declare pad="$(printf '%-29s' 'Port')" sed -i -E "/PORT_MUST_BE_CHANGED/ s|.*|${pad}${sshport}|" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/etc/ssh/sshd_config" ### /config/hooks/live/9950_hardening_fail2ban.chroot sed -i "s|PORT_MUST_BE_SET|${sshport}|g" "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/9950_hardening_fail2ban.chroot" ### /config/hooks/live/0900_ufw_setup.chroot sed -i "s|SSHPORT_MUST_BE_SET|${sshport}|g" "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot" ### /config/hooks/live/0900_ufw_setup.chroot if [[ ${#ARY_HANDLER_JUMPHOST[@]} -gt 0 ]]; then declare file="${VAR_HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot" sed -i "/^ufw allow in \"\${SSHPORT}\"\/tcp comment 'Incoming SSH (Custom-Port)'$/d" "${file}" declare line # shellcheck disable=SC2312 line=$(grep -n '^ufw default deny forward$' "${file}" | cut -d: -f1) if [[ -z "${line}" ]]; then printf "\e[91m++++ ++++ ++++ ++++ ++++ ++++ ++ โŒ'ufw default deny forward' not found in: '%s'\e[0m\n" "${file}" >&2 exit 1 fi declare host for host in "${ARY_HANDLER_JUMPHOST_UNIQUE[@]}"; do ((line++)) sed -i "${line}a ufw allow from ${host} to any port ${sshport} proto tcp comment \"Incoming SSH ([${host}]:${sshport})\"" "${file}" done fi else cp -af "${VAR_SSHPUBKEY}/authorized_keys" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh" chmod 0600 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/authorized_keys" chown root:root "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/authorized_keys" declare -r sshport="${VAR_SSHPORT:-22}" ### /config/includes.chroot/etc/ssh/sshd_config # shellcheck disable=SC2155 declare pad="$(printf '%-29s' 'Port')" sed -i -E "/PORT_MUST_BE_CHANGED/ s|.*|${pad}${sshport}|" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/etc/ssh/sshd_config" ### /config/hooks/live/9950_hardening_fail2ban.chroot sed -i "s|PORT_MUST_BE_SET|${sshport}|g" "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/9950_hardening_fail2ban.chroot" ### /config/hooks/live/0900_ufw_setup.chroot sed -i "s|SSHPORT_MUST_BE_SET|${sshport}|g" "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot" ### /config/hooks/live/0900_ufw_setup.chroot if [[ ${#ARY_HANDLER_JUMPHOST_UNIQUE[@]} -gt 0 ]]; then declare file="${VAR_HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot" sed -i "/^ufw allow in \"\${SSHPORT}\"\/tcp comment 'Incoming SSH (Custom-Port)'$/d" "${file}" declare line # shellcheck disable=SC2312 line=$(grep -n '^ufw default deny forward$' "${file}" | cut -d: -f1) if [[ -z "${line}" ]]; then printf "\e[91mโŒ Error: 'ufw default deny forward' not found in: '%s'\e[0m\n" "${file}" >&2 exit 1 fi declare host for host in "${ARY_HANDLER_JUMPHOST_UNIQUE[@]}"; do ((line++)) sed -i "${line}a ufw allow from ${host} to any port ${sshport} proto tcp comment \"Incoming SSH ([${host}]:${sshport})\"" "${file}" done fi fi printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… Updating SSH Keys, Ports done. \e[0m\n" ### /config/includes.chroot/etc/hosts.allow if [[ -f "${VAR_WORKDIR}/hosts.allow" ]]; then printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช SSH Hardening Ultra ... \e[0m\n" cp -af "${VAR_WORKDIR}/hosts.allow" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/etc" cp -af "${VAR_WORKDIR}/hosts.deny" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/etc" chmod 0644 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/etc/hosts.allow" chmod 0644 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/etc/hosts.deny" rm -f "${VAR_WORKDIR}/hosts.allow" rm -f "${VAR_WORKDIR}/hosts.deny" printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… SSH Hardening Ultra done.\e[0m\n" fi ### /config/hooks/live/9950_hardening_fail2ban.chroot if ((${#ARY_HANDLER_JUMPHOST[@]} > 0)); then printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช Updating fail2ban Jumphosts IPs ... \e[0m\n" # Join array entries with spaces, preserving any newlines declare ips="${ARY_HANDLER_JUMPHOST[*]}" # Flatten to a single line and strip literal brackets [] declare flat_ips # shellcheck disable=SC2312 flat_ips=$(printf "%s" "${ips}" | tr '\n' ' ' | tr -d '[]') # flat_ips now contains e.g., "123.128.111.42 2a03:ffff:0815:4711:... 2a03:.../64" # Perform an in-place replacement of IGNORE_IP_MUST_BE_SET with the cleaned list sed -i -E "/^[[:space:]]*ignoreip[[:space:]]*=/ s|IGNORE_IP_MUST_BE_SET|${flat_ips}|g" "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/9950_hardening_fail2ban.chroot" printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… Updating fail2ban Jumphosts IPs done. \e[0m\n" else printf "\e[93m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช No jump hosts configured, removing placeholder ... \e[0m\n" sed -i 's/IGNORE_IP_MUST_BE_SET//g' "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/9950_hardening_fail2ban.chroot" printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… Placeholder removed. \e[0m\n" fi } # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh