===== Setup partitions =====
There are many ways of using LUKS for disk encryption. I'll use the combination of LUKS and LVM to have one chunk of data (the volume group) which all is encrypted. This way all filesystems I make, including swap, will be encrypted. As this is a laptop I will not venture down all the possibilities that LVM has to offer.
Now lets get started!
{{:indexes:ubuntu_2009-07-06_20:46:21.png|}}
Boot up on a usb/cd with the alternate Ubuntu installer on it. This is important otherwise you will not get the options that we will use for this setup.
Go through the install wizard and choose what you want.
==== Boot ====
When getting to the partitioning select Manual.
{{:indexes:ubuntu_2009-07-06_20:52:04.png|}}
Select the harddrive you want to format.
{{:indexes:ubuntu_2009-07-06_20:52:21.png|}}
If you get this you just say Yes.
{{:indexes:ubuntu_2009-07-06_20:52:43.png|}}
Select the new partitioning space.
{{:indexes:ubuntu_2009-07-06_20:52:54.png|}}
Create a new partition.
{{:indexes:ubuntu_2009-07-06_20:53:01.png|}}
Select a size around 100-200MB. This is going to become the boot so not space is needed.
{{:indexes:ubuntu_2009-07-06_20:53:16.png|}}
Create it as a primary partition.
{{:indexes:ubuntu_2009-07-06_20:53:22.png|}}
Choose beginning.
{{:indexes:ubuntu_2009-07-06_20:53:28.png|}}
Select a filesystem, I chose ext4, and select the mount point /boot.
{{:indexes:ubuntu_2009-07-06_20:53:49.png|}}
==== Encrypted partition ====
Now select the remaining part of the diskspace.
{{:indexes:ubuntu_2009-07-06_20:53:58.png|}}
And yet again make a new partition.
{{:indexes:ubuntu_2009-07-06_20:54:07.png|}}
Fill out the rest of the remain diskspace.
{{:indexes:ubuntu_2009-07-06_20:54:16.png|}}
Make it primary.
{{:indexes:ubuntu_2009-07-06_20:54:26.png|}}
Make it a encrypted volume.
{{:indexes:ubuntu_2009-07-06_20:54:46.png|}}
Now configure the encrypted volume.
{{:indexes:ubuntu_2009-07-06_20:55:16.png|}}
Confirm the writing to disk.
{{:indexes:ubuntu_2009-07-06_20:55:22.png|}}
Just choose a password you can remember. Later on we will remove it and make it keybased.
{{:indexes:ubuntu_2009-07-06_20:55:33.png|}}
==== LVM ====
The wizard will automatically make one big ext3 filesystem out of the encrypted volume. We don't want that so go select the partition and hit enter.
{{:indexes:ubuntu_2009-07-06_20:56:06.png|}}
Now change it to a volume for LVM instead.
{{:indexes:ubuntu_2009-07-06_20:56:25.png|}}
When coming back to the overview move to the top and select configure LVM.
{{:indexes:ubuntu_2009-07-06_20:56:34.png|}}
Make a volume group.
{{:indexes:ubuntu_2009-07-06_20:56:43.png|}}
Call it something. Not important.
{{:indexes:ubuntu_2009-07-06_20:56:54.png|}}
Now we choose the encrypted volume for our container for the volume group.
{{:indexes:ubuntu_2009-07-06_20:57:03.png|}}
Next create a logical volume for the swap space.
{{:indexes:ubuntu_2009-07-06_20:57:11.png|}}
We only got one volume group so the choice is fairly simple :)
{{:indexes:ubuntu_2009-07-06_20:57:16.png|}}
Call it swap, or something else you would like to call your swap.
{{:indexes:ubuntu_2009-07-06_20:57:29.png|}}
Give it a proper size so at least it can contain all what's in your ram when you hibernate.
{{:indexes:ubuntu_2009-07-06_20:57:45.png|}}
Go back and make an other logical volume for the root filesystem.
{{:indexes:ubuntu_2009-07-06_20:57:59.png|}}
Give it the rest of the space that is left.
{{:indexes:ubuntu_2009-07-06_20:58:07.png|}}
Finish of in this part of the wizard.
{{:indexes:ubuntu_2009-07-06_20:58:13.png|}}
Now select the logical volume that should contain our root filesystem.
{{:indexes:ubuntu_2009-07-06_20:58:35.png|}}
Configure the filesystem for ext4 and select the mount point "/".
{{:indexes:ubuntu_2009-07-06_20:58:52.png|}}
Now go for the logical volume that contains the swapspace.
{{:indexes:ubuntu_2009-07-06_20:59:01.png|}}
Choose it to be a swapspace.
{{:indexes:ubuntu_2009-07-06_20:59:13.png|}}
Finish of the partitioning.
{{:indexes:ubuntu_2009-07-06_20:59:34.png|}}
Save the changes to disk.
{{:indexes:ubuntu_2009-07-06_20:59:44.png|}}
We do not need to encrypt our home as the hole root is encrypted. So say no.
{{:indexes:ubuntu_2009-07-06_21:13:55.png|}}
Now when ever we boot we will have to enter our password for the encrypted filesystem to startup.
{{:indexes:ubuntu_2009-07-06_21:46:26.png|}}
{{:indexes:ubuntu_2009-07-06_21:46:42.png|}}
{{:indexes:ubuntu_2009-07-06_21:46:54.png|}}
{{:indexes:ubuntu_2009-07-06_21:47:14.png|}}
===== Keyfile =====
Lets create our keyfile for authentication and access to the encrypted filesystem.
dd if=/dev/random of=/dev/shm/root.key bs=1 count=256
This will create a random key called root.key in the ramdisk. The ramdisk is used to make sure the key is completely gone after reboot.
Now add the keyfile as authenticator for the filesystem:
cryptsetup luksAddKey /dev/sda2 /dev/shm/root.key
Now move the root.key to a usb device of some sort and keep it safe!!
After you have tested that your keyfile is working, you can remove the password from the encrypted disk:
cryptsetup luksDelKey /dev/sda2 0
===== Keyscript 1 =====
Put this file into "/usr/local/sbin/crypto-usb-key.sh" and run "chmod 500" on it. If you change anything in the script you will have to update the initramfs file with the new version of the file.
The script handles both ordinary partitions, like vfat and ext3, but also encrypted usb devices (see [[Encrypted USB Storage]] on how to make one. I would recommend to have the key file store on a encrypted usb device. That way you maximize the security if someone should copy the usb device and try to get access to the key and you harddisk.
#!/bin/sh
# Part of passwordless cryptofs setup in Debian Etch.
# See: http://wejn.org/how-to-make-passwordless-cryptsetup.html
# Author: Wejn
#
# Updated by Rodolfo Garcia (kix)
# For multiple partitions
# http://www.kix.es/
#
# Updated by TJ 7 July 2008
# For use with Ubuntu Hardy, usplash, automatic detection of USB devices,
# detection and examination of *all* partitions on the device (not just partition #1),
# automatic detection of partition type, refactored, commented, debugging code.
#
# Updated by Hendrik van Antwerpen 3 Sept 2008
# For encrypted key device support, also added stty support for not
# showing your password in console mode.
# define counter-intuitive shell logic values (based on /bin/true & /bin/false)
# NB. use FALSE only to *set* something to false, but don't test for
# equality, because a program might return any non-zero on error
TRUE=0
FALSE=1
# set DEBUG=$TRUE to display debug messages, DEBUG=$FALSE to be quiet
DEBUG=$FALSE
# is usplash available? default false
USPLASH=$FALSE
# test for outfifo from Ubuntu Hardy cryptroot script, the second test
# alone proves not completely reliable.
if [ -p /dev/.initramfs/usplash_outfifo -a -x /sbin/usplash_write ]; then
# use innocuous command to determine if usplash is running
# usplash_write will return exit-code 1 if usplash isn't running
# need to set a flag to tell usplash_write to report no usplash
FAIL_NO_USPLASH=1
# enable verbose messages (required to display messages if kernel boot option "quiet" is enabled
/sbin/usplash_write "VERBOSE on"
if [ $? -eq $TRUE ]; then
# usplash is running
USPLASH=$TRUE
/sbin/usplash_write "CLEAR"
fi
fi
# is stty available? default false
STTY=$FALSE
STTYCMD=false
# check for stty executable
if [ -x /bin/stty ]; then
STTY=$TRUE
STTYCMD=/bin/stty
elif [ `(busybox stty >/dev/null 2>&1; echo $?)` -eq $TRUE ]; then
STTY=$TRUE
STTYCMD="busybox stty"
fi
# print message to usplash or stderr
# usage: msg "message" [switch]
# command: TEXT | STATUS | SUCCESS | FAILURE | CLEAR (see 'man usplash_write' for all commands)
# switch : switch used for echo to stderr (ignored for usplash)
# when using usplash the command will cause "message" to be
# printed according to the usplash definition.
# using the switch -n will allow echo to write multiple messages
# to the same line
msg ()
{
if [ $# -gt 0 ]; then
# handle multi-line messages
echo $2 | while read LINE; do
if [ $USPLASH -eq $TRUE ]; then
# use usplash
/sbin/usplash_write "$1 $LINE"
else
# use stderr for all messages
echo $3 "$2" >&2
fi
done
fi
}
dbg ()
{
if [ $DEBUG -eq $TRUE ]; then
msg "$@"
sleep 1
fi
}
# read password from console or with usplash
# usage: readpass "prompt"
readpass ()
{
if [ $# -gt 0 ]; then
if [ $USPLASH -eq $TRUE ]; then
usplash_write "INPUTQUIET $1: "
PASS="$(cat /dev/.initramfs/usplash_outfifo)"
else
[ $STTY -ne $TRUE ] && msg TEXT "WARNING stty not found, password will be visible"
echo -n "$1" >&2
$STTYCMD -echo
read -r PASS /dev/null
[ $STTY -eq $TRUE ] && echo >&2
$STTYCMD echo
fi
fi
echo -n "$PASS"
}
dbg STATUS "Executing crypto-usb-key.sh ..."
# flag tracking key-file availability
OPENED=$FALSE
# temporary mount path for USB key
MD=/tmp-usb-mount
if [ "x$1" = "x" -o "x$1" = "xnone" ]; then
# default key-file on the USB disk
KEYFILE=.key
else
KEYFILE=$1
fi
# If the file already exists use it.
# This is useful where an encrypted volume contains keyfile(s) for later
# volumes and is now mounted and accessible
if [ -f $KEYFILE ]; then
dbg TEXT "Found $KEYFILE"
cat $KEYFILE
OPENED=$TRUE
DEV="existing mount"
LABEL=""
else
# Is the USB driver loaded?
cat /proc/modules | busybox grep usb_storage >/dev/null 2>&1
USBLOAD=0$?
if [ $USBLOAD -gt 0 ]; then
dbg TEXT "Loading driver 'usb_storage'"
modprobe usb_storage >/dev/null 2>&1
fi
# give the system time to settle and open the USB devices
sleep 7
# Are there any SCSI block devices?
ls -d /sys/block/sd* >/dev/null 2>&1
SBD=$?
if [ $SBD -eq $TRUE ]; then
mkdir -p $MD
dbg TEXT "Trying to get key-file '$KEYFILE' ..."
for SFS in /sys/block/sd*/sd??; do
dbg TEXT "Examining $SFS" -n
# is it a USB device?
ls -l ${SFS}/../device | busybox grep 'usb' >/dev/null 2>&1
USB=0$?
dbg TEXT ", USB=$USB" -n
# Is the device removable?
REMOVABLE=0`cat ${SFS}/../removable`
dbg TEXT ", REMOVABLE=$REMOVABLE" -n
if [ $USB -eq 1 -a $REMOVABLE -eq 1 -a -f $SFS/dev ]; then
dbg TEXT ", *possible key device*" -n
DEV=`busybox basename $SFS`
# Check if key device itself is encrypted
/sbin/cryptsetup isLuks /dev/${DEV} >/dev/null 2>&1
ENCRYPTED=0$?
# Open crypted partition and prepare for mount
if [ $ENCRYPTED -eq $TRUE ]; then
dbg TEXT ", encrypted device" -n
# Use vol_id to determine label
LABEL="`/lib/udev/vol_id /dev/${DEV} | busybox sed -n 's/.*ID_FS_LABEL_SAFE=\(.*\)/\1/p'`"
dbg TEXT ", label $LABEL" -n
TRIES=3
DECRYPTED=$FALSE
while [ $TRIES -gt 0 -a $DECRYPTED -ne $TRUE ]; do
TRIES=$(($TRIES-1))
PASS="`readpass \"Enter LUKS password for key device ${DEV} (${LABEL}) (or empty to skip): \"`"
if [ -z "$PASS" ]; then
dbg TEXT ", device skipped" -n
break
fi
echo $PASS | /sbin/cryptsetup luksOpen /dev/${DEV} bootkey >/dev/null 2>&1
DECRYPTED=0$?
done
# If open failed, skip this device
if [ $DECRYPTED -ne $TRUE ]; then
dbg TEXT "decrypting device failed" -n
break
fi
# Decrypted device to use
DEV=mapper/bootkey
fi
dbg TEXT ", device $DEV" -n
# Use vol_id to determine label
LABEL="`/lib/udev/vol_id /dev/${DEV} | busybox sed -n 's/.*ID_FS_LABEL_SAFE=\(.*\)/\1/p'`"
dbg TEXT ", label $LABEL" -n
# Use vol_id to determine fstype
FSTYPE="`/lib/udev/vol_id /dev/${DEV} | busybox sed -n 's/.*ID_FS_TYPE=\(.*\)/\1/p'`"
dbg TEXT ", fstype $FSTYPE" -n
# Is the file-system driver loaded?
cat /proc/modules | busybox grep $FSTYPE >/dev/null 2>&1
FSLOAD=0$?
if [ $FSLOAD -gt 0 ]; then
dbg TEXT ", loading driver for $FSTYPE" -n
# load the correct file-system driver
modprobe $FSTYPE >/dev/null 2>&1
fi
dbg TEXT ", mounting /dev/$DEV on $MD" -n
mount /dev/${DEV} $MD -t $FSTYPE -o ro >/dev/null 2>&1
dbg TEXT ", (`mount | busybox grep $DEV`)" -n
if [ -f $MD/$KEYFILE ]; then
dbg TEXT ", found $MD/$KEYFILE" -n
cat $MD/$KEYFILE
OPENED=$TRUE
fi
dbg TEXT ", umount $MD" -n
umount $MD >/dev/null 2>&1
# Close encrypted key device
if [ $ENCRYPTED -eq $TRUE -a $DECRYPTED -eq $TRUE ]; then
dbg TEXT ", closing encrypted device" -n
/sbin/cryptsetup luksClose bootkey >/dev/null 2>&1
fi
dbg TEXT ", done\n\n" -n
if [ $OPENED -eq $TRUE ]; then
break
fi
else
dbg TEXT ", device `busybox basename $SFS` ignored" -n
fi
dbg CLEAR ""
done
fi
fi
# clear existing usplash text and status messages
[ $USPLASH -eq $TRUE ] && msg STATUS " " && msg CLEAR ""
if [ $OPENED -ne $TRUE ]; then
msg TEXT "FAILED to find suitable USB key-file ..."
readpass "Try to enter the LUKS password: "
else
msg TEXT "Success loading key-file from $SFS ($LABEL)"
fi
#
[ $USPLASH -eq $TRUE ] && /sbin/usplash_write "VERBOSE default"
===== Keyscript 1 with Karmic Koala =====
With the release of Karmic Koala udev was removed from the distribution. This has the unfortunate consequence that the script looses its ability to identify the filesystem type.
What I've done is to replace vol_id commands with blkid. And now it works again.
#!/bin/sh
# Part of passwordless cryptofs setup in Debian Etch.
# See: http://wejn.org/how-to-make-passwordless-cryptsetup.html
# Author: Wejn
#
# Updated by Rodolfo Garcia (kix)
# For multiple partitions
# http://www.kix.es/
#
# Updated by TJ 7 July 2008
# For use with Ubuntu Hardy, usplash, automatic detection of USB devices,
# detection and examination of *all* partitions on the device (not just partition #1),
# automatic detection of partition type, refactored, commented, debugging code.
#
# Updated by Hendrik van Antwerpen 3 Sept 2008
# For encrypted key device support, also added stty support for not
# showing your password in console mode.
#
# Updated by Thomas Domingo Dahlmann 06-11-2009
# Made the script work on Ubuntu Karmic Koala. This release doesn't have udev thus
# filesystem type recognitioning doesn't work. Changed it to us blkid instead.
# define counter-intuitive shell logic values (based on /bin/true & /bin/false)
# NB. use FALSE only to *set* something to false, but don't test for
# equality, because a program might return any non-zero on error
TRUE=0
FALSE=1
# set DEBUG=$TRUE to display debug messages, DEBUG=$FALSE to be quiet
DEBUG=$FALSE
# is usplash available? default false
USPLASH=$FALSE
# test for outfifo from Ubuntu Hardy cryptroot script, the second test
# alone proves not completely reliable.
if [ -p /dev/.initramfs/usplash_outfifo -a -x /sbin/usplash_write ]; then
# use innocuous command to determine if usplash is running
# usplash_write will return exit-code 1 if usplash isn't running
# need to set a flag to tell usplash_write to report no usplash
FAIL_NO_USPLASH=1
# enable verbose messages (required to display messages if kernel boot option "quiet" is enabled
/sbin/usplash_write "VERBOSE on"
if [ $? -eq $TRUE ]; then
# usplash is running
USPLASH=$TRUE
/sbin/usplash_write "CLEAR"
fi
fi
# is stty available? default false
STTY=$FALSE
STTYCMD=false
# check for stty executable
if [ -x /bin/stty ]; then
STTY=$TRUE
STTYCMD=/bin/stty
elif [ `(busybox stty >/dev/null 2>&1; echo $?)` -eq $TRUE ]; then
STTY=$TRUE
STTYCMD="busybox stty"
fi
# print message to usplash or stderr
# usage: msg "message" [switch]
# command: TEXT | STATUS | SUCCESS | FAILURE | CLEAR (see 'man usplash_write' for all commands)
# switch : switch used for echo to stderr (ignored for usplash)
# when using usplash the command will cause "message" to be
# printed according to the usplash definition.
# using the switch -n will allow echo to write multiple messages
# to the same line
msg ()
{
if [ $# -gt 0 ]; then
# handle multi-line messages
echo $2 | while read LINE; do
if [ $USPLASH -eq $TRUE ]; then
# use usplash
/sbin/usplash_write "$1 $LINE"
else
# use stderr for all messages
echo $3 "$2" >&2
fi
done
fi
}
dbg ()
{
if [ $DEBUG -eq $TRUE ]; then
msg "$@"
sleep 0.2
fi
}
# read password from console or with usplash
# usage: readpass "prompt"
readpass ()
{
if [ $# -gt 0 ]; then
if [ $USPLASH -eq $TRUE ]; then
usplash_write "INPUTQUIET $1: "
PASS="$(cat /dev/.initramfs/usplash_outfifo)"
else
[ $STTY -ne $TRUE ] && msg TEXT "WARNING stty not found, password will be visible"
echo -n "$1" >&2
$STTYCMD -echo
read -r PASS /dev/null
[ $STTY -eq $TRUE ] && echo >&2
$STTYCMD echo
fi
fi
echo -n "$PASS"
}
dbg STATUS "Executing crypto-usb-key.sh ..."
# flag tracking key-file availability
OPENED=$FALSE
# temporary mount path for USB key
MD=/tmp-usb-mount
if [ "x$1" = "x" -o "x$1" = "xnone" ]; then
# default key-file on the USB disk
KEYFILE=.key
else
KEYFILE=$1
fi
# If the file already exists use it.
# This is useful where an encrypted volume contains keyfile(s) for later
# volumes and is now mounted and accessible
if [ -f $KEYFILE ]; then
dbg TEXT "Found $KEYFILE"
cat $KEYFILE
OPENED=$TRUE
DEV="existing mount"
LABEL=""
else
# Is the USB driver loaded?
cat /proc/modules | busybox grep usb_storage >/dev/null 2>&1
USBLOAD=0$?
if [ $USBLOAD -gt 0 ]; then
dbg TEXT "Loading driver 'usb_storage'"
modprobe usb_storage >/dev/null 2>&1
fi
# give the system time to settle and open the USB devices
sleep 7
# Are there any SCSI block devices?
ls -d /sys/block/sd* >/dev/null 2>&1
SBD=$?
if [ $SBD -eq $TRUE ]; then
mkdir -p $MD
dbg TEXT "Trying to get key-file '$KEYFILE' ..."
for SFS in /sys/block/sd*/sd??; do
dbg TEXT "Examining $SFS" -n
# is it a USB device?
ls -l ${SFS}/../device | busybox grep 'usb' >/dev/null 2>&1
USB=0$?
dbg TEXT ", USB=$USB" -n
# Is the device removable?
REMOVABLE=0`cat ${SFS}/../removable`
dbg TEXT ", REMOVABLE=$REMOVABLE" -n
if [ $USB -eq 1 -a $REMOVABLE -eq 1 -a -f $SFS/dev ]; then
dbg TEXT ", *possible key device*" -n
DEV=`busybox basename $SFS`
# Check if key device itself is encrypted
/sbin/cryptsetup isLuks /dev/${DEV} >/dev/null 2>&1
ENCRYPTED=0$?
# Open crypted partition and prepare for mount
if [ $ENCRYPTED -eq $TRUE ]; then
dbg TEXT ", encrypted device" -n
# Use vol_id to determine label
#LABEL="`/lib/udev/vol_id /dev/${DEV} | busybox sed -n 's/.*ID_FS_LABEL_SAFE=\(.*\)/\1/p'`"
dbg TEXT ", label $LABEL" -n
TRIES=3
DECRYPTED=$FALSE
while [ $TRIES -gt 0 -a $DECRYPTED -ne $TRUE ]; do
TRIES=$(($TRIES-1))
PASS="`readpass \"Enter LUKS password for key device ${DEV} (${LABEL}) (or empty to skip): \"`"
if [ -z "$PASS" ]; then
dbg TEXT ", device skipped" -n
break
fi
echo $PASS | /sbin/cryptsetup luksOpen /dev/${DEV} bootkey >/dev/null 2>&1
DECRYPTED=0$?
done
# If open failed, skip this device
if [ $DECRYPTED -ne $TRUE ]; then
dbg TEXT "decrypting device failed" -n
break
fi
# Decrypted device to use
DEV=mapper/bootkey
fi
dbg TEXT ", device $DEV" -n
# Use blkid to determine fstype
FSTYPE=`blkid /dev/${DEV} | busybox sed -n 's/.*TYPE=\(.*\)/\1/p'| busybox sed 's/\"//g'`
dbg TEXT ", fstype $FSTYPE" -n
# Is the file-system driver loaded?
cat /proc/modules | busybox grep $FSTYPE >/dev/null 2>&1
FSLOAD=0$?
if [ $FSLOAD -gt 0 ]; then
dbg TEXT ", loading driver for $FSTYPE" -n
# load the correct file-system driver
modprobe $FSTYPE >/dev/null 2>&1
fi
dbg TEXT ", mounting /dev/$DEV on $MD" -n
mount /dev/${DEV} $MD -t $FSTYPE -o ro >/dev/null 2>&1
dbg TEXT ", (`mount | busybox grep $DEV`)" -n
if [ -f $MD/$KEYFILE ]; then
dbg TEXT ", found $MD/$KEYFILE" -n
cat $MD/$KEYFILE
OPENED=$TRUE
fi
dbg TEXT ", umount $MD" -n
umount $MD >/dev/null 2>&1
# Close encrypted key device
if [ $ENCRYPTED -eq $TRUE -a $DECRYPTED -eq $TRUE ]; then
dbg TEXT ", closing encrypted device" -n
/sbin/cryptsetup luksClose bootkey >/dev/null 2>&1
fi
dbg TEXT ", done\n\n" -n
if [ $OPENED -eq $TRUE ]; then
break
fi
else
dbg TEXT ", device `busybox basename $SFS` ignored" -n
fi
dbg CLEAR ""
done
fi
fi
# clear existing usplash text and status messages
[ $USPLASH -eq $TRUE ] && msg STATUS " " && msg CLEAR ""
if [ $OPENED -ne $TRUE ]; then
msg TEXT "FAILED to find suitable USB key-file ..."
readpass "Try to enter the LUKS password: "
else
msg TEXT "Success loading key-file from $SFS ($LABEL)"
fi
#
[ $USPLASH -eq $TRUE ] && /sbin/usplash_write "VERBOSE default"
===== Making changes to crypttab =====
To make use of the passwordless encryption we must tell LUKS what to do and where to find what it needs.
Inside /etc/crypttab you will see something like this:
sda2_crypt /dev/disk/by-uuid/8f65184b-75ce-4852-9caf-7994037d47be none luks
This file tells us that LUKS will find its encrypted partition on a device with the uuid "8f65184b-75ce-4852-9caf-7994037d47be" and that it should map it to a virtual device called "sda2_crypt". It also tells us that there is no key used for opening the device by the "none" statement. It will just ask for a password to open the disk.
As we are looking for at passwordless authentication change the file into this:
sda2_crypt /dev/disk/by-uuid/8f65184b-75ce-4852-9caf-7994037d47be root.key luks,keyscript=/usr/local/sbin/crypto-usb-key.sh
Now LUKS will look for the keyfile called root.key and it will use the script crypto-usb-key.sh to get it.
In this version we will configure a keyfile that is a regular file on a regular filesystem. Later on I will make a version where the key is store on the usb-device outside of the partitions.
The crypttab file is also a guideline for the update-initramfs command so it knows that it needs to pack a script into initrd to be able to boot.
===== An other way of storing the keyfile =====
Instead of holding the keyfile as a ordinary file on a filesystem you can also store it in raw format somewhere on the usb key. This way it will be hard to copy the keyfile of the device for misuse. If it is more secure than a keyfile on an encrypted usb filesystem I can not tell. But it may fit someones needs.
==== Keyscript 2 ====
The keyscript for extracting the keyfile is now different, so to boot with a key stored in raw format this will do it.
Paste this script into the file "/usr/local/sbin/usbkeyscript.sh" and make it executable.
#!/bin/sh
# Return true if usplash is running, otherwise return false.
[ -x /sbin/usplash_write ] && usplash_exists='1'
usplash_running()
{
[ -z "$usplash_exists" ] && return 1
pidof "usplash" >/dev/null
return $?
}
fixup_verbosity()
{
if [ "$(expr match "$(cat /proc/cmdline)" '.*quiet')" -gt "0" ]; then
/sbin/usplash_write "VERBOSE off" 2>/dev/null
else
/sbin/usplash_write "VERBOSE on" 2>/dev/null
fi
}
# Write output to the console. n: now newline s: status (no time)
write_to_console()
{
read system_uptime no_var < /proc/uptime
if [ "x$2" != "xs" ]; then
printf '[%8s0000] %s' "$system_uptime" "$1" >&2
else
printf '%s' "$1" >&2
fi
if [ "x$2" != "xn" ]; then
printf '\n' >&2
fi
}
# Write output to usplash
write_to_usplash()
{
usplash_running
if [ $? -eq 0 ]; then
/sbin/usplash_write "VERBOSE on"
/sbin/usplash_write "$1 $2"
fixup_verbosity
fi
write_to_console "$2" "$3"
return 0
}
if [ "x$1" = "x" -o "x$1" = "xnone" ]; then
write_to_usplash "TEXT" "Keyscript: not configured for external keydevice." >&2
/lib/cryptsetup/askpass "Enter passphrase: "
exit 0
else
KEYDEVICE=$(echo $1 | cut -d# -f 1)
KEYSIZE=$(echo $1 | cut -d# -f 2)
KEYPOS=$(echo $1 | cut -d# -f 3)
fi
SETTLETIMEOUT=5 #in secs
FIRSTDEVICETIMEOUT=100 #in decisecs
DEFAULTDEVICETIMEOUT=5 #in decisecs
DEVICETIMEOUT="${FIRSTDEVICETIMEOUT}"
if [ -f /tmp/usbkey-discover-done ]; then
DEVICETIMEOUT="${DEFAULTDEVICETIMEOUT}"
fi
touch /tmp/usbkey-discover-done
write_to_usplash "TEXT" "Keyscript: waiting for udev to settle"
# Wait for udev to be ready, see https://launchpad.net/bugs/85640
if [ -x /sbin/udevsettle ]; then
/sbin/udevsettle --timeout=${SETTLETIMEOUT} > /dev/null 2>&1
fi
write_to_usplash "TEXT" "Keyscript: searching for device..." "n"
# Wait for the KEYDEVICE to appear
slumber=${DEVICETIMEOUT}
while [ ! -b "${KEYDEVICE}" ]; do
/bin/sleep 0.1
slumber=$(( ${slumber} - 1 ))
if [ ${slumber} -lt 0 ]; then
write_to_usplash "FAILURE" "not found." "s"
/lib/cryptsetup/askpass "Enter passphrase: "
exit 0
fi
done
write_to_usplash "SUCCESS" "found." "s"
dd if=${KEYDEVICE} bs=1 count=${KEYSIZE} skip=${KEYPOS} 2> /dev/null
exit 0
Now take your usb device and make two partitions on it. The first should be an ordinary fat partition and the other should be an unformated one.
After formating the usb device you will need to know the unique ID of it for the configuration later on. This also means that you will only be able to use this particular one to unlock you harddisk. Run this command:
ls -l /dev/disk/by-id/ | grep sdY2
lrwxrwxrwx 1 root root 10 2009-07-10 17:44 usb-Corsair_Voyager_Mini_332677b71000b3-0:0-part2 -> ../../sdY2
The part saying "usb-Corsair_Voyager_Mini_332677b71000b3-0:0-part2" is the one we're going to use later on.
Say our usb device is called /dev/sdY2 do the following to put the keyfile onto it:
sudo dd if=keyfile.key of=/dev/sdY2 bs=1 count=256
==== Edit /etc/crypttab ====
Now edit your crypttab file and make it look like this:
sdXX_crypt /dev/disk/by-uuid/00000000-1111-2222-3333-444444444444 /dev/disk/by-id/usb-Corsair_Voyager_Mini_332677b71000b3-0:0-part2#256#0 luks,keyscript=/usr/local/sbin/usbkeyscript.sh
What it says is that on the device called "usb-Corsair_Voyager_Mini_332677b71000b3-0:0-part2" there is a 256 bit key with the offset of 0 (right at the beginning).
Now update the initramfs:
sudo update-initramfs -u
==== Force-unplug-script ====
To make sure the usb device is not left in the machine, which would make all this security pretty useless, this script will stop the bootup process and force you to eject the device before it continues the boot process.
Put the script inside this file: "/etc/init.d/remove-usbkeydevice" and make it executable.
Please note that the variable "KEYDEVICE" should match the one we have the keyfile on. Otherwise this script will not work.
#!/bin/sh
### BEGIN INIT INFO
# Provides: remove-usbkeydevice
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop:
# Short-Description: Forces removal of the keydevice to continue boot.
# Description:
### END INIT INFO
KEYDEVICE=/dev/disk/by-id/usb-Corsair_Voyager_Mini_332677b71000b3-0:0-part2
# Return true if usplash is running, otherwise return false.
[ -x /sbin/usplash_write ] && usplash_exists='1'
usplash_running()
{
[ -z "$usplash_exists" ] && return 1
pidof "usplash" >/dev/null
return $?
}
fixup_verbosity()
{
if [ "$(expr match "$(cat /proc/cmdline)" '.*quiet')" -gt "0" ]; then
/sbin/usplash_write "VERBOSE off" 2>/dev/null
else
/sbin/usplash_write "VERBOSE on" 2>/dev/null
fi
}
# Write output to the console. n: now newline s: status (no time)
write_to_console()
{
read system_uptime no_var < /proc/uptime
if [ "x$2" != "xs" ]; then
printf '[%8s0000] %s' "$system_uptime" "$1" >&2
else
printf '%s' "$1" >&2
fi
if [ "x$2" != "xn" ]; then
printf '\n' >&2
fi
}
# Write output to usplash
write_to_usplash()
{
usplash_running
if [ $? -eq 0 ]; then
/sbin/usplash_write "VERBOSE on"
/sbin/usplash_write "$1 $2"
fixup_verbosity
fi
write_to_console "$2" "$3"
return 0
}
case "$1" in
start)
if [ -b ${KEYDEVICE} ]; then
write_to_usplash "TEXT" "Please remove your keydevice to continue."
fi
while [ -b ${KEYDEVICE} ]; do sleep 0.1; done
exit 0;
;;
*)
echo "Usage: remove-usbkeydevice start"
exit 1
;;
esac
Tell the system to run the script at startup:
sudo update-rc.d remove-usbkeydevice start 28 2 3 4 5 .
===== Regaining access to data on a unbootable system =====
If you end up with a computer that is as useful as a brick there is still hope. As all infomation about the encrypted disk lies within the disk it self you can still gain access to you data on a unbootable system.
This is not a security risk as data stays encrypted if you cannot provide the correct authentication, so don't worry.
You should take note that an encrypted disk is harder to recover if there is a physical problem with the harddisk or data has been corrupted in some way. This foxhole is only gonna work if the disk is in working condition to some degree.
==== Boot on a liveCD ====
To get onto the system you will need a liveCD/USB. I use the one created by Ubuntu.
LVM and cryptsetup may not be on the LiveCD by default. This is very simple to overcome, just get an Internet connection, open a console and run:
sudo apt-get install lvm2 cryptsetup
This should "install" the needed tools for the rest of this exercise.
==== Open encrypted device ====
Next we can open the encrypted device. I'll assume my encrypted partition is called /dev/sdd1:
sudo cryptsetup luksOpen /dev/sdd1 encdisk --key-file key.txt
This command opens /dev/sdd1 and gives it the logcial name encdisk. I'm also using a keyfile for authentication, you could also use a password if so is allowed by removing the statement "--key-file".
We cannot read our files just yet as we're using LVM. If you're not you would be able to mount the filesystem now like this:
mount /dev/mapper/encdisk /media/encdisk
==== Activate LVM ====
With the device open we can now activate our volume group:
root@ubuntu:~# vgchange -ay
2 logical volume(s) in volume group "volgrp" now active
If things go right you should now have access to the two logical volumes we made earlier. You can check it out by running:
root@ubuntu:~# ls /dev/mapper/ -l
total 0
crw-rw---- 1 root root 10, 61 2009-07-12 18:41 control
brw-rw---- 1 root disk 252, 0 2009-07-12 16:53 encdisk
brw-rw---- 1 root disk 252, 2 2009-07-12 16:53 volgrp-root
brw-rw---- 1 root disk 252, 1 2009-07-12 16:53 volgrp-swap
Here we see that we have the logical name (encdisk), that represent the interface to the encrypted disk, volgrp-swap that is the logical volume "swap" in the volume group "volgrp" and the logical volume "root" also in the volume group "volgrp" (volgrp-root).
==== Mount filesystems ====
Now with both the encrypted disk unlocked and the logical volumes activated we can start mounting the root filesystem and yet again see our beloved files ;)
root@ubuntu:/media# mkdir /media/lv-root
root@ubuntu:/media# mount /dev/mapper/volgrp-root /media/lv-root/
root@ubuntu:/media# cd /media/lv-root/
root@ubuntu:/media/lv-root# ls
bin dev initrd.img lost+found opt sbin sys var
boot etc initrd.img.old media proc selinux tmp vmlinuz
cdrom home lib mnt root srv usr vmlinuz.old
Tadaa!!
----
Sources:
https://wiki.edubuntu.org/EncryptedFSRemovableKeyDeviceHowto
http://wejn.org/how-to-make-passwordless-cryptsetup.html