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