dracut
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
shimunn 2019-09-17 16:14:12 +02:00
parent ff80242e9d
commit cdcc04a5fa
Signed by: shimun
GPG Key ID: E81D8382DC2F971B
4 changed files with 328 additions and 0 deletions

22
dracut/Makefile Normal file
View File

@ -0,0 +1,22 @@
.PHONY: install
DRACUT_MODULE_D=/usr/lib/dracut/modules.d/95fido2luks
DRACUT_CONF_D=/etc/dracut.conf.d
build:
cargo install --root . --path ../ --force
rm -f .crates.toml
install: build
mkdir -p ${DRACUT_MODULE_D}
cp bin/* /usr/local/bin/
cp module-setup.sh ykluks.sh bin/* ${DRACUT_MODULE_D}/
chown -R root: ${DRACUT_MODULE_D}/
setup: install
bin/fido2luks setup
cp fido2luks.json /etc/fido2luks.json
clean:
cargo clean
rm -rf bin fido2luks.json
uninstall:
rm -rf /etc/fido2luks.json ${DRACUT_CONF_D}/fido2luks.conf ${DRACUT_MODULES_D}/95fido2luks

112
dracut/README.md Normal file
View File

@ -0,0 +1,112 @@
# ykluks
Dracut module to use yubikey in challenge/response mode to unlock LUKS partition.
This module is written to work with Qubes OS 3.2. It may work with other dracut
based distributions but there are other more complete tools you may want to try
(e.g. https://github.com/bpereto/ykfde).
For ubuntu based distributions you may want to try this one: https://github.com/cornelinux/yubikey-luks
WARNING
-------
Please note that the current version is tested with a LVM-on-LUKS setup only. The default Qubes OS installation
is a LUKS-on-LVM setup which will not work yet. Patches for LUKS-on-LVM are welcome as well as experienced testers
because a dont have a LUKS-on-LVM installation to test with.
Initialize Yubikey
------------------
Install yubikey tools.
qubes-dom0-update ykpers
Initialize the Yubikey for challenge/response in slot 2.
ykpersonalize -2 -ochal-resp -ochal-hmac -ohmac-lt64 -oserial-api-visible
Add luks slot
-------------
You need to manually add a new luks slot with the response you get when sending your
password to the yubikey.
Get response from yubikey.
ykchalresp -2 mypassword
You may want to check which LUKS key slots are currently used. Make sure you use the correct device file.
This may help if you want to replace your current password with a more secure backup password later.
sudo cryptsetup LuksDump /dev/sdXX
Use the output from the previous command as new passphrase.
sudo cryptsetup luksAddKey --key-slot a_free_key_slot /dev/sdXX
Install ykluks
--------------
To get the ykluks archive to dom0 you can run the following command where downloadvm is the VM you want to use for downloading ykluks.
qvm-run --pass-io downloadvm "wget -O - https://github.com/the2nd/ykluks/archive/master.zip" > ykluks.zip
Unzip it.
unzip ykluks.zip
rm ykluks.zip
Run the installer script. This will copy all files to the right place.
cd ykluks-master
sudo ./install.sh
Prepare system for ykluks enabled initramfs
-------------------------------------------
Now we need to do some modifications for ykluks to work.
You may want to make a backup of your current initramfs. You can use the old initramfs in case something went wrong (see "something went wrong" below).
sudo cp -av /boot/initramfs-4.8.12-12.pvops.qubes.x86_64.img /boot/initramfs-4.8.12-12.pvops.qubes.x86_64.img.org
1. Comment out all lines in crypttab.
2. Change the line with "rd.luks.uuid=..." in /etc/default/grub to "rd.ykluks.uuid=..."
3. Change the line with "rd.qubes.hide_all_usb" in /etc/default/grub to "rd.ykluks.hide_all_usb"
Now we have to recreate the grub config and the initramfs.
sudo grub2-mkconfig > /boot/grub2/grub.cfg
sudo dracut -f
That's it. After a reboot you should be able to unlock your LUKS partition with your password and your yubikey.
Remove normal password and add secure backup password
-----------------------------------------------------
If everyting works as expected you may want to replace your (probably) insecure LUKS password with a secure backup password.
Add the new backup password.
sudo cryptsetup luksAddKey --key-slot a_free_key_slot /dev/sdXX
sudo cryptsetup luksKillslot --key-slot your_old_key_slot /dev/sdXX
Something went wrong :(
-----------------------
In case you run into any trouble after ykluks installation you can use the backup initramfs you (hopefully) created before generating a new one.
1. Select the Qubes OS boot entry in the grub boot menu.
2. Press "e" to get into edit mode.
3. First we need to change the "rd.ykluks.uuid=..." parameter back to "rd.luks.uuid=...". This is normally in the line that starts with "module /vmlinuz-...".
4. Then we need to get the line that loads the initramfs. This line normally starts with "module --nounzip /initramfs-..". Just append .org to this line.
5. Press "CTRL+X" to boot this configuration.

66
dracut/module-setup.sh Executable file
View File

@ -0,0 +1,66 @@
#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
check() {
return 0
}
depends() {
echo rootfs-block
return 0
}
install() {
#inst_hook pre-trigger 91 "$moddir/ykluks.sh"
inst_hook initqueue 01 "$moddir/ykluks.sh"
#inst_hook pre-mount 1 "$moddir/fix_crypttab.sh"
#inst_hook pre-trigger 10 "$moddir/ykluks.sh"
#inst_hook cmdline 5 "$moddir/ykluks.sh"
#inst_simple "/bin/bash" "/bin/bash"
inst tr
inst cut
inst true
inst find
inst blkid
inst lsusb
inst cryptsetup
inst fido2luks
# Stolen from qubes-pciback module.
inst lspci
inst grep
inst awk
#inst_simple "/usr/bin/tr" "/bin/tr"
#inst_simple "/usr/bin/cut" "/bin/cut"
#inst_simple "/usr/bin/true" "/bin/true"
#inst_simple "/usr/sbin/blkid" "/bin/blkid"
#inst_simple "/usr/bin/ykchalresp" "/bin/ykchalresp"
inst_simple "/etc/fido2luks.json" "/etc/fido2luks.json"
#inst_rules "$moddir/20-ykfde.rules"
inst_rules "/usr/lib/udev/rules.d/60-u2f-hidraw.rules"
#inst_simple "$moddir/ykluks.sh" "/bin/ykluks.sh"
#inst_hook cmdline 30 "$moddir/parse-mod.sh"
#inst_simple "$moddir/ykfde.sh" /sbin/ykfde.sh
#inst_simple /usr/lib/udev/ykfde
#inst_simple /etc/ykfde.conf
#inst_dir /etc/ykfde.d/*
inst_multiple -o \
$systemdsystemunitdir/systemd-ask-password-console.path \
$systemdsystemunitdir/systemd-ask-password-console.service \
systemd-ask-password systemd-tty-ask-password-agent
dracut_need_initqueue
}
installkernel() {
# Stolen from qubes-pciback module.
local mod=
for mod in pciback xen-pciback; do
if modinfo -k "${kernel}" "${mod}" >/dev/null 2>&1; then
hostonly='' instmods "${mod}"
fi
done
}

128
dracut/ykluks.sh Executable file
View File

@ -0,0 +1,128 @@
#!/bin/sh
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
# Set defaults.
YK_SLOT="2"
DEVICE_MAX_WAIT="60"
MESSAGE_TIMEOUT="10"
SHOW_YK_INSERT_MSG="false"
LUKS_PROMPT="Passphrase"
FIDO2LUKS_PROMPT="Password"
LUKS_PASSPHRASE_FALLBACK="false"
# Load config file.
FIDO2LUKS_CONFIG="/etc/fido2luks.json"
if [ -f "$FIDO2LUKS_CONFIG" ] ; then
export FIDO2LUKS_CONFIG="$FIDO2LUKS_CONFIG"
fi
LUKS_UUIDS="$(getargs rd.fido2luks.uuid | tr ' ' '\n'| cut -d '-' -f 2-)"
display_msg_timeout () {
local MSG="$1"
(plymouth display-message --text="$MSG";sleep $MESSAGE_TIMEOUT;plymouth hide-message --text="$MSG") &
}
display_msg () {
local MSG="$1"
plymouth display-message --text="$MSG" &
}
hide_msg () {
local MSG="$1"
plymouth hide-message --text="$MSG" &
}
hide_devices () {
# Find all networking devices currenly installed...
HIDE_PCI="`lspci -mm -n | grep '^[^ ]* "02'|awk '{print $1}'`"
# ... and optionally all USB controllers...
if getargbool 0 rd.fido2luks.hide_all_usb; then
HIDE_PCI="$HIDE_PCI `lspci -mm -n | grep '^[^ ]* "0c03'|awk '{print $1}'`"
fi
HIDE_PCI="$HIDE_PCI `getarg rd.fido2luks.hide_pci | tr ',' ' '`"
modprobe xen-pciback 2>/dev/null || :
# ... and hide them so that Dom0 doesn't load drivers for them
for dev in $HIDE_PCI; do
BDF=0000:$dev
if [ -e /sys/bus/pci/devices/$BDF/driver ]; then
echo -n $BDF > /sys/bus/pci/devices/$BDF/driver/unbind
fi
echo -n $BDF > /sys/bus/pci/drivers/pciback/new_slot
echo -n $BDF > /sys/bus/pci/drivers/pciback/bind
done
}
handle_authenticator () {
WAIT_COUNTER="0"
YUBIKEY_TEST=""
YUBIKEY_MSG="Please insert your authenticator..."
while ! fido2luks connected 2> /dev/null ; do
YUBIKEY_TEST="1"
if [ "$SHOW_YK_INSERT_MSG" != "true" ] ; then
break
fi
if [ "$YUBIKEY_MSG" != "" ] ; then
display_msg "$YUBIKEY_MSG"
HIDE_MSG="$YUBIKEY_MSG"
YUBIKEY_MSG=""
fi
if [ "$WAIT_COUNTER" -ge "$DEVICE_MAX_WAIT" ] ; then
break
fi
WAIT_COUNTER="$[$WAIT_COUNTER+1]"
sleep 1
done
if [ "$HIDE_MSG" != "" ] ; then
hide_msg "$HIDE_MSG"
fi
while true ; do
if [ "$YUBIKEY_TEST" == "" ] ; then
if [ "$LUKS_PASSPHRASE_FALLBACK" != "true" ] ; then
break
fi
LUKS_PASSPHRASE="$(/usr/bin/systemd-ask-password --no-tty "$LUKS_PROMPT")"
for UUID in $LUKS_UUIDS ; do
DEV="$(blkid -U "$UUID")"
if echo "$LUKS_PASSPHRASE" | cryptsetup luksOpen "$DEV" luks-$UUID ; then
LUKS_MSG="Luks device opened successful: $DEV"
display_msg_timeout "$LUKS_MSG"
else
LUKS_MSG="Failed to open luks device: $DEV (Wrong password?)"
display_msg_timeout "$LUKS_MSG"
LUKS_OPEN_FAILURE="true"
fi
done
else
fido2luks open
YUBIKEY_MSG="Received response from yubikey."
display_msg_timeout "$YUBIKEY_MSG"
LUKS_OPEN_FAILURE="false"
fi
if ! $LUKS_OPEN_FAILURE ; then
break
fi
done
}
if [ "$LUKS_UUIDS" != "" ] ; then
handle_authenticator
fi
rm /etc/udev/rules.d/60-u2f-hidraw.rules
systemctl daemon-reload
# Make sure we hide devices from dom0 after yubikey/luks setup.
hide_devices