V8.00.000.2025.06.17
All checks were successful
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Successful in 56s

Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
This commit is contained in:
2025-09-05 17:15:05 +02:00
parent 2e83b6a7cc
commit 4c89e79afc
23 changed files with 942 additions and 332 deletions

View File

@@ -15,6 +15,8 @@ guard_sourcing
#######################################
# Parsing './.preseed/preseed.yaml' and './.preseed/partitioning.yaml'.
# Globals:
# ARY_ALLOW_IPV4
# ARY_ALLOW_IPV6
# ARY_BOOTPARAM
# ARY_LOCALE
# ARY_NTPSRVR
@@ -32,7 +34,7 @@ guard_sourcing
yaml_parser() {
### Declare Arrays, HashMaps, and Variables.
# shellcheck disable=SC2034
declare -ag ARY_BOOTPARAM=() ARY_LOCALE=() ARY_NTPSRVR=() ARY_PACKAGES=()
declare -ag ARY_ALLOW_IPV4=() ARY_ALLOW_IPV6=() ARY_BOOTPARAM=() ARY_LOCALE=() ARY_NTPSRVR=() ARY_PACKAGES=()
declare -gix VAR_USER_MAX=0
declare var_index="" var_key="" var_value=""
@@ -46,10 +48,12 @@ yaml_parser() {
var_value=${var_value%\'}
# shellcheck disable=SC2034
case "${var_key}" in
grub_parameter_[0-9]*) ARY_BOOTPARAM+=("${var_value}") ;;
locale_locale_[0-9]*) ARY_LOCALE+=("${var_value}") ;;
ntp_server_[0-9]*) ARY_NTPSRVR+=("${var_value}") ;;
software_[0-9]*) ARY_PACKAGES+=("${var_value}") ;;
grub_parameter_[0-9]*) ARY_BOOTPARAM+=("${var_value}") ;;
locale_locale_[0-9]*) ARY_LOCALE+=("${var_value}") ;;
ntp_server_[0-9]*) ARY_NTPSRVR+=("${var_value}") ;;
ssh_allow_ipv4_[0-9]*) ARY_ALLOW_IPV4+=("${var_value}") ;;
ssh_allow_ipv6_[0-9]*) ARY_ALLOW_IPV6+=("${var_value}") ;;
software_[0-9]*) ARY_PACKAGES+=("${var_value}") ;;
esac
done < "${VAR_PRESEED}"
@@ -68,6 +72,8 @@ yaml_parser() {
/^grub_parameter_[0-9]+=/d # delete grub parameter variables
/^locale_locale_[0-9]+=/d # delete locale variables
/^ntp_server_[0-9]+=/d # delete NTP server variables
/^ssh_allow_ipv4_[0-9]+=/d # delete ssh allow IPv4 variables
/^ssh_allow_ipv6_[0-9]+=/d # delete ssh allow IPv6 variables
/^software_[0-9]+=/d # delete software list variables
# --- Empty-value normalisation ---------------------------------------

View File

@@ -41,7 +41,8 @@ yaml_reader() {
# shellcheck disable=SC2034
declare -Ag HMP_RECIPE_DEV_PARTITIONS=()
declare -gx VAR_RECIPE_STRING="" VAR_RECIPE_HIGHEST_DEVICE="" VAR_ARCHITECTURE="" VAR_RECIPE_FIRMWARE="" VAR_NUKE="" \
VAR_RECIPE_TABLE="" VAR_NEED_RUN_IN_TARGET="false" VAR_CODENAME="" VAR_DROPBEAR="" VAR_RECOVERY=""
VAR_RECIPE_TABLE="" VAR_NEED_RUN_IN_TARGET="false" VAR_CODENAME="" VAR_DROPBEAR="" VAR_RECOVERY="" \
VAR_GRUB_PASSWORD="false" VAR_SSH_PORT="22" VAR_DEB822="true" VAR_PROVIDER="" VAR_SSH_CA="" VAR_UFW_OUT="deny"
### Declare and substitute input files.
declare -r var_if="${VAR_PRESEED}"
declare var_line="" var_middle_part="" var_highest_dev="" var_device="" var_fields="" var_partition="" \
@@ -137,19 +138,34 @@ END { print max }
done
### Extract APT file format.
# shellcheck disable=SC2034
VAR_DEB822="${apt_default_deb822,,}"
### Extract architecture.
# shellcheck disable=SC2034
VAR_ARCHITECTURE="${architecture,,}"
### Extract distribution.
# shellcheck disable=SC2034
VAR_CODENAME="${distribution,,}"
### Extract dropbear installation.
# shellcheck disable=SC2034
VAR_DROPBEAR="${dropbear_boot,,}"
### Extract grub password installation.
# shellcheck disable=SC2034
VAR_GRUB_PASSWORD="${grub_password,,}"
### Extract SSH Port.
# shellcheck disable=SC2034
VAR_SSH_PORT="${ssh_port,,}"
### Extract SSH Root CA.
# shellcheck disable=SC2034
VAR_SSH_CA="${ssh_root_ca,,}"
### Extract chroot secure '/run' mounting strategy.
# shellcheck disable=SC2034
VAR_NEED_RUN_IN_TARGET="${needrun,,}"
@@ -190,11 +206,19 @@ END { print max }
fi
### Extract provider.
# shellcheck disable=SC2034
VAR_PROVIDER="${provider,,}"
### Extract the chosen Recovery mechanism.
recipe_recovery_var="recipe_${VAR_RECIPE_STRING}_control_recovery"
# shellcheck disable=SC2034
VAR_RECOVERY="${!recipe_recovery_var,,}"
### Extract ufw outgoing policy.
# shellcheck disable=SC2034
VAR_UFW_OUT="${security_ufw_out,,}"
guard_dir && return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -116,22 +116,9 @@ EOF
chroot_script "${TARGET}" "${var_locale_hook}"
### Set the keyboard layout for the system (for consoles).
cat << EOF >| "${TARGET}/etc/default/keyboard"
# SPDX-Version: 3.0
# SPDX-CreationInfo: ${VAR_DATE}; 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
# /etc/default/keyboard : Generated by CISS.debian.installer ${VAR_VERSION}
# Architecture : ${VAR_ARCHITECTURE}
# Distribution : ${VAR_CODENAME}
insert_header "${TARGET}/etc/default/keyboard"
insert_comments "${TARGET}/etc/default/keyboard"
cat << EOF >> "${TARGET}/etc/default/keyboard"
# KEYBOARD CONFIGURATION FILE
# Consult the keyboard(5) manual page.

View File

@@ -19,8 +19,8 @@ guard_sourcing
# https://manpages.debian.org/testing/initramfs-tools-core/initramfs-tools.7.en.html
# Globals:
# TARGET
# VAR_KERNEL
# image
# VAR_ROOT_FS
# VAR_SETUP_PATH
# Arguments:
# None
# Returns:

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
#######################################
# Installation of packages 'fail2ban' and 'ufw'.
# Globals:
# TARGET
# Arguments:
# None
# Returns:
# 0: on success
#######################################
installation_netsec() {
### Declare Arrays, HashMaps, and Variables.
declare -r var_logfile="/root/.ciss/cdi/log/4305_installation_netsec.log"
chroot_logger "${TARGET}${var_logfile}"
chroot_script "${TARGET}" "
export INITRD=No
apt-get install -y --no-install-suggests fail2ban ufw 2>&1 | tee -a ${var_logfile}
echo ExitCode: \$? >> ${var_logfile}
"
guard_dir && return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -15,16 +15,15 @@ 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
# VAR_USER_MAX
# VAR_DROPBEAR
# VAR_SSH_PORT
# VAR_SSH_CA
# Arguments:
# None
# Returns:
@@ -78,15 +77,15 @@ installation_ssh() {
sed -i "/^[[:space:]]*ListenAddressIPV6[[:space:]]*/d" "${TARGET}/etc/ssh/sshd_config"
fi
sed -i -E "s|^[[:space:]]*Port[[:space:]]+.*$|$(printf '%-29s%s' 'Port' "${ssh_port}")|" "${TARGET}/etc/ssh/sshd_config"
sed -i -E "s|^[[:space:]]*Port[[:space:]]+.*$|$(printf '%-29s%s' 'Port' "${VAR_SSH_PORT}")|" "${TARGET}/etc/ssh/sshd_config"
if (( ${#ary_user[@]} > 0 )); then
sed -i -E "s|^\s*AllowUsers\s+.*$|$(printf '%-29s%s' 'AllowUsers' "root ${ary_user[*]}")|" "${TARGET}/etc/ssh/sshd_config"
fi
if [[ -n "${ssh_root_ca}" ]]; then
var_ca="${ssh_root_ca##*/}"
install -D -m 0644 -o root -g root "${VAR_SETUP_PATH}${ssh_root_ca}" "${TARGET}/etc/ssh/"
if [[ -n "${VAR_SSH_CA}" ]]; then
var_ca="${VAR_SSH_CA##*/}"
install -D -m 0644 -o root -g root "${VAR_SETUP_PATH}${VAR_SSH_CA}" "${TARGET}/etc/ssh/"
sed -i -E "s|^\s*TrustedUserCAKeys\s+.*$|$(printf '%-29s%s' 'TrustedUserCAKeys' "/etc/ssh/${var_ca}")|" "${TARGET}/etc/ssh/sshd_config"
fi
@@ -106,7 +105,7 @@ installation_ssh() {
chroot_script "${TARGET}" "ssh-keygen -r ${VAR_FINAL_FQDN}. >| /root/.ciss/cdi/log/SSHFP.log"
if [[ "${dropbear_boot}" == "true" ]]; then
if [[ "${VAR_DROPBEAR}" == "true" ]]; then
printf "### Dropbear SSHFP RR: \n" >> "${TARGET}/root/.ciss/cdi/log/SSHFP.log"
@@ -136,8 +135,6 @@ esac
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF
chmod 0644 "${TARGET}/etc/profile.d/idle-users.sh"
insert_comments "${TARGET}/etc/profile.d/idle-users.sh"
guard_dir && return 0
}

View File

@@ -0,0 +1,207 @@
#!/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
#######################################
# Hardening 'fail2ban'.
# Globals:
# ARY_ALLOW_IPV4
# ARY_ALLOW_IPV6
# TARGET
# VAR_FINAL_FQDN
# VAR_FINAL_IPV4
# VAR_FINAL_IPV6
# VAR_PROVIDER
# VAR_SSH_PORT
# Arguments:
# None
# Returns:
# 0: on success
#######################################
hardening_fail2ban() {
### Declare Arrays, HashMaps, and Variables.
declare
declare -r var_logfile="/root/.ciss/cdi/log/4420_hardening_fail2ban.log"
chroot_logger "${TARGET}${var_logfile}"
mkdir -p "${TARGET}/root/.ciss/cdi/backup/etc/fail2ban/jail.d"
cp "${TARGET}/etc/fail2ban/fail2ban.conf" "${TARGET}/root/.ciss/cdi/backup/etc/fail2ban/fail2ban.conf.bak"
mv "${TARGET}/etc/fail2ban/jail.d/defaults-debian.conf" "${TARGET}/root/.ciss/cdi/backup/etc/fail2ban/jail.d/defaults-debian.conf.bak"
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1024305
insert_header "${TARGET}/etc/fail2ban/fail2ban.local"
insert_comments "${TARGET}/etc/fail2ban/fail2ban.local"
cat << 'EOF' >> "${TARGET}/etc/fail2ban/fail2ban.local"
[DEFAULT]
allowipv6 = auto
EOF
insert_header "${TARGET}/etc/fail2ban/jail.d/centurion-default.conf"
insert_comments "${TARGET}/etc/fail2ban/jail.d/centurion-default.conf"
if [[ "${#ARY_ALLOW_IPV4[@]}" -gt 0 ]]; then
### fail2ban ufw aggressive mode, one attempt for jumphost configuration.
cat << EOF >> "${TARGET}/etc/fail2ban/jail.d/centurion-default.conf"
[DEFAULT]
usedns = yes
ignoreip = 127.0.0.0/8 ::1
# ${VAR_FINAL_FQDN}
${VAR_FINAL_IPV4}
${VAR_FINAL_IPV6}/64
# Jumphost
${ARY_ALLOW_IPV4[*]}
${ARY_ALLOW_IPV6[*]}
maxretry = 8
findtime = 12h
bantime = 12h
[sshd]
enabled = true
backend = systemd
filter = sshd
mode = normal
port = ${VAR_SSH_PORT}
protocol = tcp
logpath = /var/log/auth.log
maxretry = 3
findtime = 1d
bantime = 1d
#
# ufw aggressive approach:
# Any valid client communicating with our server should be going directly to the service ports opened in ufw (ssh, 80, ...).
# Any client touching other ports is treated malicious and therefore should be blocked access to ALL ports after 1 attempt.
#
[ufw]
enabled = true
filter = ufw.aggressive
action = iptables-allports
logpath = /var/log/ufw.log
maxretry = 1
findtime = 1d
bantime = 1d
protocol = tcp,udp
EOF
else
### fail2ban ufw aggressive mode, 32 attempts for NO jumphost configuration.
cat << EOF >> "${TARGET}/etc/fail2ban/jail.d/centurion-default.conf"
[DEFAULT]
usedns = yes
ignoreip = 127.0.0.0/8 ::1
# ${VAR_FINAL_FQDN}
${VAR_FINAL_IPV4}
${VAR_FINAL_IPV6}/64
maxretry = 8
findtime = 12h
bantime = 12h
[sshd]
enabled = true
backend = systemd
filter = sshd
mode = normal
port = ${VAR_SSH_PORT}
protocol = tcp
logpath = /var/log/auth.log
maxretry = 3
findtime = 1d
bantime = 1d
#
# ufw aggressive approach:
# Any valid client communicating with our server should be going directly to the service ports opened in ufw (ssh, 80, ...).
# Any client touching other ports is treated malicious and therefore should be blocked access to ALL ports after 32 attempts.
#
[ufw]
enabled = true
filter = ufw.aggressive
action = iptables-allports
logpath = /var/log/ufw.log
maxretry = 32
findtime = 1d
bantime = 1d
protocol = tcp,udp
EOF
fi
### Provider Hetzner needs special ignoreip rules.
if [[ "${VAR_PROVIDER}" == "hetzner" ]]; then
sed -i '0,/^maxretry/{s/^maxretry/# Hetzner Intern\n 172.31.1.1\/16\n&/}' "${TARGET}/etc/fail2ban/jail.d/centurion-default.conf"
fi
insert_header "${TARGET}/etc/fail2ban/filter.d/ufw.aggressive.conf"
insert_comments "${TARGET}/etc/fail2ban/filter.d/ufw.aggressive.conf"
cat << EOF >> "${TARGET}/etc/fail2ban/filter.d/ufw.aggressive.conf"
[Definition]
failregex = ^.*UFW BLOCK.* SRC=<HOST> .*DPT=\d+ .*
ignoreregex =
EOF
# Hardening of fail2ban systemd: https://wiki.archlinux.org/title/fail2ban#Service_hardening
# The 'CapabilityBoundingSet' parameters 'CAP_DAC_READ_SEARCH' will allow fail2ban full read access to every directory and
# file. "CAP_NET_ADMIN" and "CAP_NET_RAW" allow fail2ban to operate on any firewall that has a command-line shell interface.
# By using 'ProtectSystem=strict' the filesystem hierarchy will only be read-only; 'ReadWritePaths' allows Fail2ban to have
# write access on required paths.
mkdir -p "${TARGET}/etc/systemd/system/fail2ban.service.d"
mkdir -p "${TARGET}/var/log/fail2ban"
insert_header "${TARGET}/etc/systemd/system/fail2ban.service.d/override.conf"
insert_comments "${TARGET}/etc/systemd/system/fail2ban.service.d/override.conf"
cat << EOF >> "${TARGET}/etc/systemd/system/fail2ban.service.d/override.conf"
[Service]
PrivateDevices=yes
PrivateTmp=yes
ProtectHome=read-only
ProtectSystem=strict
ReadWritePaths=-/var/run/fail2ban
ReadWritePaths=-/var/lib/fail2ban
ReadWritePaths=-/var/log/fail2ban
ReadWritePaths=-/var/spool/postfix/maildrop
ReadWritePaths=-/run/xtables.lock
CapabilityBoundingSet=CAP_AUDIT_READ CAP_DAC_READ_SEARCH CAP_NET_ADMIN CAP_NET_RAW
ProtectClock=true
ProtectHostname=true
EOF
cat << 'EOF' >> "${TARGET}/etc/fail2ban/fail2ban.local"
[Definition]
logtarget = /var/log/fail2ban/fail2ban.log
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf
EOF
### Logrotate must be updated too.
mkdir -p "${TARGET}/root/.ciss/cdi/backup/etc/logrotate.d"
cp "${TARGET}/etc/logrotate.d/fail2ban" "${TARGET}/root/.ciss/cdi/backup/etc/logrotate.d/fail2ban.bak"
sed -i 's/\/var\/log\/fail2ban.log/\/var\/log\/fail2ban\/fail2ban.log/1' "${TARGET}/etc/logrotate.d/fail2ban"
touch "${TARGET}/var/log/fail2ban/fail2ban.log"
chmod 640 "${TARGET}/var/log/fail2ban/fail2ban.log"
### Merge / Dump-Parse via 'fail2ban-client -d'. All '*.conf', '*.local', and 'jail.*'-files are read, inherited, and merged.
### Syntax, path, and key errors result in a non-zero exit.
chroot_script "${TARGET}" "
fail2ban-client -d >> ${var_logfile} && echo "OK: config parsed" >> ${var_logfile} || echo "ERROR: config invalid" >> ${var_logfile}
"
guard_dir && return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -1,204 +0,0 @@
#!/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
#######################################
# Hardening files and directories.
# Globals:
# None
# Arguments:
# None
# Returns:
# 0: on success
#######################################
hardening_fail2ban() {
### Declare Arrays, HashMaps, and Variables.
declare
declare -r var_logfile="/root/.ciss/cdi/log/4435_hardening_fail2ban.log"
chroot_logger "${TARGET}${var_logfile}"
chroot_script "${TARGET}" "
export INITRD=No
apt-get install -y --no-install-suggests fail2ban 2>&1 | tee -a ${var_logfile}
echo ExitCode: \$? >> ${var_logfile}
"
cp -u /etc/fail2ban/fail2ban.conf "${DIR_BAK}"fail2ban.conf.bak
mv "${TARGET}/etc/resolv.conf" "${TARGET}/root/.ciss/cdi/backup/etc/resolv.conf.bak"
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1024305
sed -i 's/#allowipv6 = auto/allowipv6 = auto/1' /etc/fail2ban/fail2ban.conf
mv /etc/fail2ban/jail.d/defaults-debian.conf /etc/fail2ban/jail.d/defaults-debian.conf.bak
chmod 644 /etc/fail2ban/jail.d/defaults-debian.conf.bak
if [[ "${JUMPHOST,,}" = "yes" ]]; then
###########################################################################################
# Remarks: fail2ban ufw aggresive mode - one attempt for Jumphost configuration #
###########################################################################################
cat <<EOF >/etc/fail2ban/jail.d/centurion-default.conf
##### Added by hardening.sh - Module: do_hardening_fail2ban #####
[DEFAULT]
usedns = yes
ignoreip = 127.0.0.0/8 ::1
# $FQDN
$IPV4 $IPV6/64
# Jumphost
$JUMPHOST_IPV4 $JUMPHOST_IPV6/64
maxretry = 8
findtime = 12h
bantime = 12h
[sshd]
enabled = true
backend = systemd
filter = sshd
mode = normal
port = $SSHPORT
protocol = tcp
logpath = /var/log/auth.log
maxretry = 3
findtime = 1d
bantime = 1d
#
# ufw aggressive approach:
# Any valid client communicating with our server should be going directly to the service ports opened in ufw (ssh, 80, 443, ...).
# Any client touching other ports is treated malicious and therefore should be blocked access to ALL ports after 1 attempt.
#
[ufw]
enabled = true
filter = ufw.aggressive
action = iptables-allports
logpath = /var/log/ufw.log
maxretry = 1
findtime = 1d
bantime = 1d
protocol = tcp,udp
EOF
else
###########################################################################################
# Remarks: fail2ban ufw aggresive mode 32 attempts for NO Jumphost configuration #
###########################################################################################
cat <<EOF >/etc/fail2ban/jail.d/centurion-default.conf
##### Added by hardening.sh - Module: do_hardening_fail2ban #####
[DEFAULT]
usedns = yes
ignoreip = 127.0.0.0/8 ::1
# $FQDN
$IPV4 $IPV6/64
maxretry = 8
findtime = 12h
bantime = 12h
[sshd]
enabled = true
backend = systemd
filter = sshd
mode = normal
port = $SSHPORT
protocol = tcp
logpath = /var/log/auth.log
maxretry = 3
findtime = 1d
bantime = 1d
#
# ufw aggressive approach:
# Any valid client communicating with our server should be going directly to the service ports opened in ufw (ssh, 80, 443, ...).
# Any client touching other ports is treated malicious and therefore should be blocked access to ALL ports after 32 attempts.
#
[ufw]
enabled = true
filter = ufw.aggressive
action = iptables-allports
logpath = /var/log/ufw.log
maxretry = 32
findtime = 1d
bantime = 1d
protocol = tcp,udp
EOF
fi
cat <<EOF >/etc/fail2ban/filter.d/ufw.aggressive.conf
##### Added by hardening.sh - Module: do_hardening_fail2ban #####
[Definition]
failregex = ^.*UFW BLOCK.* SRC=<HOST> .*DPT=\d+ .*
ignoreregex =
EOF
###########################################################################################
# Remarks: hardening of fail2ban systemd #
###########################################################################################
# https://wiki.archlinux.org/title/fail2ban#Service_hardening #
# The CapabilityBoundingSet parameters CAP_DAC_READ_SEARCH will allow Fail2ban full read #
# access to every directory and file. CAP_NET_ADMIN and CAP_NET_RAW allow Fail2ban to #
# operate # on any firewall that has command-line shell interface. By using #
# ProtectSystem=strict the filesystem hierarchy will only be read-only, ReadWritePaths #
# allows Fail2ban to have write access on required paths. #
###########################################################################################
mkdir -p /etc/systemd/system/fail2ban.service.d
mkdir /var/log/fail2ban
cat <<EOF >/etc/systemd/system/fail2ban.service.d/override.conf
[Service]
PrivateDevices=yes
PrivateTmp=yes
ProtectHome=read-only
ProtectSystem=strict
ReadWritePaths=-/var/run/fail2ban
ReadWritePaths=-/var/lib/fail2ban
ReadWritePaths=-/var/log/fail2ban
ReadWritePaths=-/var/spool/postfix/maildrop
ReadWritePaths=-/run/xtables.lock
CapabilityBoundingSet=CAP_AUDIT_READ CAP_DAC_READ_SEARCH CAP_NET_ADMIN CAP_NET_RAW
##### Added by CenDev
ProtectClock=true
ProtectHostname=true
EOF
cat <<EOF >>/etc/fail2ban/fail2ban.local
[Definition]
logtarget = /var/log/fail2ban/fail2ban.log
EOF
###########################################################################################
# Remarks: Hetzner needs special ignoreip rules #
###########################################################################################
if [[ "${VPSPROVIDER,,}" = "hetzner" ]]; then
sed -i '0,/^maxretry/{s/^maxretry/# Hetzner Intern\n 172.31.1.1\/16\n&/}' /etc/fail2ban/jail.d/centurion-default.conf
fi
###########################################################################################
# Remarks: Logrotate must be updated either #
###########################################################################################
cp -a /etc/logrotate.d/fail2ban "${DIR_BAK}"fail2ban_logrotate.bak
sed -i 's/\/var\/log\/fail2ban.log/\/var\/log\/fail2ban\/fail2ban.log/1' /etc/logrotate.d/fail2ban
touch /var/log/fail2ban/fail2ban.log
chmod 640 /var/log/fail2ban/fail2ban.log
guard_dir && return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -16,32 +16,15 @@ guard_sourcing
# Hardening haveged.
# Globals:
# TARGET
# VAR_ARCHITECTURE
# VAR_CODENAME
# VAR_VERSION
# Arguments:
# None
# Returns:
# 0: on success
#######################################
hardening_haveged() {
cat << EOF >| "${TARGET}/etc/default/haveged"
# SPDX-Version: 3.0
# SPDX-CreationInfo: ${VAR_DATE}; 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
# Static file system information: /etc/default/haveged
# Generated by CISS.debian.installer ${VAR_VERSION}
# Architecture: ${VAR_ARCHITECTURE}
# Distribution: ${VAR_CODENAME}
insert_header "${TARGET}/etc/default/haveged"
insert_comments "${TARGET}/etc/default/haveged"
cat << EOF >> "${TARGET}/etc/default/haveged"
# Configuration file for haveged
# Minimal, sane defaults for server/headless systems.
# -w <bits> : target entropy level in bits; 1024 ensures fast pool fill on boot

View File

@@ -56,11 +56,9 @@ hardening_memory() {
mkdir -p "${TARGET}/etc/systemd/coredump.conf.d"
mkdir -p "${TARGET}/etc/systemd/system.conf.d"
insert_header "${TARGET}/etc/security/limits.d/99-ciss-core.conf"
insert_header "${TARGET}/etc/security/limits.d/99-ciss-core.conf"
insert_comments "${TARGET}/etc/security/limits.d/99-ciss-core.conf"
cat << EOF >> "${TARGET}/etc/security/limits.d/99-ciss-core.conf"
cat << 'EOF' >> "${TARGET}/etc/security/limits.d/99-ciss-core.conf"
# Enforce: no core dumps for all logins by default.
# Format: <domain> <type> <item> <value>
* hard core 0
@@ -72,7 +70,7 @@ root soft core 0
EOF
insert_header "${TARGET}/etc/systemd/coredump.conf.d/disable.conf"
insert_header "${TARGET}/etc/systemd/coredump.conf.d/disable.conf"
insert_comments "${TARGET}/etc/systemd/coredump.conf.d/disable.conf"
cat << 'EOF' >> "${TARGET}/etc/systemd/coredump.conf.d/disable.conf"
### Do not store core images anywhere, keep the at most minimal metadata.
@@ -91,9 +89,9 @@ EOF
mv "${TARGET}/etc/systemd/system.conf.d/10-coredump-debian.conf" "${TARGET}/etc/systemd/system.conf.d/10-coredump-debian.conf.bak"
insert_header "${TARGET}/etc/systemd/system.conf.d/99-ciss-core.conf"
insert_header "${TARGET}/etc/systemd/system.conf.d/99-ciss-core.conf"
insert_comments "${TARGET}/etc/systemd/system.conf.d/99-ciss-core.conf"
cat << EOF >> "${TARGET}/etc/systemd/system.conf.d/99-ciss-core.conf"
cat << 'EOF' >> "${TARGET}/etc/systemd/system.conf.d/99-ciss-core.conf"
[Manager]
DefaultLimitCORE=0

View File

@@ -0,0 +1,35 @@
#!/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
#######################################
# Hardening OpenSSL library defaults (system-wide), TLSv1.2-, TLSv1.3-, AES-256-only.
# Globals:
# TARGET
# VAR_SETUP_PATH
# Arguments:
# None
# Returns:
# 0: on success
#######################################
hardening_openssl() {
mkdir -p "${TARGET}/root/.ciss/cdi/backup/etc/ssl"
mv "${TARGET}/etc/ssl/openssl.cnf" "${TARGET}/root/.ciss/cdi/backup/etc/ssl/openssl.cnf.bak"
insert_header "${TARGET}/etc/ssl/openssl.cnf"
insert_comments "${TARGET}/etc/ssl/openssl.cnf"
cat "${VAR_SETUP_PATH}/includes/target/etc/ssl/openssl.cnf" >> "${TARGET}/etc/ssl/openssl.cnf"
guard_dir && return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,85 @@
#!/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
#######################################
# OpenSSL library defaults (system-wide), TLSv1.2-, TLSv1.3-, AES-256-only;
# Globals:
# TARGET
# VAR_SETUP_PATH
# Arguments:
# None
# Returns:
# 0: on success
#######################################
hardening_ufw() {
### Declare Arrays, HashMaps, and Variables.
declare -r var_logfile="/root/.ciss/cdi/log/4470_hardening_ufw.log"
chroot_logger "${TARGET}${var_logfile}"
if [[ ! -f "${TARGET}/var/log/ufw.log" ]]; then
touch "${TARGET}/var/log/ufw.log"
chmod 640 "${TARGET}/var/log/ufw.log"
fi
chroot_script "${TARGET}" "
ufw --force reset
ufw logging medium
ufw default deny incoming
ufw default ${VAR_UFW_OUT} outgoing
ufw default deny forward
ufw allow in ${VAR_SSH_PORT}/tcp comment 'Incoming SSH'
ufw limit ${VAR_SSH_PORT}/tcp comment 'Incoming SSH'
"
### Ensure that a standard set of the most commonly used ports are open if a default-'deny'-outbound policy is selected.
if [[ "${VAR_UFW_OUT}" = "deny" ]]; then
chroot_script "${TARGET}" "
ufw allow out 21/tcp comment 'Outgoing FTP'
ufw allow out 22/tcp comment 'Outgoing SSH'
ufw allow out 25/tcp comment 'Outgoing SMTP'
ufw allow out 53/tcp comment 'Outgoing DNS'
ufw allow out 80/tcp comment 'Outgoing HTTP'
ufw allow out 123/tcp comment 'Outgoing NTP'
ufw allow out 143/tcp comment 'Outgoing IMAP'
ufw allow out 443/tcp comment 'Outgoing HTTPS'
ufw allow out 465/tcp comment 'Outgoing SMTPS'
ufw allow out 587/tcp comment 'Outgoing SMTPS'
ufw allow out 993/tcp comment 'Outgoing IMAPS'
ufw allow out 4460/tcp comment 'Outgoing NTS'
ufw allow out ${VAR_SSH_PORT}/tcp comment 'Outgoing SSH'
ufw allow out 53/udp comment 'Outgoing DNS'
ufw allow out 123/udp comment 'Outgoing NTP'
ufw allow out 443/udp comment 'Outgoing QUIC'
ufw allow out 853/udp comment 'Outgoing DoQ'
"
fi
### Allowing ICMP IPv4 outgoing per default.
sed -i "/# ok icmp code for FORWARD/i \# ok icmp codes for OUTPUT" "${TARGET}/etc/ufw/before.rules"
sed -i "/# ok icmp code for FORWARD/i \-A ufw-before-output -p icmp --icmp-type destination-unreachable -j ACCEPT" "${TARGET}/etc/ufw/before.rules"
sed -i "/# ok icmp code for FORWARD/i \-A ufw-before-output -p icmp --icmp-type time-exceeded -j ACCEPT" "${TARGET}/etc/ufw/before.rules"
sed -i "/# ok icmp code for FORWARD/i \-A ufw-before-output -p icmp --icmp-type parameter-problem -j ACCEPT" "${TARGET}/etc/ufw/before.rules"
sed -i "/# ok icmp code for FORWARD/i \-A ufw-before-output -p icmp --icmp-type echo-request -j ACCEPT" "${TARGET}/etc/ufw/before.rules"
chroot_script "${TARGET}" "echo 'y' | ufw enable 2>&1"
chroot_script "${TARGET}" "
ufw status verbose >> ${var_logfile}
"
guard_dir && return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -22,7 +22,7 @@ guard_sourcing
# Returns:
# 0: on success
#######################################
installation_skel() {
accounts_preparation() {
mkdir -p "${TARGET}/etc/skel/.ciss"
install -m 0644 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.bashrc" "${TARGET}/etc/skel/.bashrc"

View File

@@ -13,17 +13,15 @@
guard_sourcing
#######################################
#
# Globals:
# TARGET
# VAR_ARCHITECTURE
# VAR_CODENAME
# VAR_VERSION
# Arguments:
# None
# Returns:
# 0: on success
#######################################
hardening_ssl() {
accounts_hardening() {
guard_dir && return 0
}

View File

@@ -27,7 +27,7 @@ guard_sourcing
# Returns:
# 0: on success
#######################################
installation_accounts() {
accounts_setup() {
### Declare Arrays, HashMaps, and Variables.
declare -i i
declare tmp_username="" tmp_fullname="" tmp_uid="" tmp_gid="" tmp_shell="" tmp_password="" tmp_sshpubkey="" tmp_sudo="" \