All checks were successful
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Successful in 1m41s
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
339 lines
12 KiB
Bash
339 lines
12 KiB
Bash
#!/bin/bash
|
|
# SPDX-Version: 3.0
|
|
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
|
|
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
|
|
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
|
|
# SPDX-FileCopyrightText: 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.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_fail2ban_hardening.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_fail2ban_hardening.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_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 's/IGNORE_IP_MUST_BE_SET//g' "${VAR_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
|