Handle optional ipconfig timeout
Specify timeout for ipconfig so that we can still boot while network is done. Otherwise ipconfig remains stuck (until IP can be configured). If not given we default to 10s. Minor code refactoring. Moved configuration file from /etc/dropbear/initrd.env to /etc/initcpio/sshcs_env since it now contains options for ipconfig and not only dropbear. Package installation script move legacy file to new path if present. v0.3-1master
parent
b61e50ebe8
commit
724d6a6bf0
6
PKGBUILD
6
PKGBUILD
|
@ -1,6 +1,6 @@
|
||||||
# Maintainer: Julien Coloos <julien.coloos [at] gmail [dot] com>
|
# Maintainer: Julien Coloos <julien.coloos [at] gmail [dot] com>
|
||||||
pkgname=initrd-ssh-cryptsetup
|
pkgname=initrd-ssh-cryptsetup
|
||||||
pkgver=0.2
|
pkgver=0.3
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Allows for LUKS-encrypted devices to be unlocked remotely over SSH"
|
pkgdesc="Allows for LUKS-encrypted devices to be unlocked remotely over SSH"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
|
@ -10,8 +10,8 @@ depends=('dropbear' 'cryptsetup' 'mkinitcpio-nfs-utils' 'iproute2')
|
||||||
install=$pkgname.install
|
install=$pkgname.install
|
||||||
changelog='ChangeLog'
|
changelog='ChangeLog'
|
||||||
source=("http://julien.coloos.free.fr/archlinux/$pkgname-$pkgver.tar.xz" "$pkgname.install")
|
source=("http://julien.coloos.free.fr/archlinux/$pkgname-$pkgver.tar.xz" "$pkgname.install")
|
||||||
md5sums=('27b040fd69d252050c20a2595f8c67ba'
|
md5sums=('a25dbbac5cd82a8d87932e646e38d9c4'
|
||||||
'a703663472bbd50882a11f6b2cfccbf0')
|
'ac60109d80e7bb2af0d66e69aaf178a6')
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
install -Dm644 "$srcdir/src/install/ssh-cryptsetup" "$pkgdir/usr/lib/initcpio/install/ssh-cryptsetup"
|
install -Dm644 "$srcdir/src/install/ssh-cryptsetup" "$pkgdir/usr/lib/initcpio/install/ssh-cryptsetup"
|
||||||
|
|
|
@ -15,7 +15,9 @@ As explained upon installation, the following things need to be done:
|
||||||
The LUKS-encrypted devices to unlock are derived from `/etc/crypttab`.
|
The LUKS-encrypted devices to unlock are derived from `/etc/crypttab`.
|
||||||
|
|
||||||
|
|
||||||
Some options can be set in `/etc/dropbear/initrd.env` (file is sourced in initrd shell):
|
Some options can be set in `/etc/initcpio/sshcs_env` (file is sourced in initrd shell):
|
||||||
|
* `sshcs_opt_timeout_ipconfig`: time (in seconds) to configure IP
|
||||||
|
- default: 10 seconds
|
||||||
* `sshcs_opt_listen`: SSH listening port
|
* `sshcs_opt_listen`: SSH listening port
|
||||||
- default: 22
|
- default: 22
|
||||||
* `sshcs_opt_timeout_poweroff`: time (in seconds) to unlock devices before automatic powering off
|
* `sshcs_opt_timeout_poweroff`: time (in seconds) to unlock devices before automatic powering off
|
||||||
|
@ -24,6 +26,7 @@ Some options can be set in `/etc/dropbear/initrd.env` (file is sourced in initrd
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
|
sshcs_opt_timeout_ipconfig=30
|
||||||
sshcs_opt_listen=2222
|
sshcs_opt_listen=2222
|
||||||
sshcs_opt_timeout_poweroff=-1
|
sshcs_opt_timeout_poweroff=-1
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,17 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
post_install() {
|
post_install() {
|
||||||
|
local sshcs_env="/etc/initcpio/sshcs_env"
|
||||||
|
local sshcs_env_old="/etc/dropbear/initrd.env"
|
||||||
local dropbear_authorized_keys="/etc/dropbear/initrd.authorized_keys"
|
local dropbear_authorized_keys="/etc/dropbear/initrd.authorized_keys"
|
||||||
local etc_dropbear=$(dirname "${dropbear_authorized_keys}")
|
local etc_dropbear=$(dirname "${dropbear_authorized_keys}")
|
||||||
|
[ ! -e "${sshcs_env}" ] && [ -e "${sshcs_env_old}" ] && {
|
||||||
|
[ -d $(dirname "${sshcs_env}") ] || mkdir -p $(dirname "${sshcs_env}")
|
||||||
|
mv "${sshcs_env_old}" "${sshcs_env}"
|
||||||
|
cat <<EOF
|
||||||
|
Moved legacy file ${sshcs_env_old} to new path ${sshcs_env}"
|
||||||
|
EOF
|
||||||
|
}
|
||||||
[ -d "${etc_dropbear}" ] || mkdir -p "${etc_dropbear}"
|
[ -d "${etc_dropbear}" ] || mkdir -p "${etc_dropbear}"
|
||||||
[ -e "${dropbear_authorized_keys}" ] || touch "${dropbear_authorized_keys}"
|
[ -e "${dropbear_authorized_keys}" ] || touch "${dropbear_authorized_keys}"
|
||||||
chmod 600 "${dropbear_authorized_keys}"
|
chmod 600 "${dropbear_authorized_keys}"
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
#!/usr/bin/ash
|
#!/usr/bin/ash
|
||||||
|
|
||||||
|
sshcs_env_load() {
|
||||||
|
local timeout_ipconfig_default=10
|
||||||
|
local timeout_poweroff_min=120
|
||||||
|
|
||||||
|
[ -e "${sshcs_env}" ] && . "${sshcs_env}"
|
||||||
|
[ -z "${sshcs_opt_timeout_ipconfig}" ] && sshcs_opt_timeout_ipconfig=${timeout_ipconfig_default}
|
||||||
|
[ -n "${sshcs_opt_listen}" ] && sshcs_opt_listen="-p ${sshcs_opt_listen}"
|
||||||
|
[ -z "${sshcs_opt_timeout_poweroff}" ] && sshcs_opt_timeout_poweroff=${timeout_poweroff_min}
|
||||||
|
[ ${sshcs_opt_timeout_poweroff} -ge 0 ] && [ ${sshcs_opt_timeout_poweroff} -lt ${timeout_poweroff_min} ] && sshcs_opt_timeout_poweroff=${timeout_poweroff_min}
|
||||||
|
}
|
||||||
|
|
||||||
sshcs_net_start() {
|
sshcs_net_start() {
|
||||||
# we must have an 'ip' setting, and a device in it
|
# we must have an 'ip' setting, and a device in it
|
||||||
[ -z "${ip}" ] && [ -n "${nfsaddrs}" ] && ip="${nfsaddrs}"
|
[ -z "${ip}" ] && [ -n "${nfsaddrs}" ] && ip="${nfsaddrs}"
|
||||||
|
@ -14,7 +25,16 @@ sshcs_net_start() {
|
||||||
# temporary file and 'source' it since '... | while read ...' spawns a
|
# temporary file and 'source' it since '... | while read ...' spawns a
|
||||||
# subshell from which outer variables cannot be altered.
|
# subshell from which outer variables cannot be altered.
|
||||||
: > "${net_env}"
|
: > "${net_env}"
|
||||||
ipconfig "ip=${ip}" | while read line; do
|
|
||||||
|
echo ""
|
||||||
|
echo "Configuring IP (timeout = ${sshcs_opt_timeout_ipconfig}s) ..."
|
||||||
|
ipconfig_out=$(ipconfig -t "${sshcs_opt_timeout_ipconfig}" "ip=${ip}")
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
err "IP configuration timeout!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "${ipconfig_out}" | while read line; do
|
||||||
[ "${line#"IP-Config:"}" != "${line}" ] && continue
|
[ "${line#"IP-Config:"}" != "${line}" ] && continue
|
||||||
|
|
||||||
line="$(echo "${line}" | sed -e 's/ :/:/g;s/: /=/g')"
|
line="$(echo "${line}" | sed -e 's/ :/:/g;s/: /=/g')"
|
||||||
|
@ -36,6 +56,14 @@ sshcs_net_start() {
|
||||||
[ -n "${net_address}" ]
|
[ -n "${net_address}" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sshcs_net_done() {
|
||||||
|
# we are done with the network
|
||||||
|
if [ -n "${net_device}" ]; then
|
||||||
|
ip addr flush dev "${net_device}"
|
||||||
|
ip link set dev "${net_device}" down
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
sshcs_trapped_timeout() {
|
sshcs_trapped_timeout() {
|
||||||
err "Timeout reached! Powering off."
|
err "Timeout reached! Powering off."
|
||||||
poweroff -f
|
poweroff -f
|
||||||
|
@ -68,8 +96,16 @@ sshcs_untrap_timeout() {
|
||||||
msg "Timeout cleared."
|
msg "Timeout cleared."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sshcs_unlock() {
|
||||||
|
sshcs_trap_timeout
|
||||||
|
|
||||||
|
# actual script (shared with SSH login) unlocking encrypted devices
|
||||||
|
. "${sshcs_cryptsetup_script}"
|
||||||
|
|
||||||
|
sshcs_untrap_timeout
|
||||||
|
}
|
||||||
|
|
||||||
sshcs_dropbear_unlock() {
|
sshcs_dropbear_unlock() {
|
||||||
local timeout_poweroff_min=120
|
|
||||||
local pid_timeout=
|
local pid_timeout=
|
||||||
local dev_pts_mounted=0
|
local dev_pts_mounted=0
|
||||||
local listen=
|
local listen=
|
||||||
|
@ -91,14 +127,14 @@ sshcs_dropbear_unlock() {
|
||||||
|
|
||||||
. "/init_functions"
|
. "/init_functions"
|
||||||
|
|
||||||
if [ ! -f "${dropbear_cryptsetup_script}" ]; then
|
if [ ! -f "${sshcs_cryptsetup_script}" ]; then
|
||||||
err "No cryptsetup script present! Please retry."
|
err "No cryptsetup script present! Please retry."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -c "/dev/mapper/control" ]; then
|
if [ -c "/dev/mapper/control" ]; then
|
||||||
CSQUIET=
|
CSQUIET=
|
||||||
. "${dropbear_cryptsetup_script}"
|
. "${sshcs_cryptsetup_script}"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "cryptsetup succeeded! Boot sequence should go on."
|
echo "cryptsetup succeeded! Boot sequence should go on."
|
||||||
|
@ -113,21 +149,11 @@ EOF
|
||||||
[ ! -d "/var/log" ] && mkdir -p "/var/log"
|
[ ! -d "/var/log" ] && mkdir -p "/var/log"
|
||||||
touch "/var/log/lastlog"
|
touch "/var/log/lastlog"
|
||||||
|
|
||||||
[ -e "${dropbear_env}" ] && . "${dropbear_env}"
|
|
||||||
[ -n "${sshcs_opt_listen}" ] && sshcs_opt_listen="-p ${sshcs_opt_listen}"
|
|
||||||
[ -z "${sshcs_opt_timeout_poweroff}" ] && sshcs_opt_timeout_poweroff=${timeout_poweroff_min}
|
|
||||||
[ ${sshcs_opt_timeout_poweroff} -ge 0 ] && [ ${sshcs_opt_timeout_poweroff} -lt ${timeout_poweroff_min} ] && sshcs_opt_timeout_poweroff=${timeout_poweroff_min}
|
|
||||||
|
|
||||||
|
|
||||||
msg "Starting dropbear ..."
|
msg "Starting dropbear ..."
|
||||||
dropbear -Emsgjk -P "${path_dropbear_pid}" ${sshcs_opt_listen}
|
dropbear -Emsgjk -P "${path_dropbear_pid}" ${sshcs_opt_listen}
|
||||||
|
|
||||||
sshcs_trap_timeout
|
# Actual unlocking
|
||||||
|
sshcs_unlock
|
||||||
# actual script (shared with SSH login) unlocking encrypted devices
|
|
||||||
. "${dropbear_cryptsetup_script}"
|
|
||||||
|
|
||||||
sshcs_untrap_timeout
|
|
||||||
|
|
||||||
# cleanup dropbear
|
# cleanup dropbear
|
||||||
if [ -f "${path_dropbear_pid}" ]; then
|
if [ -f "${path_dropbear_pid}" ]; then
|
||||||
|
@ -135,7 +161,7 @@ EOF
|
||||||
kill $(cat "${path_dropbear_pid}")
|
kill $(cat "${path_dropbear_pid}")
|
||||||
rm -f "${path_dropbear_pid}"
|
rm -f "${path_dropbear_pid}"
|
||||||
fi
|
fi
|
||||||
rm -f "${dropbear_cryptsetup_script}" "${dropbear_login_shell}" "/etc/passwd" "/etc/shells" "/var/log/lastlog"
|
rm -f "${sshcs_cryptsetup_script}" "${dropbear_login_shell}" "/etc/passwd" "/etc/shells" "/var/log/lastlog"
|
||||||
|
|
||||||
# cleanup /dev/pts if necessary
|
# cleanup /dev/pts if necessary
|
||||||
if [ ${dev_pts_mounted} -ne 0 ]; then
|
if [ ${dev_pts_mounted} -ne 0 ]; then
|
||||||
|
@ -144,14 +170,6 @@ EOF
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
sshcs_net_done() {
|
|
||||||
# we are done with the network
|
|
||||||
if [ -n "${net_device}" ]; then
|
|
||||||
ip addr flush dev "${net_device}"
|
|
||||||
ip link set dev "${net_device}" down
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
sshcs_cryptpart_process() {
|
sshcs_cryptpart_process() {
|
||||||
# ensure there is a device (handle 'UUID=' format)
|
# ensure there is a device (handle 'UUID=' format)
|
||||||
[ -z "${cryptdev}" ] && return 0
|
[ -z "${cryptdev}" ] && return 0
|
||||||
|
@ -180,7 +198,7 @@ sshcs_cryptpart_process() {
|
||||||
if cryptsetup isLuks "${cryptdev}" >/dev/null 2>&1; then
|
if cryptsetup isLuks "${cryptdev}" >/dev/null 2>&1; then
|
||||||
|
|
||||||
# update script used to unlock device either in console or SSH
|
# update script used to unlock device either in console or SSH
|
||||||
[ -s "${dropbear_cryptsetup_script}" ] || cat <<EOF > "${dropbear_cryptsetup_script}"
|
[ -s "${sshcs_cryptsetup_script}" ] || cat <<EOF > "${sshcs_cryptsetup_script}"
|
||||||
cycle_or_retry() {
|
cycle_or_retry() {
|
||||||
local res
|
local res
|
||||||
|
|
||||||
|
@ -194,7 +212,7 @@ cycle_or_retry() {
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat <<EOF >> "${dropbear_cryptsetup_script}"
|
cat <<EOF >> "${sshcs_cryptsetup_script}"
|
||||||
# loop until device is available
|
# loop until device is available
|
||||||
while [ ! -e "/dev/mapper/${cryptname}" ]; do
|
while [ ! -e "/dev/mapper/${cryptname}" ]; do
|
||||||
if cryptsetup open --type "${crypttype}" "${cryptdev}" "${cryptname}" "${cryptargs}" "\${CSQUIET}"; then
|
if cryptsetup open --type "${crypttype}" "${cryptdev}" "${cryptname}" "${cryptargs}" "\${CSQUIET}"; then
|
||||||
|
@ -220,14 +238,17 @@ EOF
|
||||||
|
|
||||||
run_hook() {
|
run_hook() {
|
||||||
local etc_crypttab="/etc/crypttab"
|
local etc_crypttab="/etc/crypttab"
|
||||||
local dropbear_env="/etc/dropbear/initrd.env"
|
local sshcs_env="/etc/initcpio/sshcs_env"
|
||||||
local path_dropbear_pid="/.dropbear.pid"
|
local path_dropbear_pid="/.dropbear.pid"
|
||||||
local dropbear_login_shell="/.cryptsetup_shell.sh"
|
local dropbear_login_shell="/.cryptsetup_shell.sh"
|
||||||
local dropbear_cryptsetup_script="/.cryptsetup_script.sh"
|
local sshcs_cryptsetup_script="/.cryptsetup_script.sh"
|
||||||
local net_env="/.net_env.sh"
|
local net_env="/.net_env.sh"
|
||||||
local line iparg net_address net_netmask net_gateway net_dns0 net_dns1
|
local line iparg net_address net_device ipconfig_out net_netmask net_gateway net_dns0 net_dns1
|
||||||
local cryptdev cryptdev_orig crypttype cryptname cryptpass cryptoptions cryptopt cryptargs CSQUIET
|
local cryptdev cryptdev_orig crypttype cryptname cryptpass cryptoptions cryptopt cryptargs CSQUIET
|
||||||
|
|
||||||
|
# Load our options
|
||||||
|
sshcs_env_load
|
||||||
|
|
||||||
# sanity check: crypttab should be present
|
# sanity check: crypttab should be present
|
||||||
[ ! -e "${etc_crypttab}" ] && return 0
|
[ ! -e "${etc_crypttab}" ] && return 0
|
||||||
|
|
||||||
|
@ -236,14 +257,6 @@ run_hook() {
|
||||||
|
|
||||||
umask 0022
|
umask 0022
|
||||||
|
|
||||||
# start and check network
|
|
||||||
if ! sshcs_net_start; then
|
|
||||||
err "Net interface not available! Skipping crypt remote unlocking."
|
|
||||||
# stop the network if possible
|
|
||||||
sshcs_net_done
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check encrypted devices to handle
|
# check encrypted devices to handle
|
||||||
cryptdev=
|
cryptdev=
|
||||||
crypttype=luks
|
crypttype=luks
|
||||||
|
@ -256,9 +269,17 @@ run_hook() {
|
||||||
sshcs_cryptpart_process
|
sshcs_cryptpart_process
|
||||||
done < "${etc_crypttab}"
|
done < "${etc_crypttab}"
|
||||||
|
|
||||||
if [ ! -e "${dropbear_cryptsetup_script}" ]; then
|
if [ ! -e "${sshcs_cryptsetup_script}" ]; then
|
||||||
err "No encrypted device found! Skipping crypt remote unlocking."
|
err "No encrypted device found! Skipping crypt remote unlocking."
|
||||||
# don't forget to stop the network
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# start and check network
|
||||||
|
if ! sshcs_net_start; then
|
||||||
|
err "Net interface not available! Skipping crypt remote unlocking."
|
||||||
|
# We still allow to unlock locally with timeout
|
||||||
|
sshcs_unlock
|
||||||
|
# stop the network if possible
|
||||||
sshcs_net_done
|
sshcs_net_done
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -31,7 +31,7 @@ sshcs_check_keys() {
|
||||||
build() {
|
build() {
|
||||||
local etc_crypttab="/etc/crypttab"
|
local etc_crypttab="/etc/crypttab"
|
||||||
local dropbear_authorized_keys="/etc/dropbear/initrd.authorized_keys"
|
local dropbear_authorized_keys="/etc/dropbear/initrd.authorized_keys"
|
||||||
local dropbear_env="/etc/dropbear/initrd.env"
|
local sshcs_env="/etc/initcpio/sshcs_env"
|
||||||
local dropbear_key_types=( "dss" "rsa" "ecdsa" )
|
local dropbear_key_types=( "dss" "rsa" "ecdsa" )
|
||||||
local dropbear_keyfile_prefix="/etc/dropbear/dropbear_"
|
local dropbear_keyfile_prefix="/etc/dropbear/dropbear_"
|
||||||
local dropbear_keyfile_suffix="_host_key"
|
local dropbear_keyfile_suffix="_host_key"
|
||||||
|
@ -71,12 +71,14 @@ build() {
|
||||||
add_binary "ip"
|
add_binary "ip"
|
||||||
add_binary "/usr/lib/initcpio/ipconfig" "/sbin/ipconfig"
|
add_binary "/usr/lib/initcpio/ipconfig" "/sbin/ipconfig"
|
||||||
|
|
||||||
|
# Our hook files
|
||||||
|
[ -e "${sshcs_env}" ] && add_file "${sshcs_env}"
|
||||||
|
|
||||||
# auth-related files
|
# auth-related files
|
||||||
add_file "/lib/libnss_files.so"
|
add_file "/lib/libnss_files.so"
|
||||||
|
|
||||||
# SSH-related files
|
# SSH-related files
|
||||||
add_file "${dropbear_authorized_keys}" "/root/.ssh/authorized_keys"
|
add_file "${dropbear_authorized_keys}" "/root/.ssh/authorized_keys"
|
||||||
[ -e "${dropbear_env}" ] && add_file "${dropbear_env}"
|
|
||||||
add_file "/etc/dropbear/dropbear_rsa_host_key"
|
add_file "/etc/dropbear/dropbear_rsa_host_key"
|
||||||
add_file "/etc/dropbear/dropbear_dss_host_key"
|
add_file "/etc/dropbear/dropbear_dss_host_key"
|
||||||
add_file "/etc/dropbear/dropbear_ecdsa_host_key"
|
add_file "/etc/dropbear/dropbear_ecdsa_host_key"
|
||||||
|
@ -101,8 +103,10 @@ Network is configured with 'ip=' kernel parameter (see 'mkinitcpio-nfs-utils').
|
||||||
Authorized SSH key(s) must be present in '/etc/dropbear/initrd.authorized_keys'.
|
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
|
LUKS encrypted devices to unlock are derived from '/etc/crypttab', which must
|
||||||
be present.
|
be present.
|
||||||
Some options can be set in '/etc/dropbear/initrd.env' (file is sourced in
|
Some options can be set in '/etc/initcpio/sshcs_env' (file is sourced in
|
||||||
initrd shell):
|
initrd shell):
|
||||||
|
* 'sshcs_opt_timeout_ipconfig': time (s) to configure IP
|
||||||
|
- default: 10 seconds
|
||||||
* 'sshcs_opt_listen': listening port (22 by default)
|
* 'sshcs_opt_listen': listening port (22 by default)
|
||||||
* 'sshcs_opt_timeout_poweroff': time (s) to unlock devices before automatic
|
* 'sshcs_opt_timeout_poweroff': time (s) to unlock devices before automatic
|
||||||
powering off
|
powering off
|
||||||
|
|
Loading…
Reference in New Issue