317 lines
12 KiB
Bash
317 lines
12 KiB
Bash
#!/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
|
||
|
||
####
|
||
setup_dropbear() {
|
||
rm -f "${TARGET}"/etc/dropbear/initramfs/dropbear*key
|
||
|
||
do_in_target "${TARGET}" "${TARGET}/usr/bin/dropbearkey" -t rsa -s 4096 -f "${TARGET}/etc/dropbear/initramfs/dropbear_rsa_host_key"
|
||
do_in_target "${TARGET}" "${TARGET}/usr/bin/dropbearkey" -t ed25519 -f "${TARGET}/etc/dropbear/initramfs/dropbear_ed25519_host_key"
|
||
|
||
chmod 0600 "${TARGET}"/etc/dropbear/initramfs/dropbear*key
|
||
chown root:root "${TARGET}"/etc/dropbear/initramfs/dropbear*key
|
||
|
||
declare -a ary_user=()
|
||
ary_user+=("${user_root_ssh_pubkeys_0}")
|
||
[[ -n "${user_root_ssh_pubkeys_1}" ]] && ary_user+=("${user_root_ssh_pubkeys_1}")
|
||
[[ -n "${user_root_ssh_pubkeys_2}" ]] && ary_user+=("${user_root_ssh_pubkeys_2}")
|
||
[[ -n "${user_root_ssh_pubkeys_3}" ]] && ary_user+=("${user_root_ssh_pubkeys_3}")
|
||
|
||
touch "${TARGET}/etc/dropbear/initramfs/authorized_keys" && chmod 0600 "${TARGET}/etc/dropbear/initramfs/authorized_keys"
|
||
printf "%s\n" "${ary_user[@]}" > "${TARGET}/etc/dropbear/initramfs/authorized_keys"
|
||
install -D -m 0755 -o root -g root "${VAR_SETUP_PATH}/includes/etc/banner" "${TARGET}/etc/dropbear/initramfs/"
|
||
|
||
if [[ "${user_dropbear_dhcp,,}" != "true" ]]; then
|
||
declare network_static_ipv4ntpserver_0="192.53.103.108"
|
||
### "IP=<HOST IP>::<GATEWAY IP>:<SUBNET MASK>:<FQDN>:<NIC>:none:<NS 0 IP>:<NS 1 IP>:<NTP IP>"
|
||
printf "IP=%s::%s:%s:%s:%s:none:%s:%s:%s\n" \
|
||
"${VAR_FINAL_IPV4}" \
|
||
"${VAR_FINAL_IPV4_GW}" \
|
||
"${VAR_FINAL_IPV4_SUBNET}" \
|
||
"${VAR_FINAL_FQDN}" \
|
||
"${VAR_FINAL_NIC}" \
|
||
"${network_static_ipv4nameserver_0}" \
|
||
"${network_static_ipv4nameserver_1}" \
|
||
"${network_static_ipv4ntpserver_0}" \
|
||
>| "${TARGET}/etc/initramfs-tools/conf.d/ip"
|
||
else
|
||
### "IP=:::::<NIC>:dhcp"
|
||
printf "IP=:::::%s:dhcp\n" "${VAR_FINAL_NIC}" >| "${TARGET}/etc/initramfs-tools/conf.d/ip"
|
||
fi
|
||
|
||
}
|
||
|
||
# TODO Important insert cryptdevice=UUID=881366ae-61ee-4ee0-893c-0def27c78c9e:cryptroot root=/dev/mapper/vg00-root
|
||
# TODO Important insert GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0 biosdevname=0 ip=152.53.66.126::152.53.64.1:255.255.252.0:soc:ens3:none"
|
||
|
||
|
||
command="/usr/local/bin/coresecret.sh",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICp+6S+qM87lLWUtvTGBV/GFNvYyvZ992X4/AcuraKwm 2025_run.coresecret.dev_root
|
||
|
||
***
|
||
run.coresecret.dev
|
||
/dev/sda5: UUID="468ad656-0e2f-4fff-9501-c691bab9f553" TYPE="crypto_LUKS" PARTLABEL="crypt_system" PARTUUID="78c0f711-f84f-425e-9455-a46430f40794"
|
||
echo "IP=65.21.249.232::172.31.1.1:255.255.255.255:run.coresecret.dev:enp1s0:none:135.181.207.105:89.58.62.53:192.53.103.108" >| /etc/initramfs-tools/conf.d/ip
|
||
GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=UUID=468ad656-0e2f-4fff-9501-c691bab9f553:cryptroot root=/dev/mapper/vg_system-root"
|
||
***
|
||
|
||
/usr/share/cryptsetup/initramfs/bin/cryptroot-unlock
|
||
# Vorher (Standard)
|
||
ASKPASS=/lib/cryptsetup/askpass
|
||
|
||
# Danach
|
||
ASKPASS=/lib/cryptsetup/askpass.cryptsetup
|
||
|
||
apt-get cryptsetup-nuke-password
|
||
dpkg-reconfigure cryptsetup-nuke-password
|
||
|
||
debconf-set-selections << END
|
||
cryptsetup-nuke-password cryptsetup-nuke-password/password string Th3Pa$$w0rd
|
||
cryptsetup-nuke-password cryptsetup-nuke-password/password-again string Th3Pa$$w0rd
|
||
END
|
||
sudo dpkg-reconfigure -f noninteractive cryptsetup-nuke-password
|
||
|
||
apt-get install -y busybox cryptsetup-initramfs dropbear-initramfs initramfs-tools
|
||
rm -f /etc/dropbear/initramfs/dropbear*key
|
||
dropbearkey -t rsa -s 4096 -f /etc/dropbear/initramfs/dropbear_rsa_host_key
|
||
dropbearkey -t ed25519 -f /etc/dropbear/initramfs/dropbear_ed25519_host_key
|
||
chmod 600 /etc/dropbear/initramfs/dropbear*key
|
||
chown root:root /etc/dropbear/initramfs/dropbear*key
|
||
cp -af ~/.ssh/authorized_keys /etc/dropbear/initramfs
|
||
echo "IP=152.53.110.40::152.53.108.1:255.255.252.0:git.coresecret.dev:ens3:none:135.181.207.105:89.58.62.53:192.53.103.108" >| /etc/initramfs-tools/conf.d/ip
|
||
sed -i 's|#DROPBEAR_OPTIONS=""|DROPBEAR_OPTIONS="-p 37768 -s -j -k -I 300 -c coresecret.sh"|g' /etc/dropbear/initramfs/dropbear.conf
|
||
|
||
GRUB_CMDLINE_LINUX_DEFAULT="cryptdevice=UUID=881366ae-61ee-4ee0-893c-0def27c78c9e:cryptroot root=/dev/mapper/vg00-root"
|
||
update-initramfs -u -v -k all
|
||
|
||
NIC_MODULE=$(lspci -k | grep -A2 -i ethernet | grep 'Kernel driver in use' | awk '{print $5}')
|
||
echo "$NIC_MODULE"
|
||
|
||
grep_nic_driver_modules() {
|
||
# Alle Treibernamen sammeln und unique sortieren
|
||
readarray -t _mods < <(
|
||
lspci -k \
|
||
| grep -A2 -i ethernet \
|
||
| grep 'Kernel driver in use' \
|
||
| awk '{print $5}' \
|
||
| sort -u
|
||
)
|
||
|
||
# Wenn nur ein Eintrag übrig bleibt, in NIC_MODULE speichern,
|
||
# sonst alternativ alle Module in NIC_MODULES
|
||
if [ "${#_mods[@]}" -eq 1 ]; then
|
||
NIC_MODULE="${_mods[0]}"
|
||
else
|
||
NIC_MODULES="${_mods[*]}"
|
||
fi
|
||
|
||
# Ausgabe zur Kontrolle
|
||
if [ -n "$NIC_MODULE" ]; then
|
||
echo "Einzelnes Modul: $NIC_MODULE"
|
||
else
|
||
echo "Mehrere Module: $NIC_MODULES"
|
||
fi
|
||
}
|
||
|
||
###########################################################################################
|
||
# Installation of the specified kernel incl. dropbear SSH, LUKS Nuke.
|
||
# Globals:
|
||
# MODULE_ERR
|
||
# MODULE_TXT
|
||
# TARGET
|
||
# kernel
|
||
# Arguments:
|
||
# None
|
||
###########################################################################################
|
||
3_7_7_functions_installation_kernel() {
|
||
declare -g -x MODULE_ERR="3_7_7_functions_installation_kernel"
|
||
declare -g -x MODULE_TXT="Install kernel: '${kernel}'"
|
||
do_show_header "${MODULE_TXT}"
|
||
|
||
# Installing the chosen Kernel Image according to preseed.yaml
|
||
do_in_target "${TARGET}" apt-get install -y "${kernel}"
|
||
|
||
if [[ ${accounts_dropbear_ssh,,} == "true" ]]; then
|
||
|
||
do_in_target "${TARGET}" apt-get install -y busybox cryptsetup-initramfs dropbear-initramfs initramfs-tools
|
||
|
||
echo "DROPBEAR_OPTIONS=\"-p ${accounts_ssh_port} -s -j -k -I 300\"" > "${TARGET}/etc/dropbear/initramfs/dropbear.conf"
|
||
cat > "${TARGET}/etc/dropbear/initramfs/authorized_keys" << EOF
|
||
command="/bin/security-rescue-shell",no-port-forwarding,no-pty,no-X11-forwarding ${accounts_dropbear_pubkey}
|
||
EOF
|
||
chmod 0644 "${TARGET}/etc/dropbear/initramfs/dropbear.conf"
|
||
chown root:root "${TARGET}/etc/dropbear/initramfs/dropbear.conf"
|
||
chmod 0600 "${TARGET}/etc/dropbear/initramfs/authorized_keys"
|
||
chown root:root "${TARGET}/etc/dropbear/initramfs/authorized_keys"
|
||
do_log "info" "true" "Command: 'echo \"DROPBEAR_OPTIONS=\"-p ${accounts_ssh_port} -s -j -k -I 300 -K curve25519-sha256 -c aes256-gcm@openssh.com -m hmac-sha2-256,hmac-sha2-512\" > ${TARGET}/etc/dropbear/initramfs/dropbear.conf' executed in: '${TARGET}'."
|
||
do_log "info" "true" "Command: 'echo ${accounts_dropbear_pubkey} > ${TARGET}/etc/dropbear/initramfs/authorized_keys' executed in: '${TARGET}'."
|
||
|
||
# Network-Pre-Script for initramfs DHCP
|
||
cat > "${TARGET}/etc/initramfs-tools/scripts/init-premount/dhcp-network" << 'EOF'
|
||
#!/bin/sh
|
||
# ^^ no bash in initramfs environment, only BusyBox
|
||
PREREQ=""
|
||
prereqs() { echo "${PREREQ}"; }
|
||
case $1 in
|
||
prereqs) prereqs; exit 0 ;;
|
||
esac
|
||
|
||
# NIC without ":" and VLAN-Suffix
|
||
iface=$(grep -E '^(eth|en)[^:.]*$' /sys/class/net | head -n1)
|
||
[ -n "${iface}" ] || exit 0
|
||
|
||
# Setup Link and dhclient or udhcpc
|
||
ip link set "${iface}" up
|
||
if command -v dhclient >/dev/null 2>&1; then
|
||
dhclient "${iface}"
|
||
else
|
||
udhcpc -i "${iface}"
|
||
fi
|
||
|
||
exit 0
|
||
EOF
|
||
chmod +x "${TARGET}/etc/initramfs-tools/scripts/init-premount/dhcp-network"
|
||
do_log "info" "true" "Generated: '${TARGET}/etc/initramfs-tools/scripts/init-premount/dhcp-network: '${TARGET}'."
|
||
|
||
cat > "${TARGET}/etc/initramfs-tools/scripts/init-bottom/dropbear_fw" << EOF
|
||
#!/bin/sh
|
||
# ^^ no bash in initramfs environment, only BusyBox
|
||
if command -v iptables >/dev/null 2>&1; then
|
||
iptables -F
|
||
iptables -P INPUT DROP
|
||
iptables -P OUTPUT ACCEPT
|
||
iptables -P FORWARD DROP
|
||
iptables -A INPUT -p tcp --dport "${accounts_ssh_port}" -s "${accounts_bastion_vpn_ipv4}" -j ACCEPT
|
||
iptables -A INPUT -i lo -j ACCEPT
|
||
fi
|
||
|
||
if command -v ip6tables >/dev/null 2>&1; then
|
||
ip6tables -F
|
||
ip6tables -P INPUT DROP
|
||
ip6tables -P OUTPUT ACCEPT
|
||
ip6tables -P FORWARD DROP
|
||
ip6tables -A INPUT -p tcp --dport "${accounts_ssh_port}" -s "${accounts_bastion_vpn_ipv6}" -j ACCEPT
|
||
ip6tables -A INPUT -i lo -j ACCEPT
|
||
fi
|
||
EOF
|
||
chmod +x "${TARGET}/etc/initramfs-tools/scripts/init-bottom/dropbear_fw"
|
||
|
||
cat > "${TARGET}/bin/remote-nuke.sh" << EOF
|
||
#!/bin/sh
|
||
# ^^ no bash in initramfs environment, only BusyBox
|
||
# remote-nuke.sh – to be executed at the end of Initramfs
|
||
|
||
PREREQ="local-bottom"
|
||
prereqs() { echo "${PREREQ}"; }
|
||
case $1 in
|
||
prereqs) prereqs; exit 0 ;;
|
||
esac
|
||
|
||
message() {
|
||
if [ ${#*} -lt 76 ]; then
|
||
echo "$*" 1>&2
|
||
else
|
||
# use busybox's fold(1) and sed(1) at initramfs stage
|
||
echo "$*" | fold -s | sed '1! s/^/ /' 1>&2
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
. /scripts/functions # delivers log_* und ASKPASS
|
||
|
||
# Brief break, to ensure all devices are mapped
|
||
sleep 1
|
||
|
||
readonly MAX_RETRIES=5
|
||
|
||
for DEV in /dev/sd*[0-9]; do
|
||
[ -b "${DEV}" ] || continue
|
||
DEV_NAME=$(basename "${DEV}" | tr -cs 'a-zA-Z0-9' '_')
|
||
NUKE_MAP="nuke_${DEV_NAME}"
|
||
TRY_MAP="try_${DEV_NAME}"
|
||
|
||
ASKPASS=/usr/bin/ssh-askpass
|
||
password="$(${ASKPASS} "Enter LUKS passphrase: ")"
|
||
|
||
message "Checking ${DEV} ..."
|
||
if ! cryptsetup isLuks "${DEV}" 2>/dev/null; then
|
||
message "${DEV} is not a LUKS-Container – skipped."
|
||
continue
|
||
fi
|
||
|
||
# Verify, if LUKS Key Slot #31 exists
|
||
if cryptsetup luksDump "${DEV}" 2>/dev/null | grep -q '^Key Slot 31: *ENABLED'; then
|
||
has_slot31="yes"
|
||
else
|
||
has_slot31="no"
|
||
fi
|
||
|
||
attempt=1
|
||
while [ ${attempt} -le ${MAX_RETRIES} ]; do
|
||
message "Attempt '${attempt}/${MAX_RETRIES}' for opening ${DEV} ..."
|
||
|
||
if [ "${has_slot31}" = yes ]; then
|
||
if echo "${password}" | cryptsetup open --test-passphrase --key-slot 31 "${DEV}" "${NUKE_MAP}" 2>/dev/null; then
|
||
echo YES | cryptsetup erase "${DEV}"
|
||
message "Slot 31 of ${DEV} exists. Cleaning OK successful."
|
||
break
|
||
fi
|
||
fi
|
||
|
||
if echo "$((password))" | cryptsetup open "${DEV}" "crypt_${NAME}" 2>/dev/null; then
|
||
|
||
decrypted_any=yes
|
||
break
|
||
fi
|
||
# 2) Normales Entschlüsseln (jeder Slot)
|
||
echo "$password" | cryptsetup open \
|
||
--test-passphrase \
|
||
"$DEV" nuke_tmp 2>/dev/null
|
||
if [ $? -eq 0 ]; then
|
||
log_success_msg "Normales Test-Passphrase erfolgreich"
|
||
cryptsetup erase "$DEV" && \
|
||
log_success_msg "LUKS-Header von $DEV gelöscht"
|
||
break
|
||
else
|
||
log_warning_msg "Normales Test-Passphrase fehlgeschlagen"
|
||
fi
|
||
|
||
attempt=$((attempt + 1))
|
||
if [ $attempt -le $MAX_RETRIES ]; then
|
||
log_begin_msg "Warte 1s vor erneutem Versuch für $DEV…"
|
||
sleep 1
|
||
else
|
||
log_error_msg "Maximale Versuche für $DEV erreicht – überspringe"
|
||
fi
|
||
done
|
||
|
||
# Aufräumen: falls ein Mapper existiert, schließen
|
||
if [ -e /dev/mapper/nuke_tmp ]; then
|
||
cryptsetup close nuke_tmp
|
||
fi
|
||
done
|
||
|
||
log_end_msg 0
|
||
exit 0
|
||
EOF
|
||
chmod +x "${TARGET}/bin/security-rescue-shell"
|
||
|
||
# Regenerate Initramfs incl. Dropbear SSH, Scripts and Keys
|
||
do_in_target "${TARGET}" update-initramfs -u
|
||
fi
|
||
|
||
do_log "info" "true" "Dropbear SSH in initramfs des Targets installiert und konfiguriert (Port: ${accounts_ssh_port}, CA aktiviert, RateLimit & Nuke-Key)."
|
||
do_show_footer "${MODULE_TXT}"
|
||
}
|
||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh:
|