User Tools

Site Tools


howtos:full_disk_encryption

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

howtos:full_disk_encryption [d/m/Y H:i] (current)
Line 1: Line 1:
 +
 +===== 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!
 +
 +{{:​howtos:​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.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​52:​04.png|}}
 +
 +Select the harddrive you want to format.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​52:​21.png|}}
 +
 +If you get this you just say Yes.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​52:​43.png|}}
 +
 +Select the new partitioning space.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​52:​54.png|}}
 +
 +Create a new partition.
 +
 +{{:​howtos:​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.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​53:​16.png|}}
 +
 +Create it as a primary partition.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​53:​22.png|}}
 +
 +Choose beginning.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​53:​28.png|}}
 +
 +Select a filesystem, I chose ext4, and select the mount point /boot.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​53:​49.png|}}
 +==== Encrypted partition ====
 +
 +
 +Now select the remaining part of the diskspace.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​53:​58.png|}}
 +
 +And yet again make a new partition.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​54:​07.png|}}
 +
 +Fill out the rest of the remain diskspace.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​54:​16.png|}}
 +
 +Make it primary.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​54:​26.png|}}
 +
 +Make it a encrypted volume.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​54:​46.png|}}
 +
 +Now configure the encrypted volume.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​55:​16.png|}}
 +
 +Confirm the writing to disk.
 +
 +{{:​howtos:​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.
 +
 +{{:​howtos:​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.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​56:​06.png|}}
 +
 +Now change it to a volume for LVM instead.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​56:​25.png|}}
 +
 +When coming back to the overview move to the top and select configure LVM.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​56:​34.png|}}
 +
 +Make a volume group.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​56:​43.png|}}
 +
 +Call it something. Not important.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​56:​54.png|}}
 +
 +Now we choose the encrypted volume for our container for the volume group.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​57:​03.png|}}
 +
 +Next create a logical volume for the swap space.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​57:​11.png|}}
 +
 +We only got one volume group so the choice is fairly simple :)
 +
 + 
 +{{:​howtos:​ubuntu_2009-07-06_20:​57:​16.png|}}
 +
 +Call it swap, or something else you would like to call your swap.
 +
 +{{:​howtos:​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.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​57:​45.png|}}
 +
 +Go back and make an other logical volume for the root filesystem.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​57:​59.png|}}
 +
 +Give it the rest of the space that is left.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​58:​07.png|}}
 +
 +Finish of in this part of the wizard.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​58:​13.png|}}
 +
 +Now select the logical volume that should contain our root filesystem.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​58:​35.png|}}
 +
 +Configure the filesystem for ext4 and select the mount point "/"​.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​58:​52.png|}}
 +
 +Now go for the logical volume that contains the swapspace.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​59:​01.png|}}
 +
 +Choose it to be a swapspace.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​59:​13.png|}}
 +
 +Finish of the partitioning.
 +
 +{{:​howtos:​ubuntu_2009-07-06_20:​59:​34.png|}}
 +
 +Save the changes to disk.
 +
 +{{:​howtos:​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.
 +
 +{{:​howtos:​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.
 +
 +{{:​howtos:​ubuntu_2009-07-06_21:​46:​26.png|}}
 +
 +{{:​howtos:​ubuntu_2009-07-06_21:​46:​42.png|}}
 +
 +{{:​howtos:​ubuntu_2009-07-06_21:​46:​54.png|}}
 +
 +{{:​howtos:​ubuntu_2009-07-06_21:​47:​14.png|}}
 +
 +
 +===== Keyfile =====
 +Lets create our keyfile for authentication and access to the encrypted filesystem.
 +
 +<​code>​
 +dd if=/​dev/​random of=/​dev/​shm/​root.key bs=1 count=256
 +</​code>​
 +
 +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:
 +
 +<​code>​
 +cryptsetup luksAddKey /dev/sda2 /​dev/​shm/​root.key
 +</​code>​
 +
 +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:
 +<​code>​
 +cryptsetup luksDelKey /dev/sda2 0
 +</​code>​
 +
 +
 +===== 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.
 +
 +<​file>​
 +#!/bin/sh
 +
 +# Part of passwordless cryptofs setup in Debian Etch.
 +# See: http://​wejn.org/​how-to-make-passwordless-cryptsetup.html
 +# Author: Wejn <wejn at box dot cz>
 +#
 +# Updated by Rodolfo Garcia (kix) <kix at kix dot com>
 +# For multiple partitions
 +# http://​www.kix.es/​
 +#
 +# Updated by TJ <​linux@tjworld.net>​ 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 <hendrik at van-antwerpen dot net> 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 <​command>​ "​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 <​command>​ 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/​console >/​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"​
 +</​file>​
 +
 +===== 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.
 +
 +<​file>​
 +#!/bin/sh
 +
 +# Part of passwordless cryptofs setup in Debian Etch.
 +# See: http://​wejn.org/​how-to-make-passwordless-cryptsetup.html
 +# Author: Wejn <wejn at box dot cz>
 +#
 +# Updated by Rodolfo Garcia (kix) <kix at kix dot com>
 +# For multiple partitions
 +# http://​www.kix.es/​
 +#
 +# Updated by TJ <​linux@tjworld.net>​ 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 <hendrik at van-antwerpen dot net> 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 <domingo at domingo dot dk> 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 <​command>​ "​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 <​command>​ 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/​console >/​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"​
 +</​file>​
 +
 +===== 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:
 +<​file>​
 +sda2_crypt /​dev/​disk/​by-uuid/​8f65184b-75ce-4852-9caf-7994037d47be none luks
 +</​file>​
 +
 +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:
 +<​file>​
 +sda2_crypt /​dev/​disk/​by-uuid/​8f65184b-75ce-4852-9caf-7994037d47be root.key luks,​keyscript=/​usr/​local/​sbin/​crypto-usb-key.sh
 +</​file>​
 +
 +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.
 +
 +<​file>​
 +#!/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
 +</​file>​
 +
 +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:
 +<​code>​
 +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
 +</​code>​
 +
 +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:
 +<​code>​
 +sudo dd if=keyfile.key of=/​dev/​sdY2 bs=1 count=256
 +</​code>​
 +
 +==== Edit /​etc/​crypttab ====
 +
 +Now edit your crypttab file and make it look like this:
 +
 +<​file>​
 +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 ​
 +</​file>​
 +
 +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:
 +<​code>​
 +sudo update-initramfs -u
 +</​code>​
 +
 +==== 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.
 +
 +<​file>​
 +#!/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
 +</​file>​
 +
 +Tell the system to run the script at startup:
 +<​code>​
 +sudo update-rc.d remove-usbkeydevice start 28 2 3 4 5 .
 +</​code>​
 +
 +
 +===== 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:
 +<​code>​
 +sudo apt-get install lvm2 cryptsetup
 +</​code>​
 +
 +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:
 +<​code>​
 +sudo cryptsetup luksOpen /dev/sdd1 encdisk --key-file key.txt
 +</​code>​
 +
 +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:
 +<​code>​
 +mount /​dev/​mapper/​encdisk /​media/​encdisk
 +</​code>​
 +
 + 
 +
 +==== Activate LVM ====
 +With the device open we can now activate our volume group:
 +<​code>​
 +root@ubuntu:​~#​ vgchange -ay
 +  2 logical volume(s) in volume group "​volgrp"​ now active
 +</​code>​
 +
 +If things go right you should now have access to the two logical volumes we made earlier. You can check it out by running:
 +<​code>​
 +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
 +</​code>​
 +
 +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 ;)
 +
 +<​code>​
 +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
 +</​code>​
 +
 +Tadaa!!
 +
 +----
 +Sources: ​
 +
 +https://​wiki.edubuntu.org/​EncryptedFSRemovableKeyDeviceHowto ​
 +
 +http://​wejn.org/​how-to-make-passwordless-cryptsetup.html
  
howtos/full_disk_encryption.txt · Last modified: d/m/Y H:i (external edit)