3 Commits
0.2-1 ... 0.4-1

Author SHA1 Message Date
Julien Coloos
e5ee05f382 Fixed TRIM option handling in /etc/crypttab
'discard' ('allow-discards' being the switch name to use in cryptsetup)

v0.4-1
2017-06-25 18:22:53 +02:00
Julien Coloos
cf6ccb2d23 Updated changelog 2015-11-22 19:05:58 +01:00
Julien Coloos
724d6a6bf0 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-1
2015-11-22 18:54:57 +01:00
6 changed files with 127 additions and 67 deletions

View File

@@ -1,19 +1,32 @@
2017-06-25 Julien Coloos <julien.coloos [at] gmail [dot] com>
* v0.4-1
Fixed TRIM option handling in /etc/crypttab: 'discard' ('allow-discards' being the switch name to use in cryptsetup)
2015-11-22 Julien Coloos <julien.coloos [at] gmail [dot] com>
* v0.3-1
Added configurable timeout for ipconfig
Moved configuration file from /etc/dropbear/initrd.env to /etc/initcpio/sshcs_env
2014-05-20 Julien Coloos <julien.coloos [at] gmail [dot] com>
* v0.2-1
Removed unnecessary dependency: psmisc
Added configurable timeout to unlock devices before automatic poweroff
* v0.2-1
Removed unnecessary dependency: psmisc
Added configurable timeout to unlock devices before automatic poweroff
2014-05-19 Julien Coloos <julien.coloos [at] gmail [dot] com>
* v0.1-1
* v0.1-1
* Code adapted from dropbear_initrd_encrypt (https://aur.archlinux.org/packages/dropbear_initrd_encrypt/)
Reworked code
Dropped non-LUKS support
Rely on /etc/crypttab
Handle multiple devices to unlock
Merged dropbear and encryptssh hooks
Better resources cleanup
* Code adapted from dropbear_initrd_encrypt (https://aur.archlinux.org/packages/dropbear_initrd_encrypt/)
Reworked code
Dropped non-LUKS support
Rely on /etc/crypttab
Handle multiple devices to unlock
Merged dropbear and encryptssh hooks
Better resources cleanup

View File

@@ -1,6 +1,6 @@
# Maintainer: Julien Coloos <julien.coloos [at] gmail [dot] com>
pkgname=initrd-ssh-cryptsetup
pkgver=0.2
pkgver=0.4
pkgrel=1
pkgdesc="Allows for LUKS-encrypted devices to be unlocked remotely over SSH"
arch=('any')
@@ -10,8 +10,8 @@ depends=('dropbear' 'cryptsetup' 'mkinitcpio-nfs-utils' 'iproute2')
install=$pkgname.install
changelog='ChangeLog'
source=("http://julien.coloos.free.fr/archlinux/$pkgname-$pkgver.tar.xz" "$pkgname.install")
md5sums=('27b040fd69d252050c20a2595f8c67ba'
'a703663472bbd50882a11f6b2cfccbf0')
md5sums=('fab9d0ffc14a6cd7bcb79fa1b9411336'
'ac60109d80e7bb2af0d66e69aaf178a6')
package() {
install -Dm644 "$srcdir/src/install/ssh-cryptsetup" "$pkgdir/usr/lib/initcpio/install/ssh-cryptsetup"

View File

@@ -8,22 +8,35 @@ After cloning the repo, installation is done as for an AUR package.
## Configuration
As explained upon installation, the following things need to be done:
* add the SSH public key to `/etc/dropbear/initrd.authorized_keys`
* add the `ip=` kernel command parameter to the bootloader configuration (see https://wiki.archlinux.org/index.php/Mkinitcpio#Using_net)
* in the `HOOKS` section of `/etc/mkinitcpio.conf`, add `ssh-cryptsetup` before `filesystems`; then rebuild the initramfs: `mkinitcpio -p linux`
* add the SSH public key to `/etc/dropbear/initrd.authorized_keys`
* add the `ip=` kernel command parameter to the bootloader configuration (see https://wiki.archlinux.org/index.php/Mkinitcpio#Using_net)
* in the `HOOKS` section of `/etc/mkinitcpio.conf`, add `ssh-cryptsetup` before `filesystems`; then rebuild the initramfs: `mkinitcpio -p linux`
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):
* `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): 2 minutes
- negative value to deactivate
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
- default: 22
* `sshcs_opt_timeout_poweroff`: time (in seconds) to unlock devices before automatic powering off
- default (and minimum value): 2 minutes
- negative value to deactivate
For example:
sshcs_opt_timeout_ipconfig=30
sshcs_opt_listen=2222
sshcs_opt_timeout_poweroff=-1
## Building notes
1. Modify the sources (features in `src`, and/or package building files)
2. If `src` was modified
* archive the `src` folder in `$pkgname-$pkgver.tar.xz` file; e.g.: `tar -cJf initrd-ssh-cryptsetup-0.4.tar.xz src`
* upload the archive on the online repository (pointed by `PKGBUILD`)
3. Update `PKGBUILD`
* bump `pkgver` if `src` was modified, or `pkgrel` if building files were modified
* refresh `md5sums` if necessary (based on `md5sum initrd-ssh-cryptsetup-*.tar.xz initrd-ssh-cryptsetup.install` output)
4. Delete generated archive file if any

View File

@@ -1,8 +1,17 @@
#!/bin/bash
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 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}"
[ -e "${dropbear_authorized_keys}" ] || touch "${dropbear_authorized_keys}"
chmod 600 "${dropbear_authorized_keys}"

View File

@@ -1,5 +1,16 @@
#!/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() {
# we must have an 'ip' setting, and a device in it
[ -z "${ip}" ] && [ -n "${nfsaddrs}" ] && ip="${nfsaddrs}"
@@ -14,7 +25,16 @@ sshcs_net_start() {
# temporary file and 'source' it since '... | while read ...' spawns a
# subshell from which outer variables cannot be altered.
: > "${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="$(echo "${line}" | sed -e 's/ :/:/g;s/: /=/g')"
@@ -36,6 +56,14 @@ sshcs_net_start() {
[ -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() {
err "Timeout reached! Powering off."
poweroff -f
@@ -68,8 +96,16 @@ sshcs_untrap_timeout() {
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() {
local timeout_poweroff_min=120
local pid_timeout=
local dev_pts_mounted=0
local listen=
@@ -91,14 +127,14 @@ sshcs_dropbear_unlock() {
. "/init_functions"
if [ ! -f "${dropbear_cryptsetup_script}" ]; then
if [ ! -f "${sshcs_cryptsetup_script}" ]; then
err "No cryptsetup script present! Please retry."
exit 0
fi
if [ -c "/dev/mapper/control" ]; then
CSQUIET=
. "${dropbear_cryptsetup_script}"
. "${sshcs_cryptsetup_script}"
echo ""
echo "cryptsetup succeeded! Boot sequence should go on."
@@ -113,21 +149,11 @@ EOF
[ ! -d "/var/log" ] && mkdir -p "/var/log"
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 ..."
dropbear -Emsgjk -P "${path_dropbear_pid}" ${sshcs_opt_listen}
sshcs_trap_timeout
# actual script (shared with SSH login) unlocking encrypted devices
. "${dropbear_cryptsetup_script}"
sshcs_untrap_timeout
# Actual unlocking
sshcs_unlock
# cleanup dropbear
if [ -f "${path_dropbear_pid}" ]; then
@@ -135,7 +161,7 @@ EOF
kill $(cat "${path_dropbear_pid}")
rm -f "${path_dropbear_pid}"
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
if [ ${dev_pts_mounted} -ne 0 ]; then
@@ -144,14 +170,6 @@ EOF
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() {
# ensure there is a device (handle 'UUID=' format)
[ -z "${cryptdev}" ] && return 0
@@ -161,7 +179,7 @@ sshcs_cryptpart_process() {
cryptargs=
for cryptopt in ${cryptoptions//,/ }; do
case ${cryptopt} in
allow-discards)
discard)
cryptargs="${cryptargs} --allow-discards"
;;
@@ -180,7 +198,7 @@ sshcs_cryptpart_process() {
if cryptsetup isLuks "${cryptdev}" >/dev/null 2>&1; then
# 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() {
local res
@@ -194,7 +212,7 @@ cycle_or_retry() {
}
EOF
cat <<EOF >> "${dropbear_cryptsetup_script}"
cat <<EOF >> "${sshcs_cryptsetup_script}"
# loop until device is available
while [ ! -e "/dev/mapper/${cryptname}" ]; do
if cryptsetup open --type "${crypttype}" "${cryptdev}" "${cryptname}" "${cryptargs}" "\${CSQUIET}"; then
@@ -220,14 +238,17 @@ EOF
run_hook() {
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 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 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
# Load our options
sshcs_env_load
# sanity check: crypttab should be present
[ ! -e "${etc_crypttab}" ] && return 0
@@ -236,14 +257,6 @@ run_hook() {
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
cryptdev=
crypttype=luks
@@ -256,9 +269,17 @@ run_hook() {
sshcs_cryptpart_process
done < "${etc_crypttab}"
if [ ! -e "${dropbear_cryptsetup_script}" ]; then
if [ ! -e "${sshcs_cryptsetup_script}" ]; then
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
return 0
fi

View File

@@ -31,7 +31,7 @@ sshcs_check_keys() {
build() {
local etc_crypttab="/etc/crypttab"
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_keyfile_prefix="/etc/dropbear/dropbear_"
local dropbear_keyfile_suffix="_host_key"
@@ -71,12 +71,14 @@ build() {
add_binary "ip"
add_binary "/usr/lib/initcpio/ipconfig" "/sbin/ipconfig"
# Our hook files
[ -e "${sshcs_env}" ] && add_file "${sshcs_env}"
# auth-related files
add_file "/lib/libnss_files.so"
# SSH-related files
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_dss_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'.
LUKS encrypted devices to unlock are derived from '/etc/crypttab', which must
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):
* 'sshcs_opt_timeout_ipconfig': time (s) to configure IP
- default: 10 seconds
* 'sshcs_opt_listen': listening port (22 by default)
* 'sshcs_opt_timeout_poweroff': time (s) to unlock devices before automatic
powering off