161 lines
5.2 KiB
Bash
161 lines
5.2 KiB
Bash
#!/bin/bash
|
|
|
|
sshcs_check_nonempty() {
|
|
local filepath="$1"
|
|
|
|
[ -e "${filepath}" ] && grep -q -v '^\s*\(#\|$\)' "${filepath}"
|
|
}
|
|
|
|
sshcs_check_keys() {
|
|
local dropbear_keyfile
|
|
local openssh_keyfile
|
|
local fingerprint
|
|
|
|
for keytype in "${dropbear_key_types[@]}"; do
|
|
dropbear_keyfile=${dropbear_keyfile_prefix}${keytype}${dropbear_keyfile_suffix}
|
|
openssh_keyfile=${openssh_keyfile_prefix}${keytype}${openssh_keyfile_suffix}
|
|
|
|
# Prefer OpenSSH keys, or generate missing ones
|
|
if [ -e "${openssh_keyfile}" ]; then
|
|
#echo "Copying OpenSSH ${keytype} host key for dropbear ..."
|
|
dropbearconvert openssh dropbear "${openssh_keyfile}" "${dropbear_keyfile}" > /dev/null 2>&1
|
|
elif [ ! -e "${dropbear_keyfile}" ]; then
|
|
#echo "Generating ${keytype} host key for dropbear ..."
|
|
dropbearkey -t "${keytype}" -f "${dropbear_keyfile}" > /dev/null 2>&1
|
|
fi
|
|
fingerprint=$(dropbearkey -y -f "${dropbear_keyfile}" | sed -n '/^Fingerprint:/ {s/Fingerprint: *//; p}')
|
|
echo "$(basename "${dropbear_keyfile}") : ${fingerprint}"
|
|
done
|
|
}
|
|
|
|
build() {
|
|
local etc_crypttab="/etc/crypttab"
|
|
local dropbear_authorized_keys="/etc/dropbear/initrd.authorized_keys"
|
|
local sshcs_env="/etc/initcpio/sshcs_env"
|
|
local dropbear_key_types=( "rsa" "ecdsa" "ed25519" )
|
|
local dropbear_keyfile_prefix="/etc/dropbear/dropbear_"
|
|
local dropbear_keyfile_suffix="_host_key"
|
|
local openssh_keyfile_prefix="/etc/ssh/ssh_host_"
|
|
local openssh_keyfile_suffix="_key"
|
|
|
|
# Check we are needed
|
|
if ! sshcs_check_nonempty "${dropbear_authorized_keys}"; then
|
|
echo "There is no root key(s) in ${dropbear_authorized_keys}. Skipping."
|
|
return 0
|
|
fi
|
|
if ! sshcs_check_nonempty "${etc_crypttab}"; then
|
|
echo "There is no device in ${etc_crypttab}. Skipping."
|
|
return 0
|
|
fi
|
|
|
|
umask 0022
|
|
|
|
sshcs_check_keys
|
|
|
|
# Note: parts of this script (modules/binaries/files added) are the same than
|
|
# other install scripts (/usr/lib/initcpio/install/):
|
|
# - 'encryp': nominal support of encrypted volumes at boot time
|
|
# - 'net': network tools
|
|
|
|
## Modules
|
|
# (from 'encrypt')
|
|
add_module 'dm-crypt'
|
|
add_module 'dm-integrity'
|
|
if [[ $CRYPTO_MODULES ]]; then
|
|
local mod
|
|
for mod in $CRYPTO_MODULES; do
|
|
add_module "$mod"
|
|
done
|
|
else
|
|
add_all_modules '/crypto/'
|
|
fi
|
|
|
|
# (from 'net')
|
|
add_checked_modules '/drivers/net/'
|
|
|
|
|
|
## Binaries
|
|
# (from 'encrypt')
|
|
add_binary 'cryptsetup'
|
|
# cryptsetup calls pthread_create(), which dlopen()s libgcc_s.so.1
|
|
# Note: at least necessary for LUKS v2 volumes.
|
|
# Also see similar/related bug reports (e.g. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=950254).
|
|
add_binary '/usr/lib/libgcc_s.so.1'
|
|
|
|
# (from 'net')
|
|
add_binary '/usr/lib/initcpio/ipconfig' '/bin/ipconfig'
|
|
|
|
# (ours)
|
|
# Note: dmsetup is necessary for device mapper features
|
|
add_binary 'dmsetup'
|
|
add_binary 'dropbear'
|
|
add_binary 'ip'
|
|
add_binary 'ethtool'
|
|
|
|
|
|
## Other files
|
|
# (from 'encrypt')
|
|
# cryptsetup-related files
|
|
map add_udev_rule \
|
|
'10-dm.rules' \
|
|
'13-dm-disk.rules' \
|
|
'95-dm-notify.rules' \
|
|
'/usr/lib/initcpio/udev/11-dm-initramfs.rules'
|
|
|
|
# (ours)
|
|
# Our script and options
|
|
[ -e "${sshcs_env}" ] && add_file "${sshcs_env}"
|
|
# Note: use /usr/local/bin, even though everything actually points to /usr/bin
|
|
# in initramfs.
|
|
add_file '/usr/lib/initcpio/hooks/ssh-cryptsetup-tools' '/usr/local/bin/ssh-cryptsetup-tools'
|
|
|
|
# SSH-related files
|
|
add_file "${dropbear_authorized_keys}" '/root/.ssh/authorized_keys'
|
|
for keytype in "${dropbear_key_types[@]}"; do
|
|
add_file "${dropbear_keyfile_prefix}${keytype}${dropbear_keyfile_suffix}"
|
|
done
|
|
|
|
# crypt partitions
|
|
add_file "${etc_crypttab}"
|
|
|
|
add_runscript
|
|
}
|
|
|
|
help() {
|
|
cat <<EOF
|
|
This hook allows for LUKS encrypted devices to be unlocked either locally
|
|
(boot console) or remotely over SSH.
|
|
|
|
Network is configured with 'ip=' kernel parameter (see 'mkinitcpio-nfs-utils').
|
|
Authorized SSH key(s) must be present in '/etc/dropbear/initrd.authorized_keys'.
|
|
LUKS encrypted devices to unlock are derived from '/etc/crypttab', which must
|
|
be present.
|
|
Some options can be set in '/etc/initcpio/sshcs_env' (file is sourced in
|
|
initrd shell):
|
|
* 'sshcs_opt_debug': whether to be more verbose about ongoing actions
|
|
- default: '0'
|
|
- any non-zero value to enable
|
|
* 'sshcs_opt_net_wol': Wake-on-LAN option to set on network device
|
|
- default: 'g' (MagicPacket™)
|
|
- usually WOL is disabled once in initramfs shell
|
|
- set empty to not change network device WOL setting
|
|
* 'sshcs_opt_timeout_ipconfig': time (in seconds) to configure IP
|
|
- default: '10'
|
|
* 'sshcs_opt_listen': SSH listening port
|
|
- default: '22'
|
|
* 'sshcs_opt_timeout_poweroff': time (in seconds) to unlock devices before
|
|
automatic powering off
|
|
- default (and minimum value): '120' (2 minutes)
|
|
- negative value to deactivate
|
|
* 'sshcs_opt_use_shell': whether to start a full 'ash' shell
|
|
- default: '0'
|
|
- '1' to enable
|
|
- when disabled (the default), a script to unlock devices is executed instead
|
|
|
|
Each SSH server key ('dropbear_rsa_host_key', 'dropbear_ecdsa_host_key' and
|
|
'dropbear_ed25519_host_key' in '/etc/dropbear' folder) is imported from OpenSSH
|
|
if present or generated if missing. Fingerprints are displayed upon building
|
|
the initramfs image.
|
|
EOF
|
|
}
|