Files
CISS.debian.installer/func/4195_setup_dropbear.sh
2025-07-17 13:42:37 +02:00

317 lines
12 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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: