From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 222D8139085 for ; Sat, 7 Jan 2017 23:50:37 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 6B4E7E0C31; Sat, 7 Jan 2017 23:50:35 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 32D74E0C2A for ; Sat, 7 Jan 2017 23:50:35 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id BF76C3413C3 for ; Sat, 7 Jan 2017 23:50:33 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 285FB261F for ; Sat, 7 Jan 2017 23:50:32 +0000 (UTC) From: "Robin H. Johnson" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Robin H. Johnson" Message-ID: <1483832985.11a3470508a6475a5fee00f26ccbd7a98b4f9e01.robbat2@gentoo> Subject: [gentoo-commits] proj/genkernel:master commit in: /, defaults/ X-VCS-Repository: proj/genkernel X-VCS-Files: defaults/initrd.scripts defaults/login-remote.sh gen_initramfs.sh genkernel.conf X-VCS-Directories: defaults/ / X-VCS-Committer: robbat2 X-VCS-Committer-Name: Robin H. Johnson X-VCS-Revision: 11a3470508a6475a5fee00f26ccbd7a98b4f9e01 X-VCS-Branch: master Date: Sat, 7 Jan 2017 23:50:32 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 3c1226cb-a4ba-42a4-a266-f1f226c23186 X-Archives-Hash: 3c43845f0a7f62a1a999446f8a5b3fad commit: 11a3470508a6475a5fee00f26ccbd7a98b4f9e01 Author: Sebastian Bauer gmail com> AuthorDate: Thu Aug 21 21:19:16 2014 +0000 Commit: Robin H. Johnson gentoo org> CommitDate: Sat Jan 7 23:49:45 2017 +0000 URL: https://gitweb.gentoo.org/proj/genkernel.git/commit/?id=11a34705 FL-1476: Add support for remote decryption of luks devices via dropbear (cherry picked from commit 1886bbafecca1c225646e8d297bbb522caedfd9b) Closes: https://bugs.gentoo.org/show_bug.cgi?id=440126 Signed-off-by: Robin H. Johnson gentoo.org> defaults/initrd.scripts | 42 ++++++++++++++-- defaults/login-remote.sh | 127 +++++++++++++++++++++++++++++++++++++++++++++++ gen_initramfs.sh | 72 +++++++++++++++++++++++++++ genkernel.conf | 3 ++ 4 files changed, 241 insertions(+), 3 deletions(-) diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts index 1ee1699..17166e4 100644 --- a/defaults/initrd.scripts +++ b/defaults/initrd.scripts @@ -752,7 +752,7 @@ prompt_user(){ bad_msg '- type "shell" for a shell' bad_msg '- type "q" to skip...' printf "%s" "${2}(${oldvalue}) :: " - read ${1} + read -t 10 ${1} case `eval echo '$'${1}` in 'q') eval ${1}'='${oldvalue} @@ -1169,7 +1169,7 @@ openLUKS() { eval local LUKS_DEVICE='"${CRYPT_'${TYPE}'}"' LUKS_NAME="$1" LUKS_KEY='"${CRYPT_'${TYPE}'_KEY}"' LUKS_KEYDEV='"${CRYPT_'${TYPE}'_KEYDEV}"' LUKS_TRIM='"${CRYPT_'${TYPE}'_TRIM}"' local DEV_ERROR=0 KEY_ERROR=0 KEYDEV_ERROR=0 - local mntkey="/mnt/key/" cryptsetup_options='' + local mntkey="/mnt/key/" cryptsetup_options='' flag_opened="/${TYPE}.decrypted" [ ! -e /sbin/cryptsetup ] && bad_msg "The ramdisk does not support LUKS" && exit 1 while [ 1 ] @@ -1191,6 +1191,10 @@ openLUKS() { then prompt_user "LUKS_KEYDEV" "${LUKS_NAME} key device" KEYDEV_ERROR=0 + elif [ -e ${flag_opened} ] + then + good_msg "The LUKS device ${LUKS_DEVICE} meanwhile was opened by someone else." + break else LUKS_DEVICE=$(find_real_device "${LUKS_DEVICE}") @@ -1284,6 +1288,8 @@ openLUKS() { crypt_filter "${gpg_cmd}cryptsetup ${cryptsetup_options} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}" crypt_filter_ret=$? + touch ${flag_opened} + [ -e /dev/tty.org ] \ && rm -f /dev/tty \ && mv /dev/tty.org /dev/tty @@ -1307,7 +1313,12 @@ openLUKS() { startLUKS() { - # if key is set but key device isn't, find it + # if key is set but neither ssh enabled or key device is given, find + # the key device + + if [ -e "/usr/sbin/dropbear" ]; then + startdropbear + fi [ -n "${CRYPT_ROOT_KEY}" ] && [ -z "${CRYPT_ROOT_KEYDEV}" ] \ && sleep 6 && bootstrapKey "ROOT" @@ -1335,6 +1346,31 @@ startLUKS() { REAL_RESUME="/dev/mapper/swap" fi fi + + if [ -e "/usr/sbin/dropbear" ]; then + /bin/kill $(cat /var/run/dropbear.pid) + /sbin/ifconfig $(echo "${IP}" | awk -F":" '{print $6}' ) 0.0.0.0 + fi + + if [ -e /root.decrypted ]; then + rm /root.decrypted + fi + + if [ -e /swap.decrypted ]; then + rm /swap.decrypted + fi +} + +startdropbear() { + if [ "${IP}" == '' ] ; then + busybox udhcpc -n -T 15 -q + fi + + # setup environment variables for the ssh login shell + echo "CRYPT_ROOT=${CRYPT_ROOT}" > /etc/login-remote.conf + echo "CRYPT_SWAP=${CRYPT_SWAP}" >> /etc/login-remote.conf + touch /var/log/lastlog + /usr/sbin/dropbear } sdelay() { diff --git a/defaults/login-remote.sh b/defaults/login-remote.sh new file mode 100644 index 0000000..630d484 --- /dev/null +++ b/defaults/login-remote.sh @@ -0,0 +1,127 @@ +#!/bin/sh + +. /etc/login-remote.conf +. /etc/initrd.defaults +. /etc/initrd.scripts +KEYFILE_ROOT="/tmp/root.key" +KEYFILE_SWAP="/tmp/swap.key" + +splash() { + return 0 +} + +[ -e /etc/initrd.splash ] && . /etc/initrd.splash + +receivefile() { + case ${1} in + root) + file=${KEYFILE_ROOT} + ;; + swap) + file=${KEYFILE_SWAP} + ;; + esac + # limit maximum stored bytes to 1M to avoid killing the server + dd of=${file} count=1k bs=1k 2>/dev/null + exit $? +} + +openLUKSremote() { + case $1 in + root) + local TYPE=ROOT + ;; + swap) + local TYPE=SWAP + ;; + esac + + [ ! -d /tmp/key ] && mkdir -p /tmp/key + + eval local LUKS_DEVICE='"${CRYPT_'${TYPE}'}"' LUKS_NAME="$1" LUKS_KEY='"${KEYFILE_'${TYPE}'}"' + local DEV_ERROR=0 KEY_ERROR=0 + local input="" cryptsetup_options="" flag_opened="/${TYPE}.decrypted" + while [ 1 ] + do + local gpg_cmd="" crypt_filter_ret=42 + echo $- + sleep 1 + + if [ -e ${flag_opened} ] + then + good_msg "The LUKS device ${LUKS_DEVICE} meanwhile was opened by someone else." + break + elif [ ${DEV_ERROR} -eq 1 ] + then + prompt_user "LUKS_DEVICE" "${LUKS_NAME}" + DEV_ERROR=0 + else + LUKS_DEVICE=$(find_real_device "${LUKS_DEVICE}") + + setup_md_device ${LUKS_DEVICE} + cryptsetup isLuks ${LUKS_DEVICE} + if [ $? -ne 0 ] + then + bad_msg "The LUKS device ${LUKS_DEVICE} does not contain a LUKS header" ${CRYPT_SILENT} + DEV_ERROR=1 + continue + else + # Handle keys + if [ "x${LUKS_TRIM}" = "xyes" ] + then + good_msg "Enabling TRIM support for ${LUKS_NAME}." ${CRYPT_SILENT} + cryptsetup_options="${cryptsetup_options} --allow-discards" + fi + + if [ ${crypt_filter_ret} -ne 0 ] + then + # 1st try: unencrypted keyfile + crypt_filter "cryptsetup ${cryptsetup_options} --key-file ${LUKS_KEY} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}" + crypt_filter_ret=$? + + if [ ${crypt_filter_ret} -ne 0 ] + then + # 2nd try: gpg-encrypted keyfile + [ -e /dev/tty ] && mv /dev/tty /dev/tty.org + mknod /dev/tty c 5 1 + gpg_cmd="/sbin/gpg --logger-file /dev/null --quiet --decrypt ${LUKS_KEY} |" + crypt_filter "${gpg_cmd}cryptsetup ${cryptsetup_options} --key-file ${LUKS_KEY} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}" + crypt_filter_ret=$? + + [ -e /dev/tty.org ] \ + && rm -f /dev/tty \ + && mv /dev/tty.org /dev/tty + fi + fi + + if [ ${crypt_filter_ret} -eq 0 ] + then + touch ${flag_opened} + good_msg "LUKS device ${LUKS_DEVICE} opened" ${CRYPT_SILENT} + break + else + bad_msg "Failed to open LUKS device ${LUKS_DEVICE}" ${CRYPT_SILENT} + DEV_ERROR=1 + fi + fi + fi + done + rm -f ${LUKS_KEY} + cd / + rmdir -p tmp/key +} + +if [ "x${1}" = "x-c" ] +then + command=$(echo ${2} | awk -F" " '{print $1}') + type=$(echo ${2} | awk -F" " '{print $2}') + + case ${command} in + post) + receivefile ${type} + ;; + esac +else + [ -n "${CRYPT_ROOT}" ] && openLUKSremote root + [ -n "${CRYPT_SWAP}" ] && openLUKSremote swap +fi diff --git a/gen_initramfs.sh b/gen_initramfs.sh index 10108fb..e81b477 100755 --- a/gen_initramfs.sh +++ b/gen_initramfs.sh @@ -632,6 +632,77 @@ append_luks() { rm -r "${TEMP}/initramfs-luks-temp/" } +append_dropbear(){ + if [ -d "${TEMP}"/initramfs-dropbear-temp ] + then + rm -r "${TEMP}"/initramfs-dropbear-temp + fi + + if [ ! -d /etc/dropbear ] + then + mkdir /etc/dropbear + fi + if [ ! -e /etc/dropbear/dropbear_rsa_host_key ] + then + if [ -e /usr/bin/dropbearconvert -a /etc/ssh/ssh_host_rsa_key ] + then + /usr/bin/dropbearconvert openssh dropbear /etc/ssh/ssh_host_rsa_key /etc/dropbear/dropbear_rsa_host_key + else + /usr/bin/dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key -s 4096 > /dev/null + fi + fi + + if [ ! -e /etc/dropbear/dropbear_dss_host_key ] + then + /usr/bin/dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key > /dev/null + fi + + cd "${TEMP}" \ + || gen_die "cd '${TEMP}' failed" + mkdir -p ${TEMP}/initramfs-dropbear-temp/var/run + mkdir -p ${TEMP}/initramfs-dropbear-temp/var/log + mkdir -p ${TEMP}/initramfs-dropbear-temp/etc/dropbear + mkdir -p ${TEMP}/initramfs-dropbear-temp/bin + mkdir -p ${TEMP}/initramfs-dropbear-temp/root/.ssh + + cp -L ${GK_SHARE}/defaults/login-remote.sh ${TEMP}/initramfs-dropbear-temp/bin/ + cp -L /etc/dropbear/{dropbear_rsa_host_key,dropbear_dss_host_key} ${TEMP}/initramfs-dropbear-temp/etc/dropbear/ + cp -L /etc/dropbear/authorized_keys ${TEMP}/initramfs-dropbear-temp/root/.ssh + cp -L /etc/localtime ${TEMP}/initramfs-dropbear-temp/etc/ + if [ ${ARCH} = "x86_64" ] + then + mkdir -p ${TEMP}/initramfs-dropbear-temp/lib64 + cp -L /lib64/libnss_files.so.2 ${TEMP}/initramfs-dropbear-temp/lib64/ + else + mkdir -p ${TEMP}/initramfs-dropbear-temp/lib + cp -L /lib/libnss_files.so.2 ${TEMP}/initramfs-dropbear-temp/lib/ + fi + + sed "s/compat/files/g" /etc/nsswitch.conf > ${TEMP}/initramfs-dropbear-temp/etc/nsswitch.conf + echo "root:x:0:0:root:/root:/bin/login-remote.sh" > ${TEMP}/initramfs-dropbear-temp/etc/passwd + echo "/bin/login-remote.sh" > ${TEMP}/initramfs-dropbear-temp/etc/shells + echo "root:!:0:0:99999:7:::" > ${TEMP}/initramfs-dropbear-temp/etc/shadow + echo "root:x:0:root" > ${TEMP}/initramfs-dropbear-temp/etc/group + echo "" > ${TEMP}/initramfs-dropbear-temp/var/log/lastlog + + chmod 0755 ${TEMP}/initramfs-dropbear-temp/bin/login-remote.sh + chmod 0700 ${TEMP}/initramfs-dropbear-temp/root/.ssh + chmod 0640 ${TEMP}/initramfs-dropbear-temp/etc/shadow + chmod 0644 ${TEMP}/initramfs-dropbear-temp/etc/passwd + chmod 0644 ${TEMP}/initramfs-dropbear-temp/etc/group + mkfifo ${TEMP}/initramfs-dropbear-temp/etc/dropbear/fifo_root + mkfifo ${TEMP}/initramfs-dropbear-temp/etc/dropbear/fifo_swap + + copy_binaries "${TEMP}"/initramfs-dropbear-temp/ /usr/sbin/dropbear \ + /bin/login /usr/bin/passwd + + log_future_cpio_content + cd "${TEMP}"/initramfs-dropbear-temp \ + || gen_die "cd '${TEMP}/initramfs-dropbear-temp' failed" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + rm -rf "${TEMP}"/initramfs-dropbear-temp > /dev/null +} + append_firmware() { if [ -z "${FIRMWARE_FILES}" -a ! -d "${FIRMWARE_DIR}" ] then @@ -882,6 +953,7 @@ create_initramfs() { append_data 'iscsi' "${ISCSI}" append_data 'mdadm' "${MDADM}" append_data 'luks' "${LUKS}" + append_data 'dropbear' "${SSH}" append_data 'multipath' "${MULTIPATH}" append_data 'gpg' "${GPG}" diff --git a/genkernel.conf b/genkernel.conf index a95978d..d8f4ede 100644 --- a/genkernel.conf +++ b/genkernel.conf @@ -83,6 +83,9 @@ USECOLOR="yes" # Add DMRAID support. #DMRAID="no" +# Add SSH support. +#SSH="no" + # Include (or suppresses the inclusion of) busybox in the initrd or initramfs. # If included, busybox is rebuilt if the cached copy is out of date. #BUSYBOX="yes"