#!/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 || return "${ERR_GUARD_SRCE}" ####################################### # Module for accompanying all 'CISS.debian.hardening' features into the Live ISO image. # Globals: # ARY_HANDLER_JUMPHOST # ARY_HANDLER_JUMPHOST_UNIQUE # BASH_SOURCE # VAR_ARCHITECTURE # VAR_HANDLER_BUILD_DIR # VAR_SSHFP # VAR_SSHPORT # VAR_SSHPUBKEY # VAR_WORKDIR # Arguments: # None # Returns: # 0: on success ####################################### hardening_ultra() { printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช %s starting ... \e[0m\n" "${BASH_SOURCE[0]}" # 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" ]]; then mkdir -p "${VAR_HANDLER_BUILD_DIR}/config/includes.binary" 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" chmod 0755 ./config/includes.chroot/etc/ciss/keys chmod 0444 ./config/includes.chroot/etc/ciss/keys/* else cp -af ./config/includes.chroot "${VAR_HANDLER_BUILD_DIR}/config" chmod 0755 ./config/includes.chroot/etc/ciss/keys chmod 0444 ./config/includes.chroot/etc/ciss/keys/* 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" ### ./config/package-lists --------------------------------------------------------------------------------------------------- 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" ### ./config/includes.chroot/root/.ssh --------------------------------------------------------------------------------------- install -d -m 0700 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh" install -m 0600 -o root -g root "${VAR_SSHPUBKEY}/authorized_keys" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/" 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 printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… Updating SSH Keys, Ports done. \e[0m\n" ### ./config/includes.chroot/etc/hosts. -------------------------------------------------------------------------------------- if [[ -f "${VAR_WORKDIR}/hosts.allow" ]]; then printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ ๐Ÿงช SSH Hardening Ultra ... \e[0m\n" mv "${VAR_WORKDIR}/hosts.allow" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/etc" mv "${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" 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 printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ โœ… %s successfully applied. \e[0m\n" "${BASH_SOURCE[0]}" return 0 } ### Prevents accidental 'unset -f'. # shellcheck disable=SC2034 readonly -f hardening_ultra # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh