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

Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
This commit is contained in:
2025-10-13 18:58:51 +01:00
parent e5262782e9
commit a8142abc9c
23 changed files with 406 additions and 178 deletions

View File

@@ -39,14 +39,12 @@ check_usr_merge() {
test -L /bin && test $(readlink -f /bin) = '/usr/bin' && echo 'MERGED:/bin' >> ${var_logfile} || echo 'UNMERGED:/bin' >> ${var_logfile} test -L /bin && test $(readlink -f /bin) = '/usr/bin' && echo 'MERGED:/bin' >> ${var_logfile} || echo 'UNMERGED:/bin' >> ${var_logfile}
test -L /sbin && test $(readlink -f /sbin) = '/usr/sbin' && echo 'MERGED:/sbin' >> ${var_logfile} || echo 'UNMERGED:/sbin' >> ${var_logfile} test -L /sbin && test $(readlink -f /sbin) = '/usr/sbin' && echo 'MERGED:/sbin' >> ${var_logfile} || echo 'UNMERGED:/sbin' >> ${var_logfile}
test -L /lib && test $(readlink -f /lib) = '/usr/lib' && echo 'MERGED:/lib' >> ${var_logfile} || echo 'UNMERGED:/lib' >> ${var_logfile} test -L /lib && test $(readlink -f /lib) = '/usr/lib' && echo 'MERGED:/lib' >> ${var_logfile} || echo 'UNMERGED:/lib' >> ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile}
" "
${PIPESTATUS[0]}
if [[ "${architecture}" == "amd64" ]]; then if [[ "${architecture}" == "amd64" ]]; then
# shellcheck disable=SC2312 # shellcheck disable=SC2312
chroot_script "${var_target}" " chroot_script "${var_target}" "
test -L /lib64 && test $(readlink -f /lib64) = '/usr/lib64' && echo 'MERGED:/lib64' >> ${var_logfile} || echo 'UNMERGED:/lib64' >> ${var_logfile} test -L /lib64 && test $(readlink -f /lib64) = '/usr/lib64' && echo 'MERGED:/lib64' >> ${var_logfile} || echo 'UNMERGED:/lib64' >> ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile}
" "
fi fi

View File

@@ -39,7 +39,11 @@ update_sources() {
### Update generated sources. ### Update generated sources.
# shellcheck disable=SC2312 # shellcheck disable=SC2312
chroot_script "${var_target}" "apt-get update 2>&1 | tee -a ${var_logfile}; echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile}" chroot_script "${var_target}" "
apt-get update 2>&1 | tee -a ${var_logfile}
RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
"
do_log "info" "file_only" "4110() Sources lists: updated successfully." do_log "info" "file_only" "4110() Sources lists: updated successfully."
@@ -49,7 +53,8 @@ update_sources() {
chroot_script "${var_target}" " chroot_script "${var_target}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests unattended-upgrades 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests unattended-upgrades 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
do_log "info" "file_only" "4110() The update policy was set at installation time to: '${apt_updates_policy}'." do_log "info" "file_only" "4110() The update policy was set at installation time to: '${apt_updates_policy}'."
@@ -58,7 +63,8 @@ update_sources() {
chroot_script "${var_target}" " chroot_script "${var_target}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests unattended-upgrades 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests unattended-upgrades 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
# shellcheck disable=SC2016 # shellcheck disable=SC2016

View File

@@ -34,11 +34,12 @@ installation_kernel() {
if [[ -n "${VAR_KERNEL}" ]]; then if [[ -n "${VAR_KERNEL}" ]]; then
chroot_script "${TARGET}" ' chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests '"${VAR_KERNEL}"' initramfs-tools 2>&1 | tee -a '"${var_logfile}"' apt-get install -y --no-install-recommends --no-install-suggests ${VAR_KERNEL} initramfs-tools 2>&1 | tee -a ${var_logfile}
echo ExitCode: $? >> '"${var_logfile}"' RC=( \${PIPESTATUS[@]} )
' echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
"
do_log "info" "file_only" "4120() Kernel image: '${VAR_KERNEL}' installed successfully." do_log "info" "file_only" "4120() Kernel image: '${VAR_KERNEL}' installed successfully."
@@ -49,7 +50,8 @@ installation_kernel() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests ${image} initramfs-tools 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests ${image} initramfs-tools 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
do_log "info" "file_only" "4120() Kernel image: '${image}' installed successfully." do_log "info" "file_only" "4120() Kernel image: '${image}' installed successfully."

View File

@@ -97,11 +97,15 @@ installation_toolset() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests ${ary_unique_pkgs[*]} 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests ${ary_unique_pkgs[*]} 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
fi fi
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f installation_toolset
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -36,7 +36,8 @@ installation_systemd() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests systemd systemd-sysv dbus 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests systemd systemd-sysv dbus 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
else else
@@ -51,4 +52,7 @@ installation_systemd() {
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f installation_systemd
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -57,7 +57,8 @@ installation_microcode() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests ${var_microcode_pkgs} 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests ${var_microcode_pkgs} 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
else else
@@ -65,7 +66,8 @@ installation_microcode() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests --only-upgrade ${var_microcode_pkgs} 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests --only-upgrade ${var_microcode_pkgs} 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
fi fi
@@ -78,4 +80,7 @@ installation_microcode() {
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f installation_microcode
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -295,11 +295,15 @@ installation_firmware() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests ${ary_pkgs_resolved[*]} 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests ${ary_pkgs_resolved[*]} 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f installation_firmware
####################################### #######################################
# Helper: Wildcardize a module alias (bus-aware, conservative) # Helper: Wildcardize a module alias (bus-aware, conservative)
@@ -352,4 +356,7 @@ wildcard_mod_alias() {
return 0 return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f wildcard_mod_alias
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -50,7 +50,8 @@ installation_chrony() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests chrony 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests chrony 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
if [[ ! -e "${TARGET}/etc/systemd/system/multi-user.target.wants/chrony.service" ]]; then if [[ ! -e "${TARGET}/etc/systemd/system/multi-user.target.wants/chrony.service" ]]; then
@@ -71,7 +72,8 @@ installation_chrony() {
do_log "debug" "file_only" "4150() Executing: [chroot_script ${TARGET} chronyd -Q -f /etc/chrony/chrony.conf]." do_log "debug" "file_only" "4150() Executing: [chroot_script ${TARGET} chronyd -Q -f /etc/chrony/chrony.conf]."
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
chronyd -Q -f /etc/chrony/chrony.conf 2>&1 | tee -a ${var_logfile} chronyd -Q -f /etc/chrony/chrony.conf 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
do_log "info" "file_only" "4150() Chrony NTPsec client installed." do_log "info" "file_only" "4150() Chrony NTPsec client installed."

View File

@@ -51,9 +51,13 @@ EOF
export INITRD=No export INITRD=No
apt-get update apt-get update
apt-get install -y --no-install-recommends --no-install-suggests eza 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests eza 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f installation_eza
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -51,9 +51,13 @@ EOF
export INITRD=No export INITRD=No
apt-get update apt-get update
apt-get install -y --no-install-recommends --no-install-suggests lynis 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests lynis 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f installation_lynis
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -38,16 +38,17 @@ guard_sourcing
# VAR_SETUP_PATH # VAR_SETUP_PATH
# grub_background_enable # grub_background_enable
# grub_background_path # grub_background_path
# grub_latest # grub_bootdev
# grub_force_efi
# grub_prober # grub_prober
# grub_skip # grub_skip
# grub_update_nvram
# var_update_grub_required # var_update_grub_required
# Arguments: # Arguments:
# None # None
# Returns: # Returns:
# 0: on success # 0: on success
# ERR_GRUB_BACKGROUND # ERR_GRUB_ARCHITECTURE: on failure
# ERR_GRUB_EFI_FORCE
####################################### #######################################
installation_grub() { installation_grub() {
### Declare Arrays, HashMaps, and Variables. ### Declare Arrays, HashMaps, and Variables.
@@ -78,7 +79,8 @@ installation_grub() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends grub2-common grub-efi-amd64 grub-efi-amd64-bin 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends grub2-common grub-efi-amd64 grub-efi-amd64-bin 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
;; ;;
@@ -86,7 +88,8 @@ installation_grub() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends grub2-common grub-efi-arm64 grub-efi-arm64-bin 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends grub2-common grub-efi-arm64 grub-efi-arm64-bin 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
;; ;;
@@ -101,7 +104,8 @@ installation_grub() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends grub2-common grub-pc grub-pc-bin 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends grub2-common grub-pc grub-pc-bin 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
fi fi
@@ -210,6 +214,9 @@ EOF
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f installation_grub
####################################### #######################################
# Installs GRUB to BIOS in BIOS mode. # Installs GRUB to BIOS in BIOS mode.
@@ -222,7 +229,7 @@ EOF
# None # None
# Returns: # Returns:
# 0: on success # 0: on success
# ERR_GRUB_INSTALL # ERR_GRUB_INSTALL: on failure
####################################### #######################################
install_grub_bios() { install_grub_bios() {
### Declare Arrays, HashMaps, and Variables. ### Declare Arrays, HashMaps, and Variables.
@@ -253,6 +260,9 @@ install_grub_bios() {
return 0 return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f install_grub_bios
####################################### #######################################
# Installs GRUB to ESP in UEFI mode. # Installs GRUB to ESP in UEFI mode.
@@ -260,14 +270,13 @@ install_grub_bios() {
# TARGET # TARGET
# VAR_MODINFO_PATH # VAR_MODINFO_PATH
# grub_bootdev # grub_bootdev
# grub_force_efi
# grub_update_nvram # grub_update_nvram
# var_update_grub_required # var_update_grub_required
# Arguments: # Arguments:
# None # None
# Returns: # Returns:
# 0: on success # 0: on success
# ERR_GRUB_INSTALL # ERR_GRUB_INSTALL: on failure
####################################### #######################################
install_grub_uefi() { install_grub_uefi() {
### Declare Arrays, HashMaps, and Variables. ### Declare Arrays, HashMaps, and Variables.
@@ -300,6 +309,9 @@ install_grub_uefi() {
return 0 return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f install_grub_uefi
####################################### #######################################
# Get the path of the required Grub modules. # Get the path of the required Grub modules.
@@ -316,6 +328,7 @@ get_grub_modinfo_path() {
### Declare Arrays, HashMaps, and Variables. ### Declare Arrays, HashMaps, and Variables.
declare -gx VAR_MODINFO_PATH="" declare -gx VAR_MODINFO_PATH=""
# shellcheck disable=SC2249
case "${VAR_RECIPE_FIRMWARE}" in case "${VAR_RECIPE_FIRMWARE}" in
uefi) uefi)
@@ -339,4 +352,7 @@ get_grub_modinfo_path() {
return 0 return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f get_grub_modinfo_path
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -46,19 +46,22 @@ installation_network() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get purge -y dhcpcd isc-dhcp-client 2>&1 | tee -a ${var_logfile} apt-get purge -y dhcpcd isc-dhcp-client 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-suggests dhcpcd-base ifupdown 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-suggests dhcpcd-base ifupdown 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
systemctl disable systemd-networkd NetworkManager 2>/dev/null | tee -a ${var_logfile} || true systemctl disable systemd-networkd NetworkManager 2>/dev/null | tee -a ${var_logfile} || true
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
mkdir -p "${TARGET}/etc/network/interfaces.d" mkdir -p "${TARGET}/etc/network/interfaces.d"
@@ -230,7 +233,8 @@ EOF
### Check dhcpcd connectivity. ### Check dhcpcd connectivity.
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
dhcpcd -T ${VAR_FINAL_NIC} | tee -a ${var_logfile} dhcpcd -T ${VAR_FINAL_NIC} | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
guard_dir && return 0 guard_dir && return 0

View File

@@ -30,9 +30,13 @@ installation_netsec() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-suggests fail2ban ufw 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-suggests fail2ban ufw 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f installation_netsec
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -32,18 +32,21 @@ update_initramfs() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
update-grub 2>&1 | tee -a ${var_logfile} update-grub 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
depmod -a ${var_kernel} 2>&1 | tee -a ${var_logfile} depmod -a ${var_kernel} 2>&1 | tee -a ${var_logfile}
update-initramfs -c -v -k all 2>&1 | tee -a ${var_logfile} update-initramfs -c -v -k all 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
update-grub 2>&1 | tee -a ${var_logfile} update-grub 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
chmod 0400 "${TARGET}/boot/grub/grub.cfg" chmod 0400 "${TARGET}/boot/grub/grub.cfg"

View File

@@ -31,20 +31,25 @@ hardening_usb() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests usbguard 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests usbguard 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
touch /tmp/rules.conf touch /tmp/rules.conf
usbguard generate-policy >| /tmp/rules.conf usbguard generate-policy >| /tmp/rules.conf
if [[ -f /etc/usbguard/rules.conf && -s /etc/usbguard/rules.conf ]]; then if [[ -f /etc/usbguard/rules.conf && -s /etc/usbguard/rules.conf ]]; then
mkdir -p /root/.ciss/cdi/backup/etc/usbguard mkdir -p /root/.ciss/cdi/backup/etc/usbguard
mv /etc/usbguard/rules.conf /root/.ciss/cdi/backup/etc/usbguard/usbguard_rules.conf mv /etc/usbguard/rules.conf /root/.ciss/cdi/backup/etc/usbguard/usbguard_rules.conf
mv /tmp/rules.conf /etc/usbguard/rules.conf mv /tmp/rules.conf /etc/usbguard/rules.conf
chmod 0600 /etc/usbguard/rules.conf chmod 0600 /etc/usbguard/rules.conf
else else
rm -f /etc/usbguard/rules.conf rm -f /etc/usbguard/rules.conf
mv /tmp/rules.conf /etc/usbguard/rules.conf mv /tmp/rules.conf /etc/usbguard/rules.conf
chmod 0600 /etc/usbguard/rules.conf chmod 0600 /etc/usbguard/rules.conf
fi fi
#cp -a /etc/usbguard/usbguard-daemon.conf /root/.ciss/cdi/backup/etc/usbguard/usbguard-daemon.conf #cp -a /etc/usbguard/usbguard-daemon.conf /root/.ciss/cdi/backup/etc/usbguard/usbguard-daemon.conf
@@ -53,4 +58,7 @@ hardening_usb() {
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f hardening_usb
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -30,9 +30,13 @@ hardening_virus() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests rkhunter 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests rkhunter 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f hardening_virus
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -31,7 +31,8 @@ accounts_preparation() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests bash-completion fzf 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests bash-completion fzf 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
mkdir -p "${TARGET}/etc/skel/.ciss" mkdir -p "${TARGET}/etc/skel/.ciss"
@@ -60,4 +61,7 @@ accounts_preparation() {
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f accounts_preparation
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -34,7 +34,8 @@ accounts_hardening() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests ${ary_security_pkgs[*]} 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests ${ary_security_pkgs[*]} 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
### Preparing 2fa hardening. ### Preparing 2fa hardening.
@@ -100,4 +101,7 @@ accounts_hardening() {
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f accounts_hardening
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -50,8 +50,12 @@ accounts_setup() {
var_access_tty="" var_auth_pwd="" var_2fa_ssh="" var_2fa_tty="" var_sudo="" var_restricted="" var_system="" \ var_access_tty="" var_auth_pwd="" var_2fa_ssh="" var_2fa_tty="" var_sudo="" var_restricted="" var_system="" \
var_specific="" var_specific=""
declare var_ssh_totp_update="false" declare var_ssh_totp_update="false"
declare var_target="${TARGET}"
chroot_logger "${TARGET}${var_logfile}" ### Check for TARGET / RECOVERY.
[[ "${VAR_RUN_RECOVERY}" == "true" ]] && var_target="${RECOVERY}"
chroot_logger "${var_target}${var_logfile}"
### Prepare the '2fa'-seed variable. ### Prepare the '2fa'-seed variable.
read_totp_seed read_totp_seed
@@ -60,21 +64,21 @@ accounts_setup() {
### 0) The 'root' account is generated via debootstrap by default. ### 0) The 'root' account is generated via debootstrap by default.
### 1) Prepare the 'root' account. ### 1) Prepare the 'root' account.
install -d -m 0700 -o root -g root "${TARGET}/root/.ssh" install -d -m 0700 -o root -g root "${var_target}/root/.ssh"
install -m 0600 -o root -g root /dev/null "${TARGET}/root/.ssh/authorized_keys" install -m 0600 -o root -g root /dev/null "${var_target}/root/.ssh/authorized_keys"
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.bashrc" "${TARGET}/root/" install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.bashrc" "${var_target}/root/"
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.ciss/theme_eza_ciss.yml" "${TARGET}/root/.ciss/" install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.ciss/theme_eza_ciss.yml" "${var_target}/root/.ciss/"
if [[ "${user_root_shell}" == "/bin/zsh" ]]; then if [[ "${user_root_shell}" == "/bin/zsh" ]]; then
if [[ -x "${TARGET}${user_root_shell}" ]]; then if [[ -x "${var_target}${user_root_shell}" ]]; then
case "${user_root_specific,,}" in case "${user_root_specific,,}" in
"ciss") "ciss")
zsh_omz_installer "root" zsh_omz_installer "root" "${var_target}"
mv "${TARGET}/root/.zshrc" "${TARGET}/root/.zshrc.bak" mv "${var_target}/root/.zshrc" "${var_target}/root/.zshrc.bak"
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.zshrc" "${TARGET}/root/" install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/etc/skel/.zshrc" "${var_target}/root/"
;; ;;
"physnet") "physnet")
@@ -87,24 +91,24 @@ accounts_setup() {
esac esac
chroot_exec "${TARGET}" chsh -s "${user_root_shell}" root chroot_exec "${var_target}" chsh -s "${user_root_shell}" root
do_log "info" "file_only" "4520() Shell: '${user_root_shell}' used for: 'root'." do_log "info" "file_only" "4520() Shell: '${user_root_shell}' used for: 'root'."
else else
chroot_exec "${TARGET}" chsh -s /bin/bash root chroot_exec "${var_target}" chsh -s /bin/bash root
do_log "info" "file_only" "4520() Shell: '${user_root_shell}' not found for: 'root'. Using '/bin/bash' instead." do_log "info" "file_only" "4520() Shell: '${user_root_shell}' not found for: 'root'. Using '/bin/bash' instead."
fi fi
fi fi
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/alias" "${TARGET}/root/.ciss/" install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/alias" "${var_target}/root/.ciss/"
install -m 0700 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/clean_logout.sh" "${TARGET}/root/.ciss/" install -m 0700 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/clean_logout.sh" "${var_target}/root/.ciss/"
install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/shortcuts" "${TARGET}/root/.ciss/" install -m 0600 -o root -g root "${VAR_SETUP_PATH}/includes/target/root/.ciss/shortcuts" "${var_target}/root/.ciss/"
### To be able to copy/paste from vim, one needs to create a '.vimrc' with the following content: ### To be able to copy/paste from vim, one needs to create a '.vimrc' with the following content:
echo 'set clipboard=unnamed' >| "${TARGET}/root/.vimrc" echo 'set clipboard=unnamed' >| "${var_target}/root/.vimrc"
chmod 0600 "${TARGET}/root/.vimrc" chmod 0600 "${var_target}/root/.vimrc"
do_log "info" "file_only" "4520() Skeleton: 'root' successfully generated." do_log "info" "file_only" "4520() Skeleton: 'root' successfully generated."
@@ -112,12 +116,12 @@ accounts_setup() {
case "${user_root_authentication_access_ssh,,}" in case "${user_root_authentication_access_ssh,,}" in
false) false)
sed -i -E "s|^[[:space:]]*PermitRootLogin[[:space:]]+.*$|$(printf '%-29s%s' 'PermitRootLogin' 'no')|" "${TARGET}/etc/ssh/sshd_config" sed -i -E "s|^[[:space:]]*PermitRootLogin[[:space:]]+.*$|$(printf '%-29s%s' 'PermitRootLogin' 'no')|" "${var_target}/etc/ssh/sshd_config"
do_log "info" "file_only" "4520() User: 'root' SSH access: [PermitRootLogin no]" do_log "info" "file_only" "4520() User: 'root' SSH access: [PermitRootLogin no]"
;; ;;
true) true)
sed -i -E "s|^[[:space:]]*PermitRootLogin[[:space:]]+.*$|$(printf '%-29s%s' 'PermitRootLogin' 'prohibit-password')|" "${TARGET}/etc/ssh/sshd_config" sed -i -E "s|^[[:space:]]*PermitRootLogin[[:space:]]+.*$|$(printf '%-29s%s' 'PermitRootLogin' 'prohibit-password')|" "${var_target}/etc/ssh/sshd_config"
do_log "info" "file_only" "4520() User: 'root' SSH access: [PermitRootLogin prohibit-password]" do_log "info" "file_only" "4520() User: 'root' SSH access: [PermitRootLogin prohibit-password]"
;; ;;
@@ -136,7 +140,7 @@ accounts_setup() {
pam_access_sync_login_sshd pam_access_sync_login_sshd
### 3) A) 2) Ensure 'pam_securetty' in the auth phase; requisite causes immediate fail for disallowed ttys. ### 3) A) 2) Ensure 'pam_securetty' in the auth phase; requisite causes immediate fail for disallowed ttys.
chroot_stdin "${TARGET}" "__payload__" <<'EOF' chroot_stdin "${var_target}" "__payload__" <<'EOF'
export LC_ALL=C export LC_ALL=C
if ! grep -Eq '^[[:space:]]*auth[[:space:]]+requisite[[:space:]]+pam_securetty[.]so([[:space:]]|$)' /etc/pam.d/login; then if ! grep -Eq '^[[:space:]]*auth[[:space:]]+requisite[[:space:]]+pam_securetty[.]so([[:space:]]|$)' /etc/pam.d/login; then
tmp="$(mktemp /etc/pam.d/login.XXXXXX)" tmp="$(mktemp /etc/pam.d/login.XXXXXX)"
@@ -162,10 +166,10 @@ fi
EOF EOF
### 3) A) 3) Disallow all local access for root in '/etc/security/access.conf'. ### 3) A) 3) Disallow all local access for root in '/etc/security/access.conf'.
printf -- '-: root:ALL\n' >> "${TARGET}/etc/security/access.conf" printf -- '-: root:ALL\n' >> "${var_target}/etc/security/access.conf"
### 3) A) 4) Empty "/etc/securetty". ### 3) A) 4) Empty "/etc/securetty".
cat << 'EOF' >| "${TARGET}/etc/securetty" cat << 'EOF' >| "${var_target}/etc/securetty"
EOF EOF
do_log "info" "file_only" "4520() User: 'root' tty access: [false]" do_log "info" "file_only" "4520() User: 'root' tty access: [false]"
@@ -173,10 +177,10 @@ EOF
true) true)
### 3) B) 1) Allow local access for 'root' only on 'tty1' in '/etc/security/access.conf'. ### 3) B) 1) Allow local access for 'root' only on 'tty1' in '/etc/security/access.conf'.
printf -- "+: root:tty1 \n" >> "${TARGET}/etc/security/access.conf" printf -- "+: root:tty1 \n" >> "${var_target}/etc/security/access.conf"
### 3) B) 2) Allow local access for 'root' only on 'tty1' in '/etc/securetty'. ### 3) B) 2) Allow local access for 'root' only on 'tty1' in '/etc/securetty'.
cat << 'EOF' >| "${TARGET}/etc/securetty" cat << 'EOF' >| "${var_target}/etc/securetty"
tty1 tty1
EOF EOF
do_log "info" "file_only" "4520() User: 'root' tty access: [true]" do_log "info" "file_only" "4520() User: 'root' tty access: [true]"
@@ -193,13 +197,13 @@ EOF
case "${user_root_authentication_password,,}" in case "${user_root_authentication_password,,}" in
false) false)
chroot_script "${TARGET}" "passwd -l root" chroot_script "${var_target}" "passwd -l root"
do_log "info" "file_only" "4520() User: 'root' password access: [false]" do_log "info" "file_only" "4520() User: 'root' password access: [false]"
;; ;;
true) true)
chroot_script "${TARGET}" "printf '%s:%s\n' root '${var_password}' | /usr/sbin/chpasswd -e" chroot_script "${var_target}" "printf '%s:%s\n' root '${var_password}' | /usr/sbin/chpasswd -e"
#chroot_script "${TARGET}" "/usr/sbin/usermod -p '${user_root_password}' root" #chroot_script "${var_target}" "/usr/sbin/usermod -p '${user_root_password}' root"
do_log "info" "file_only" "4520() User: 'root' password access: [true]" do_log "info" "file_only" "4520() User: 'root' password access: [true]"
;; ;;
@@ -213,7 +217,7 @@ EOF
### 5) Update the 'root' SSH pubkey, if provided via 'preseed.yaml'. ### 5) Update the 'root' SSH pubkey, if provided via 'preseed.yaml'.
if [[ -n "${user_root_sshpubkey:-}" ]]; then if [[ -n "${user_root_sshpubkey:-}" ]]; then
printf "%s\n" "${user_root_sshpubkey}" >| "${TARGET}/root/.ssh/authorized_keys" printf "%s\n" "${user_root_sshpubkey}" >| "${var_target}/root/.ssh/authorized_keys"
do_log "info" "file_only" "4520() User: 'root' SSH public key: inserted." do_log "info" "file_only" "4520() User: 'root' SSH public key: inserted."
fi fi
@@ -221,36 +225,36 @@ EOF
### 6) Update the 'root' 'totp'-policy and write the '.google_authenticator'-file. ### 6) Update the 'root' 'totp'-policy and write the '.google_authenticator'-file.
if [[ "${user_root_authentication_2fa_ssh}" == "true" || "${user_root_authentication_2fa_tty}" == "true" ]]; then if [[ "${user_root_authentication_2fa_ssh}" == "true" || "${user_root_authentication_2fa_tty}" == "true" ]]; then
write_google_authenticator_file "root" "0" "0" write_google_authenticator_file "root" "0" "0" "${var_target}"
fi fi
if [[ "${user_root_authentication_2fa_ssh}" == "true" ]]; then if [[ "${user_root_authentication_2fa_ssh}" == "true" ]]; then
pam_access_totp_enable "root" "sshd" pam_access_totp_enable "root" "sshd" "${var_target}"
var_ssh_totp_update="true" var_ssh_totp_update="true"
cat << EOF >> "${TARGET}/etc/ssh/sshd_config" cat << EOF >> "${var_target}/etc/ssh/sshd_config"
Match User root Match User root
AuthenticationMethods publickey,keyboard-interactive:pam AuthenticationMethods publickey,keyboard-interactive:pam
EOF EOF
fi fi
[[ "${user_root_authentication_2fa_tty}" == "true" ]] && pam_access_totp_enable "root" "login" [[ "${user_root_authentication_2fa_tty}" == "true" ]] && pam_access_totp_enable "root" "login" "${var_target}"
### 7) Install eza themes. ### 7) Install eza themes.
eza_installer "root" eza_installer "root" "${var_target}"
### 8) Double check permissions. ### 8) Double check permissions.
### Directories: 0700 ### Directories: 0700
find "${TARGET}/root" -type d -exec chmod 0700 {} + find "${var_target}/root" -type d -exec chmod 0700 {} +
### Executable files: 0700 (any x-bit set) ### Executable files: 0700 (any x-bit set)
find "${TARGET}/root" -type f -perm /111 -exec chmod 0700 {} + find "${var_target}/root" -type f -perm /111 -exec chmod 0700 {} +
### Non-executable files: 0600 ### Non-executable files: 0600
find "${TARGET}/root" -type f ! -perm /111 -exec chmod 0600 {} + find "${var_target}/root" -type f ! -perm /111 -exec chmod 0600 {} +
### Ownership: UID:GID (do not dereference symlinks; stay on this filesystem) ### Ownership: UID:GID (do not dereference symlinks; stay on this filesystem)
find "${TARGET}/root" -xdev -exec chown -h root:root {} + find "${var_target}/root" -xdev -exec chown -h root:root {} +
### 9) Final status logging. ### 9) Final status logging.
do_log "info" "file_only" "4520() User: 'root' updated." do_log "info" "file_only" "4520() User: 'root' updated."
@@ -292,8 +296,8 @@ EOF
var_specific="${!tmp_specific}" var_specific="${!tmp_specific}"
### 0) A) Check if the 'group' of the 'user' already exists. ### 0) A) Check if the 'group' of the 'user' already exists.
if ! chroot_exec "${TARGET}" getent group "${var_username}" >/dev/null; then if ! chroot_exec "${var_target}" getent group "${var_username}" >/dev/null; then
chroot_exec "${TARGET}" groupadd --gid "${var_gid}" "${var_username}" chroot_exec "${var_target}" groupadd --gid "${var_gid}" "${var_username}"
fi fi
### 0) B) Generates the user account. ### 0) B) Generates the user account.
@@ -302,7 +306,7 @@ EOF
case "${var_restricted}":"${var_system}" in case "${var_restricted}":"${var_system}" in
false:false) false:false)
chroot_exec "${TARGET}" useradd \ chroot_exec "${var_target}" useradd \
--comment "${var_fullname}" \ --comment "${var_fullname}" \
--create-home \ --create-home \
--expiredate 2102-12-31 \ --expiredate 2102-12-31 \
@@ -312,11 +316,11 @@ EOF
--shell "${var_shell}" \ --shell "${var_shell}" \
--uid "${var_uid}" \ --uid "${var_uid}" \
"${var_username}" "${var_username}"
eza_installer "${var_username}" eza_installer "${var_username}" "${var_target}"
;; ;;
true:false) true:false)
chroot_exec "${TARGET}" useradd \ chroot_exec "${var_target}" useradd \
--comment "${var_fullname}" \ --comment "${var_fullname}" \
--expiredate 2102-12-31 \ --expiredate 2102-12-31 \
--gid "${var_gid}" \ --gid "${var_gid}" \
@@ -328,7 +332,7 @@ EOF
;; ;;
false:true) false:true)
chroot_exec "${TARGET}" useradd \ chroot_exec "${var_target}" useradd \
--comment "${var_fullname}" \ --comment "${var_fullname}" \
--create-home \ --create-home \
--expiredate 2102-12-31 \ --expiredate 2102-12-31 \
@@ -342,7 +346,7 @@ EOF
;; ;;
true:true) true:true)
chroot_exec "${TARGET}" useradd \ chroot_exec "${var_target}" useradd \
--comment "${var_fullname}" \ --comment "${var_fullname}" \
--expiredate 2102-12-31 \ --expiredate 2102-12-31 \
--gid "${var_gid}" \ --gid "${var_gid}" \
@@ -362,20 +366,20 @@ EOF
esac esac
### 1) Prepare the 'user' account. ### 1) Prepare the 'user' account.
install -d -m 0700 -o "${var_uid}" -g "${var_gid}" "${TARGET}/home/${var_username}/.ssh" install -d -m 0700 -o "${var_uid}" -g "${var_gid}" "${var_target}/home/${var_username}/.ssh"
install -m 0600 -o "${var_uid}" -g "${var_gid}" /dev/null "${TARGET}/home/${var_username}/.ssh/authorized_keys" install -m 0600 -o "${var_uid}" -g "${var_gid}" /dev/null "${var_target}/home/${var_username}/.ssh/authorized_keys"
install -m 0600 -o "${var_uid}" -g "${var_gid}" "${VAR_SETUP_PATH}/includes/target/etc/skel/.bashrc" "${TARGET}/home/${var_username}/" install -m 0600 -o "${var_uid}" -g "${var_gid}" "${VAR_SETUP_PATH}/includes/target/etc/skel/.bashrc" "${var_target}/home/${var_username}/"
if [[ "${var_shell}" == "/bin/zsh" ]]; then if [[ "${var_shell}" == "/bin/zsh" ]]; then
if [[ -x "${TARGET}${var_shell}" ]]; then if [[ -x "${var_target}${var_shell}" ]]; then
case "${var_specific,,}" in case "${var_specific,,}" in
"ciss") "ciss")
zsh_omz_installer "${var_username}" zsh_omz_installer "${var_username}" "${var_target}"
mv "${TARGET}/home/${var_username}/.zshrc" "${TARGET}/home/${var_username}/.zshrc.bak" mv "${var_target}/home/${var_username}/.zshrc" "${var_target}/home/${var_username}/.zshrc.bak"
install -m 0600 -o "${var_uid}" -g "${var_gid}" "${VAR_SETUP_PATH}/includes/target/etc/skel/.zshrc" "${TARGET}/home/${var_username}" install -m 0600 -o "${var_uid}" -g "${var_gid}" "${VAR_SETUP_PATH}/includes/target/etc/skel/.zshrc" "${var_target}/home/${var_username}"
;; ;;
"physnet") "physnet")
@@ -388,12 +392,12 @@ EOF
esac esac
chroot_exec "${TARGET}" chsh -s "${var_shell}" "${var_username}" chroot_exec "${var_target}" chsh -s "${var_shell}" "${var_username}"
do_log "info" "file_only" "4520() Shell: '${var_shell}' used for: '${var_username}'." do_log "info" "file_only" "4520() Shell: '${var_shell}' used for: '${var_username}'."
else else
chroot_exec "${TARGET}" chsh -s /bin/bash "${var_username}" chroot_exec "${var_target}" chsh -s /bin/bash "${var_username}"
do_log "info" "file_only" "4520() Shell: '${var_shell}' not found for: '${var_username}'. Using '/bin/bash' instead." do_log "info" "file_only" "4520() Shell: '${var_shell}' not found for: '${var_username}'. Using '/bin/bash' instead."
fi fi
@@ -415,7 +419,7 @@ EOF
### 3) A) 2) This step is not required for user accounts. ### 3) A) 2) This step is not required for user accounts.
### 3) A) 3) Disallow all local access for user in '/etc/security/access.conf'. ### 3) A) 3) Disallow all local access for user in '/etc/security/access.conf'.
printf '%s\n' "-: ${var_username}:ALL" >> "${TARGET}/etc/security/access.conf" printf '%s\n' "-: ${var_username}:ALL" >> "${var_target}/etc/security/access.conf"
### 3) A) 4) This step is not required for user accounts. ### 3) A) 4) This step is not required for user accounts.
@@ -424,7 +428,7 @@ EOF
true) true)
### 3) B) 1) Allow local access for 'user' only on 'tty1' in '/etc/security/access.conf'. ### 3) B) 1) Allow local access for 'user' only on 'tty1' in '/etc/security/access.conf'.
printf '%s\n' "+: ${var_username}:tty1" >> "${TARGET}/etc/security/access.conf" printf '%s\n' "+: ${var_username}:tty1" >> "${var_target}/etc/security/access.conf"
### 3) B) 2) This step is not required for user accounts. ### 3) B) 2) This step is not required for user accounts.
@@ -442,13 +446,13 @@ EOF
case "${var_auth_pwd}" in case "${var_auth_pwd}" in
false) false)
chroot_script "${TARGET}" "passwd -l ${var_username}" chroot_script "${var_target}" "passwd -l ${var_username}"
do_log "info" "file_only" "4520() User: '${var_username}' password access: [false]" do_log "info" "file_only" "4520() User: '${var_username}' password access: [false]"
;; ;;
true) true)
chroot_script "${TARGET}" "printf '%s:%s\n' \"${var_username}\" '${var_password}' | /usr/sbin/chpasswd -e" chroot_script "${var_target}" "printf '%s:%s\n' \"${var_username}\" '${var_password}' | /usr/sbin/chpasswd -e"
#chroot_script "${TARGET}" "/usr/sbin/usermod -p '${var_password}' ${var_username}" #chroot_script "${var_target}" "/usr/sbin/usermod -p '${var_password}' ${var_username}"
do_log "info" "file_only" "4520() User: '${var_username}' password access: [true]" do_log "info" "file_only" "4520() User: '${var_username}' password access: [true]"
;; ;;
@@ -462,7 +466,7 @@ EOF
### 5) Update the 'user' SSH pubkey, if provided via 'preseed.yaml'. ### 5) Update the 'user' SSH pubkey, if provided via 'preseed.yaml'.
if [[ -n "${var_sshpubkey:-}" ]]; then if [[ -n "${var_sshpubkey:-}" ]]; then
printf "%s\n" "${var_sshpubkey}" >| "${TARGET}/home/${var_username}/.ssh/authorized_keys" printf "%s\n" "${var_sshpubkey}" >| "${var_target}/home/${var_username}/.ssh/authorized_keys"
do_log "info" "file_only" "4520() User: '${var_username}' SSH public key: inserted." do_log "info" "file_only" "4520() User: '${var_username}' SSH public key: inserted."
fi fi
@@ -470,43 +474,43 @@ EOF
### 6) Update the 'root' 'totp'-policy and write the '.google_authenticator'-file. ### 6) Update the 'root' 'totp'-policy and write the '.google_authenticator'-file.
if [[ "${var_2fa_ssh}" == "true" || "${var_2fa_tty}" == "true" ]]; then if [[ "${var_2fa_ssh}" == "true" || "${var_2fa_tty}" == "true" ]]; then
write_google_authenticator_file "${var_username}" "${var_uid}" "${var_gid}" write_google_authenticator_file "${var_username}" "${var_uid}" "${var_gid}" "${var_target}"
fi fi
if [[ "${var_2fa_ssh}" == "true" ]]; then if [[ "${var_2fa_ssh}" == "true" ]]; then
pam_access_totp_enable "${var_username}" "sshd" pam_access_totp_enable "${var_username}" "sshd" "${var_target}"
var_ssh_totp_update="true" var_ssh_totp_update="true"
cat << EOF >> "${TARGET}/etc/ssh/sshd_config" cat << EOF >> "${var_target}/etc/ssh/sshd_config"
Match User ${var_username} Match User ${var_username}
AuthenticationMethods publickey,keyboard-interactive:pam AuthenticationMethods publickey,keyboard-interactive:pam
EOF EOF
fi fi
[[ "${var_2fa_tty}" == "true" ]] && pam_access_totp_enable "${var_username}" "login" [[ "${var_2fa_tty}" == "true" ]] && pam_access_totp_enable "${var_username}" "login" "${var_target}"
### 7) Check sudo membership for user. ### 7) Check sudo membership for user.
if [[ "${var_sudo}" == "true" ]]; then if [[ "${var_sudo}" == "true" ]]; then
chroot_exec "${TARGET}" usermod -aG sudo "${var_username}" chroot_exec "${var_target}" usermod -aG sudo "${var_username}"
### Hardening sudo users (idempotent) and ensure WinSCP SFTP-as-root. ### Hardening sudo users (idempotent) and ensure WinSCP SFTP-as-root.
hardening_sudo "${var_username}" "${var_specific:-none}" hardening_sudo "${var_username}" "${var_specific:-none}" "${var_target}"
### Enable per-user TOTP in a given PAM service (login, sshd, su, sudo). ### Enable per-user TOTP in a given PAM service (login, sshd, su, sudo).
pam_access_totp_enable "${var_username}" "sudo" pam_access_totp_enable "${var_username}" "sudo" "${var_target}"
fi fi
### 8) Double check permissions. ### 8) Double check permissions.
### Directories: 0700 ### Directories: 0700
find "${TARGET}/home/${var_username}" -type d -exec chmod 0700 {} + find "${var_target}/home/${var_username}" -type d -exec chmod 0700 {} +
### Executable files: 0700 (any x-bit set) ### Executable files: 0700 (any x-bit set)
find "${TARGET}/home/${var_username}" -type f -perm /111 -exec chmod 0700 {} + find "${var_target}/home/${var_username}" -type f -perm /111 -exec chmod 0700 {} +
### Non-executable files: 0600 ### Non-executable files: 0600
find "${TARGET}/home/${var_username}" -type f ! -perm /111 -exec chmod 0600 {} + find "${var_target}/home/${var_username}" -type f ! -perm /111 -exec chmod 0600 {} +
### Ownership: UID:GID (do not dereference symlinks; stay on this filesystem) ### Ownership: UID:GID (do not dereference symlinks; stay on this filesystem)
find "${TARGET}/home/${var_username}" -xdev -exec chown -h "${var_uid}:${var_gid}" {} + find "${var_target}/home/${var_username}" -xdev -exec chown -h "${var_uid}:${var_gid}" {} +
### 9) Final status logging. ### 9) Final status logging.
do_log "info" "file_only" "4520() Created user: [${var_username}] UID: [${var_uid}] GID: [${var_gid}]" do_log "info" "file_only" "4520() Created user: [${var_username}] UID: [${var_uid}] GID: [${var_gid}]"
@@ -515,20 +519,20 @@ EOF
if [[ "${var_ssh_totp_update}" == "true" ]]; then if [[ "${var_ssh_totp_update}" == "true" ]]; then
sed -i -E "s|^[[:space:]]*KbdInteractiveAuthentication[[:space:]]+.*$|$(printf '%-29s%s' 'KbdInteractiveAuthentication' 'yes')|" "${TARGET}/etc/ssh/sshd_config" sed -i -E "s|^[[:space:]]*KbdInteractiveAuthentication[[:space:]]+.*$|$(printf '%-29s%s' 'KbdInteractiveAuthentication' 'yes')|" "${var_target}/etc/ssh/sshd_config"
fi fi
unset VAR_TEMP_PLAIN_MFA_SEED unset VAR_TEMP_PLAIN_MFA_SEED
if ! grep -Fqx -- '-: ALL:ALL' "${TARGET}/etc/security/access.conf"; then if ! grep -Fqx -- '-: ALL:ALL' "${var_target}/etc/security/access.conf"; then
printf '%s\n' '-: ALL:ALL' >> "${TARGET}/etc/security/access.conf" printf '%s\n' '-: ALL:ALL' >> "${var_target}/etc/security/access.conf"
fi fi
printf "# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf \n" >> "${TARGET}/etc/security/access.conf" printf "# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf \n" >> "${var_target}/etc/security/access.conf"
printf "# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf \n" >> "${TARGET}/etc/ssh/sshd_config" printf "# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf \n" >> "${var_target}/etc/ssh/sshd_config"
### Hardening of '/bin/su': only members of the group 'sudo' can su to root. ### Hardening of '/bin/su': only members of the group 'sudo' can su to root.
hardening_su hardening_su
@@ -542,21 +546,23 @@ readonly -f accounts_setup
####################################### #######################################
# Install eza CISS theme for the respective user. # Install eza CISS theme for the respective user.
# Globals: # Globals:
# TARGET # None
# Arguments: # Arguments:
# 1: Username # 1: Username
# 2: Target
# Returns: # Returns:
# 0: on success # 0: on success
####################################### #######################################
eza_installer() { eza_installer() {
### Declare Arrays, HashMaps, and Variables. ### Declare Arrays, HashMaps, and Variables.
declare var_user="${1}" declare -r var_user="${1}" var_target="${2}"
case "${1}" in case "${1}" in
root) declare var_base="/root" ;; root) declare var_base="/root" ;;
*) declare var_base="/home/${var_user}" ;; *) declare var_base="/home/${var_user}" ;;
esac esac
chroot_script "${TARGET}" " chroot_script "${var_target}" "
cd ${var_base} cd ${var_base}
git clone https://github.com/eza-community/eza-themes.git git clone https://github.com/eza-community/eza-themes.git
mkdir -p ${var_base}/.config/eza mkdir -p ${var_base}/.config/eza
@@ -630,9 +636,9 @@ hardening_su() {
### Declare Arrays, HashMaps, and Variables. ### Declare Arrays, HashMaps, and Variables.
declare -r pam_su="/etc/pam.d/su" declare -r pam_su="/etc/pam.d/su"
[[ -f "${TARGET}${pam_su}" ]] || return 0 [[ -f "${var_target}${pam_su}" ]] || return 0
chroot_stdin "${TARGET}" "__payload__" -- "${pam_su}" <<'EOF' chroot_stdin "${var_target}" "__payload__" -- "${pam_su}" <<'EOF'
export LC_ALL=C export LC_ALL=C
pam="$1" pam="$1"
@@ -673,9 +679,11 @@ readonly -f hardening_su
####################################### #######################################
# Hardening sudo users (idempotent) and ensure WinSCP SFTP-as-root. # Hardening sudo users (idempotent) and ensure WinSCP SFTP-as-root.
# Globals: # Globals:
# TARGET # None
# Arguments: # Arguments:
# 1: <username> # 1: username
# 2: user_specifics
# 3: target
# Returns: # Returns:
# 0: on success # 0: on success
# ERR_VERIFY_LOGROTATE: on failure # ERR_VERIFY_LOGROTATE: on failure
@@ -683,15 +691,14 @@ readonly -f hardening_su
####################################### #######################################
hardening_sudo() { hardening_sudo() {
### Declare Arrays, HashMaps, and Variables. ### Declare Arrays, HashMaps, and Variables.
declare var_user="$1" declare -r var_user="${1}" var_specific="${2}" var_target="${3}"
declare var_specific="$2"
declare -r var_logfile="/root/.ciss/cdi/log/4520_accounts_setup.log" declare -r var_logfile="/root/.ciss/cdi/log/4520_accounts_setup.log"
declare -r var_sudo_iolog_dir="${TARGET}/var/log/sudo-io" declare -r var_sudo_iolog_dir="${var_target}/var/log/sudo-io"
declare -r var_sudoers_main="${TARGET}/etc/sudoers" declare -r var_sudoers_main="${var_target}/etc/sudoers"
declare -r var_sudoers_dir="${TARGET}/etc/sudoers.d" declare -r var_sudoers_dir="${var_target}/etc/sudoers.d"
declare -r var_lr_conf="${TARGET}/etc/logrotate.d/sudo" declare -r var_lr_conf="${var_target}/etc/logrotate.d/sudo"
declare -r var_sudoers_winscp_global="${TARGET}/etc/sudoers.d/90-ciss-winscp-sftp" declare -r var_sudoers_winscp_global="${var_target}/etc/sudoers.d/90-ciss-winscp-sftp"
declare -r var_sudoers_winscp_user="${TARGET}/etc/sudoers.d/91-ciss-winscp-${var_user}" declare -r var_sudoers_winscp_user="${var_target}/etc/sudoers.d/91-ciss-winscp-${var_user}"
declare -r var_sftp_bin="/usr/lib/openssh/sftp-server" declare -r var_sftp_bin="/usr/lib/openssh/sftp-server"
### Create sudo I/O log directory (idempotent). ### Create sudo I/O log directory (idempotent).
@@ -716,7 +723,7 @@ EOF
"ciss") "ciss")
### Install global WinSCP SFTP-as-root command alias (idempotent). ### Install global WinSCP SFTP-as-root command alias (idempotent).
if [[ -x "${TARGET}${var_sftp_bin}" ]]; then if [[ -x "${var_target}${var_sftp_bin}" ]]; then
if [[ ! -f "${var_sudoers_winscp_global}" ]]; then if [[ ! -f "${var_sudoers_winscp_global}" ]]; then
@@ -779,14 +786,14 @@ EOF
find "${var_sudoers_dir}" -type f -exec chmod 0440 {} \; find "${var_sudoers_dir}" -type f -exec chmod 0440 {} \;
### Verify sudoers syntax in chroot. ### Verify sudoers syntax in chroot.
if ! chroot_script "${TARGET}" "EDITOR=/usr/bin/nano /usr/sbin/visudo -q -c >> ${var_logfile}"; then if ! chroot_script "${var_target}" "EDITOR=/usr/bin/nano /usr/sbin/visudo -q -c >> ${var_logfile}"; then
do_log "warn" "file_only" "4520() Command: [chroot_script ${TARGET} EDITOR=/usr/bin/nano /usr/sbin/visudo -q -c] failed." do_log "warn" "file_only" "4520() Command: [chroot_script ${var_target} EDITOR=/usr/bin/nano /usr/sbin/visudo -q -c] failed."
return "${ERR_VERIFY_VISUDO}" return "${ERR_VERIFY_VISUDO}"
else else
do_log "info" "file_only" "4520() Command: [chroot_script ${TARGET} EDITOR=/usr/bin/nano /usr/sbin/visudo -q -c] successful." do_log "info" "file_only" "4520() Command: [chroot_script ${var_target} EDITOR=/usr/bin/nano /usr/sbin/visudo -q -c] successful."
fi fi
@@ -813,14 +820,14 @@ EOF
EOF EOF
### Verify logrotate config in chroot. ### Verify logrotate config in chroot.
if ! chroot_script "${TARGET}" "logrotate -d /etc/logrotate.conf >> ${var_logfile}"; then if ! chroot_script "${var_target}" "logrotate -d /etc/logrotate.conf >> ${var_logfile}"; then
do_log "warn" "file_only" "4520() Command: [chroot_script ${TARGET} logrotate -d /etc/logrotate.conf] failed." do_log "warn" "file_only" "4520() Command: [chroot_script ${var_target} logrotate -d /etc/logrotate.conf] failed."
return "${ERR_VERIFY_LOGROTATE}" return "${ERR_VERIFY_LOGROTATE}"
else else
do_log "info" "file_only" "4520() Command: [chroot_script ${TARGET} logrotate -d /etc/logrotate.conf] successful." do_log "info" "file_only" "4520() Command: [chroot_script ${var_target} logrotate -d /etc/logrotate.conf] successful."
fi fi
@@ -848,12 +855,12 @@ pam_access_sync_login_sshd() {
declare var_file_sshd="/etc/pam.d/sshd" declare var_file_sshd="/etc/pam.d/sshd"
### Guard: The file must exist, no-op otherwise. ### Guard: The file must exist, no-op otherwise.
if [[ ! -f "${TARGET}${var_file_login}" ]]; then if [[ ! -f "${var_target}${var_file_login}" ]]; then
return 0 return 0
fi fi
### 1) If the 'pam_access' line is commented in '/etc/pam.d/login', uncomment exactly one occurrence. ### 1) If the 'pam_access' line is commented in '/etc/pam.d/login', uncomment exactly one occurrence.
chroot_stdin "${TARGET}" "__payload__" <<'EOF' chroot_stdin "${var_target}" "__payload__" <<'EOF'
tmp="$(mktemp /etc/pam.d/login.XXXXXX)" tmp="$(mktemp /etc/pam.d/login.XXXXXX)"
export LC_ALL=C export LC_ALL=C
awk ' awk '
@@ -877,9 +884,9 @@ EOF
### 2) If '/etc/pam.d/login' now has an active pam_access line, ensure '/etc/pam.d/sshd' pam_access line(s) are commented out. ### 2) If '/etc/pam.d/login' now has an active pam_access line, ensure '/etc/pam.d/sshd' pam_access line(s) are commented out.
### No-op if '/etc/pam.d/sshd' is absent. ### No-op if '/etc/pam.d/sshd' is absent.
[[ -f "${TARGET}${var_file_sshd}" ]] || return 0 [[ -f "${var_target}${var_file_sshd}" ]] || return 0
chroot_stdin "${TARGET}" "__payload__" <<'EOF' chroot_stdin "${var_target}" "__payload__" <<'EOF'
export LC_ALL=C export LC_ALL=C
if grep -Eq '^[[:space:]]*account[[:space:]]+required[[:space:]]+pam_access[.]so([[:space:]]|$)' /etc/pam.d/login; then if grep -Eq '^[[:space:]]*account[[:space:]]+required[[:space:]]+pam_access[.]so([[:space:]]|$)' /etc/pam.d/login; then
tmp="$(mktemp /etc/pam.d/sshd.XXXXXX)" tmp="$(mktemp /etc/pam.d/sshd.XXXXXX)"
@@ -903,25 +910,25 @@ readonly -f pam_access_sync_login_sshd
####################################### #######################################
# Enable per-user TOTP in a given PAM service (login, sshd, su, sudo). # Enable per-user TOTP in a given PAM service (login, sshd, su, sudo).
# Globals: # Globals:
# TARGET # None
# Arguments: # Arguments:
# 1: <username> # 1: username
# 2: <pam_module> # 2: pam_module
# 3: target
# Returns: # Returns:
# 0: on success # 0: on success
####################################### #######################################
pam_access_totp_enable() { pam_access_totp_enable() {
### Declare Arrays, HashMaps, and Variables. ### Declare Arrays, HashMaps, and Variables.
declare var_user="$1" declare -r var_user="${1}" var_module="${2}" var_target="${3}"
declare var_module="$2" declare -r var_pam_file="/etc/pam.d/${var_module}"
declare var_pam_file="/etc/pam.d/${var_module}" declare -r var_users_file="${var_target}/etc/ciss/2fa.users"
declare var_users_file="${TARGET}/etc/ciss/2fa.users" declare -r var_allowlist="/etc/ciss/2fa.users"
declare var_allowlist="/etc/ciss/2fa.users"
### Basic sanitation; module must be a safe 'pam.d' filename. ### Basic sanitation; module must be a safe 'pam.d' filename.
[[ -n "${var_user:-}" && -n "${var_module:-}" ]] || return 0 [[ -n "${var_user:-}" && -n "${var_module:-}" ]] || return 0
[[ "${var_module}" =~ ^[A-Za-z0-9._+-]+$ ]] || return 0 [[ "${var_module}" =~ ^[A-Za-z0-9._+-]+$ ]] || return 0
[[ -f "${TARGET}${var_pam_file}" ]] || return 0 [[ -f "${var_target}${var_pam_file}" ]] || return 0
### 0) Ensure the allowlist file contains the user (deduplicated). ### 0) Ensure the allowlist file contains the user (deduplicated).
if ! grep -Fxq "${var_user}" "${var_users_file}"; then if ! grep -Fxq "${var_user}" "${var_users_file}"; then
@@ -931,7 +938,7 @@ pam_access_totp_enable() {
### 1) Ensure a single CISS TOTP framework block is present in the PAM file. ### 1) Ensure a single CISS TOTP framework block is present in the PAM file.
### The block gates GA by pam_listfile over '/etc/ciss/2fa.users'. ### The block gates GA by pam_listfile over '/etc/ciss/2fa.users'.
### We place it right after pam_unix.so or @include common-auth; fallback: append. ### We place it right after pam_unix.so or @include common-auth; fallback: append.
chroot_stdin "${TARGET}" "__payload__" -- "${var_pam_file}" "${var_allowlist}" <<'EOF' chroot_stdin "${var_target}" "__payload__" -- "${var_pam_file}" "${var_allowlist}" <<'EOF'
export LC_ALL=C export LC_ALL=C
pam="$1" pam="$1"
allowlist="$2" allowlist="$2"
@@ -969,7 +976,7 @@ rm -f -- "${tmp}" || :
EOF EOF
### 2) Comment out any other active GA lines to avoid double prompts. ### 2) Comment out any other active GA lines to avoid double prompts.
chroot_stdin "${TARGET}" "__payload__" -- "${var_pam_file}" <<'EOF' chroot_stdin "${var_target}" "__payload__" -- "${var_pam_file}" <<'EOF'
export LC_ALL=C export LC_ALL=C
pam="$1" pam="$1"
tmp="$(mktemp "${pam}.XXXXXX")" tmp="$(mktemp "${pam}.XXXXXX")"
@@ -1037,20 +1044,22 @@ readonly -f read_totp_seed
# Writes '.google_authenticator'-file for the respective user. # Writes '.google_authenticator'-file for the respective user.
# Globals: # Globals:
# DIR_TMP # DIR_TMP
# TARGET
# Arguments: # Arguments:
# 1: Username # 1: USERNAME
# 2: UID # 2: UID
# 3: GID # 3: GID
# 4: TARGET
# Returns: # Returns:
# 0: on success # 0: on success
####################################### #######################################
write_google_authenticator_file() { write_google_authenticator_file() {
### Declare Arrays, HashMaps, and Variables. ### Declare Arrays, HashMaps, and Variables.
declare var_user="${1}" var_user_id="${2}" var_group_id="${3}" var_secret="" declare -r var_user="${1}" var_user_id="${2}" var_group_id="${3}" var_target="${4}"
declare var_secret=""
case "${1}" in case "${1}" in
root) declare var_base="${TARGET}/root" ;; root) declare var_base="${var_target}/root" ;;
*) declare var_base="${TARGET}/home/${var_user}" ;; *) declare var_base="${var_target}/home/${var_user}" ;;
esac esac
declare -i i=0 declare -i i=0
@@ -1102,19 +1111,20 @@ readonly -f write_google_authenticator_file
####################################### #######################################
# Use the official ohmyzsh-installer but force non-interactive behavior; do not run zsh; do not chsh. # Use the official ohmyzsh-installer but force non-interactive behavior; do not run zsh; do not chsh.
# Globals: # Globals:
# TARGET # None
# Arguments: # Arguments:
# 1: Username # 1: Username
# 2: Target
# Returns: # Returns:
# 0: on success # 0: on success
####################################### #######################################
zsh_omz_installer() { zsh_omz_installer() {
### Declare Arrays, HashMaps, and Variables. ### Declare Arrays, HashMaps, and Variables.
declare var_user="${1}" declare -r var_user="${1}" var_target="${2}"
### Install Oh My Zsh and two plugins for a given user (non-interactive, idempotent). ### Install Oh My Zsh and two plugins for a given user (non-interactive, idempotent).
### Args to payload: $1 = username (e.g., "root" or "alice") ### Args to payload: $1 = username (e.g., "root" or "alice")
chroot_stdin "${TARGET}" "__payload__" -- "${var_user}" <<'EOF' chroot_stdin "${var_target}" "__payload__" -- "${var_user}" <<'EOF'
export LC_ALL=C export LC_ALL=C
user="$1" user="$1"
@@ -1225,4 +1235,105 @@ EOF
### Prevents accidental 'unset -f'. ### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034 # shellcheck disable=SC2034
readonly -f zsh_omz_installer readonly -f zsh_omz_installer
#######################################
# description
# Globals:
# TARGET
# Arguments:
# None
#######################################
write_pam_sshd() {
### Declare Arrays, HashMaps, and Variables.
declare -r var_target="$1"
mv "${var_target}/etc/pam.d/sshd" "${var_target}/root/.ciss/cdi/backup/etc/pam.d/sshd"
insert_header "${var_target}/etc/pam.d/sshd"
insert_comments "${var_target}/etc/pam.d/sshd"
cat << EOF >> "${var_target}/etc/pam.d/sshd"
# ===== CISS 2FA block (MUST be placed at the very top of /etc/pam.d/sshd) =====
# If user is NOT listed -> succeed and SKIP next two lines (silent Keyboard-Interactive (KI) success).
auth [success=2 default=ignore] pam_listfile.so item=user sense=deny file=/etc/ciss/2fa onerr=ignore
# For listed users: enforce that the secret file exists, else deny without prompting.
# pam_google_authenticator will itself fail if the file is absent; we add a clear hint before it.
auth required pam_echo.so file=/etc/ciss/ssh_totp.prompt
auth required pam_google_authenticator.so
# No 'nullok' here: listed users MUST have a secret; missing -> hard fail.
# For non-2FA users KI must be a silent success to satisfy AuthenticationMethods.
auth sufficient pam_permit.so
# ===== CISS 2FA block end =====
# Keep the rest as shipped by Debian; it will be short-circuited by pam_permit for KI
# and never reached for 2FA users after successful GA.
# PAM configuration for the Secure Shell service
# Standard Un*x authentication.
@include common-auth
# Disallow non-root logins when /etc/nologin exists.
account required pam_nologin.so
# Uncomment and edit /etc/security/access.conf if you need to set complex
# access limits that are hard to express in sshd_config.
# account required pam_access.so
# Standard Un*x authorization.
@include common-account
# SELinux needs to be the first session rule. This ensures that any
# lingering context has been cleared. Without this it is possible that a
# module could execute code in the wrong domain.
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
# Set the loginuid process attribute.
session required pam_loginuid.so
# Create a new session keyring.
session optional pam_keyinit.so force revoke
# Standard Un*x session setup and teardown.
@include common-session
# Print the message of the day upon successful login.
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
session optional pam_motd.so motd=/run/motd.dynamic
session optional pam_motd.so noupdate
# Print the status of the user's mailbox upon successful login.
session optional pam_mail.so standard noenv # [1]
# Set up user limits from /etc/security/limits.conf.
session required pam_limits.so
# Read environment variables from /etc/environment and
# /etc/security/pam_env.conf.
session required pam_env.so # [1]
# In Debian 4.0 (etch), locale-related environment variables were moved to
# /etc/default/locale, so read that as well.
session required pam_env.so envfile=/etc/default/locale
# SELinux needs to intervene at login time to ensure that the process starts
# in the proper default security context. Only sessions which are intended
# to run in the user's context should be run after this.
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
# Standard Un*x password updating.
@include common-password
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf
EOF
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f write_pam_sshd
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -31,29 +31,44 @@ installation_packages() {
if [[ "${VAR_APT_FULL_UPGRADE}" == "true" ]]; then if [[ "${VAR_APT_FULL_UPGRADE}" == "true" ]]; then
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get update 2>&1 | tee -a ${var_logfile} apt-get update 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
apt-get upgrade -y 2>&1 | tee -a ${var_logfile} apt-get upgrade -y 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
fi fi
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests ${ARY_PACKAGES[*]} 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests ${ARY_PACKAGES[*]} 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get autoclean -y 2>&1 | tee -a ${var_logfile} apt-get autoclean -y 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
apt-get autopurge -y 2>&1 | tee -a ${var_logfile} apt-get autopurge -y 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
apt-get autoremove -y 2>&1 | tee -a ${var_logfile} apt-get autoremove -y 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f installation_packages
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -39,7 +39,8 @@ installation_security() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests ${ary_fw[*]} 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests ${ary_fw[*]} 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
if [[ ${VAR_SEC_FW} == apparmor ]]; then if [[ ${VAR_SEC_FW} == apparmor ]]; then
systemctl enable apparmor 2>&1 | tee -a ${var_logfile} || true systemctl enable apparmor 2>&1 | tee -a ${var_logfile} || true
@@ -100,4 +101,7 @@ EOF
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f installation_security
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -34,7 +34,8 @@ install_verification() {
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests auditd 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests auditd 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
rm -f "${TARGET}/etc/audit/rules.d/audit.rules" rm -f "${TARGET}/etc/audit/rules.d/audit.rules"
@@ -49,7 +50,7 @@ install_verification() {
-b 16384 -b 16384
## This determine how long to wait in burst of events ## This determine how long to wait in burst of events
--backlog_wait_time 60000 --backlog_wait_time 1024
## Set failure mode to syslog ## Set failure mode to syslog
-f 1 -f 1
@@ -339,26 +340,35 @@ EOF
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
systemctl enable auditd.service 2>&1 | tee -a ${var_logfile} systemctl enable auditd.service 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
### Validate and build audit rules now; fail early if syntax is wrong. ### Validate and build audit rules now; fail early if syntax is wrong.
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
if command -v augenrules >/dev/null 2>&1; then if command -v augenrules >/dev/null 2>&1; then
augenrules --load 2>&1 | tee -a ${var_logfile} augenrules --load 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
else else
### Fallback: build consolidated rules file without loading into the kernel. ### Fallback: build consolidated rules file without loading into the kernel.
if command -v bash >/dev/null 2>&1; then if command -v bash >/dev/null 2>&1; then
bash -lc 'cat /etc/audit/rules.d/*.rules > /etc/audit/audit.rules' bash -lc 'cat /etc/audit/rules.d/*.rules > /etc/audit/audit.rules'
fi fi
fi fi
" "
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests aide aide-common 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests aide aide-common 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
sed -i 's/Checksums = H/Checksums = sha512/' /etc/aide/aide.conf sed -i 's/Checksums = H/Checksums = sha512/' /etc/aide/aide.conf
aideinit > /dev/null 2>> ${var_logfile} aideinit > /dev/null 2>> ${var_logfile}
" "
@@ -366,7 +376,8 @@ EOF
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests debsums 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests debsums 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
if ! debsums -g >> ${var_logfile} 2>> ${var_logfile}; then if ! debsums -g >> ${var_logfile} 2>> ${var_logfile}; then
printf 'Running debsums -g - encountered errors.' >> ${var_logfile} printf 'Running debsums -g - encountered errors.' >> ${var_logfile}
fi fi
@@ -374,10 +385,13 @@ EOF
chroot_script "${TARGET}" " chroot_script "${TARGET}" "
rkhunter --propupd 2>&1 | tee -a ${var_logfile} rkhunter --propupd 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
guard_dir && return 0 guard_dir && return 0
} }
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f install_verification
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -96,7 +96,8 @@ installation_toolset_reco() {
chroot_script "${RECOVERY}" " chroot_script "${RECOVERY}" "
export INITRD=No export INITRD=No
apt-get install -y --no-install-recommends --no-install-suggests ${ary_unique_pkgs[*]} 2>&1 | tee -a ${var_logfile} apt-get install -y --no-install-recommends --no-install-suggests ${ary_unique_pkgs[*]} 2>&1 | tee -a ${var_logfile}
echo ExitCode of PIPESTATUS[0]: \${PIPESTATUS[0]} >> ${var_logfile} RC=( \${PIPESTATUS[@]} )
echo ExitCode of PIPESTATUS[0]: \${RC[0]} >> ${var_logfile}
" "
fi fi