个人工具

UbuntuHelp:GutsyLUKSTwoFormFactor

来自Ubuntu中文

跳转至: 导航, 搜索

目录

Two Form Factor Authentication and LUKS Whole Disk Encryption with Gutsy Gibbon 7.10

Skill: High Complexity: High estTimeToComplete: 1.5 hours (ex. radomizing disks) Two Form Factor authentication in general relies on something you have and something you know. I'll detail a means of creating an encrypted USB flash drive that will then contain the keys for unlocking and booting your systems. The encrypted USB flash drive containing the system keys will be what you have and the passphrase to unlock the encrypted USB flash drive to retrieve the system keys will be what you know. Gutsy Gibbon 7.10 (Server) does offer first time installation to an encrypted volume , but does not have a two form setup. There are alternative methods available to install Gutsy Gibbon onto an encrypted whole disk system. This 'howto' details creating an encrypted USB flash drive, installing Gutsy Gibbon onto an encrypted whole disk system and finally configuring the two form factor authentication for the system startup using the encrypted USB flash drive.

Consider these excellent documents for related encryption information and methods. >

INPLACE UPGRADE from FF7.04 to GG7.10 ONLY

Quick notes on upgrading from FF7.04 to GG7.10....

Perform Upgrade

Let the automated upgrade proceed. But, PRIOR TO REBOOTING THE SYSTEM YOU MUST APPLY THE FOLLOWING!

Patch Initramfs Scripts/Hooks and UDEV

  • You will have to repatch initramfs cryptroot for the lvm/vgchange
  • You will have to repatch intiramfs udev for the lvm stomp
  • Create the copyfiles script to copy the /bin/stty for the bootkeyscript in the initramfs image
  • Re-add the KERNEL entry for the udev persistent storage naming of the USBCryptkey

Remove old cryptkey script & add new bootcryptkey script

  • Copy the bootcryptkey as instructed before making sure to chmod for executable
  • Remove the old cryptkey script if desired

Update the crypttab

  • Edit the crypttab file to use the new bootcryptkey script

Double Check for Typos

  • Look over the edits
  • Make sure the USBCryptKey is found when inserted or that the key entry in /etc/crypttab matches
  • Save back the /boot/* files of the previous version (just in case) and create entries in menu.lst if you like

Update INTIRAMFS

  • Run update-initramfs -u ALL

Update GRUB

  • Run update-grub

Reboot

  • The bootcryptkey script works with or without splash
  • You should be prompted for the two form auth as usual
  • If you encounter a problem you can reboot to the saved kernel

FRESH INSTALL Gutsy Gibbon 7.10 SERVER on Temporary Partition

The desktop version installation CD does not include any of the utilities required for 'out-of-the-box' encryption. The server version of the installation CD must be used. Installing the server version first reduces installation times, minimizes the disk consumed and avoids the initial clutter of a gui desktop for the encrypted setup. There is an included optional step towards the very end which will install the ubuntu-desktop. The boot volume /boot must be unecrypted as grub can't handle decrypting a boot partition. So, create 3 primary partitions. Use the /dev/sda5 partition as the tempoary unencrypted root / volume to begin. /dev/sda5 will later be used for the encrypted swap partition. So, size /dev/sda5 to accomodate the minimum server installation ~600MB and the maximum of what you want set for swap. (General rule of thumb 1.5 to 2 times physical RAM). Note: You will be root for all commands. i.e., $ sudo -i after each login.

Install Server Base

There is a wealth of documentation for installing Ubuntu Gutsy Gibbon 7.10 Server. Please refer to those documents if neccessary.

Disk Partitioning

GG7.10 is almost viable for creating encrypted systems during the installation. However, there are some quirks where it wasn't completely bullet-proof yet. ie. it didn't work. (I'll be trying to see what the issues are; because I'd rather not have to install to a temporary partition...) But, for now - this works. /dev/sda1 - boot /dev/sda2 - extended /dev/sda5 - logical /dev/sda6 - LVM logical partitions When you get to disk partitioning you may be better served by connecting to a second tty (ALT-F2) and running fdisk. No swap partition at this point. /dev/sda5 will be converted later to swap. sda5 could be a RAID 0 partition for the fastest swap you can get with the least disk. Either way it is the temporary root which will be converted to swap later on.

/dev/sda1 255M ext3 primary /boot
/dev/sda2 extended
/dev/sda5 2048M ext3 logical /
/dev/sda6 AllRemaingSpace primary unused

Update & Upgrade

With the base installation completed login and update the package listing.

Setup APT

Uncomment the deb resources for multiverse and universe. /etc/apt/sources.list

Update and Reboot

apt-get update
apt-get install cryptsetup lvm2 patch
apt-get upgrade
reboot

Creating Encrypeted USB Flash Drive

Create UDEV Mapping

Each computer system will report and mount your USB flash drive differently. e.g., /dev/sda or /dev/sdb To avoid constant changes in the cryptsetup's initramfs scripts which rely on the the USB flash drive create a common device name for your USB flash drive on each system you intend to lock.

Find USB Flash Drive Serial ID

Insert the USB flash drive you will be using. The USB will trigger a udev scan and will report the deivce name to the console. e.g., /dev/sdb. Armed with the device retrieve the device information and look for your USB flash drive manufacturer and associated serial number.

udevinfo -a -p $(udevinfo -q path -n /dev/sdb)
...
    ATTRS{serial}=="#######################"
    ATTRS{product}=="SUPERFLY"
    ATTRS{manufacturer}=="LEXAR"
...

Add USB Flash Drive Serial ID to UDEV Rules

Add the USB flash drive serial id and the common name to `/etc/udev/rules.d/65-persistent-storage.rules` and rescan the devices. The modified cryptsetup scripts use `/dev/USBCryptKey`. If you change the naming you'll need to modify those scripts.

vi /etc/udev/rules.d/65-persistent-storage.rules

Insert the following somewhere before the end label `LABEL="persistent_storage_end"`.

KERNEL=="sd*|sr*|st*", ATTRS{serial}=="######################", SYMLINK+="USBCryptKey%n"

Trigger and look for the common name device for your USB flash drive.

udevtrigger
ls /dev/USBCryptKey

The list command should have successfully returned `/dev/USBCryptKey`. Do not continue until this is correct.

Create LUKS Partition with EXT2 Filesystem

modprobe dm_crypt
cryptsetup luksFormat --hash=sha512 --cipher=aes-cbc-essiv:sha256 --key-size=256 /dev/USBCryptKey
cryptsetup luksOpen /dev/USBCryptKey cryptkeys
mkfs.ext2 /dev/cryptkeys
mkdir /mnt/cryptkeys
mount -t ext2 /dev/cryptkeys /mnt/cryptkeys

Generate Random Machine Key

Create a random key that will eventually be used to lock/unlock this system and store it on the opened and mounted encrypted USB flash drive. Replace #FILENAME with the name of your choosing. It will be used in later system configurations.

cd /mnt/cryptkeys
dd if=/dev/random of=#FILENAME bs=1 count=256

Install bootcryptkey Script

Swami Petaramesh in facilitating two-form factor authentication, brought his script to my attention. It is a clever script which accounts for both encrypted and unencrypted USB devices and most agreeably accounts for the pretty splash screens on bootup. It also alleviates some of the patching to the cryptroot scripts from the FeistyFawn7.04 two-form documentation. It works within the existing cryptroot scripting logic. I've made minor modifications to the original for inserting line echos, presented here. Install into /usr/local/sbin/bootcryptkey

#!/bin/sh

# Swami Petaramesh, 2007/11/28
# Copyright Swami Petaramesh 2007 <swami AT petaramesh DOT org>


# Parts copied from "cryptroot" script from the "cryptsetup"
# package, copyright cryptsetup authors. (Christophe Saout,
# Clemens Fruhwirth).

# This script allows using a key file stored on an external
# device, which can be LUKS-encrypted or not. It can fallback
# to using a manually input passphrase if the external device
# is missing.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>


# Additional boot params : cryptopts=key=<device>/<keyfile>
# Example : cryptopts=key=mmcblk0p1/mykeyfile
#	Will mount /dev/mmcblk0p1 and use "mykeyfile" on this device

#
# Helper functions
#

. /scripts/functions

parse_options()
{
	local cryptopts
	cryptopts="$1"

	if [ -z "$cryptopts" ]; then
		return 1
	fi

	# Defaults
	crypttarget="filesystem"
	cryptkeydev=""
	cryptkey=""

	local IFS=" ,"
	for x in $cryptopts; do
		case $x in
		target=*)
			crypttarget=${x#target=}
			;;
		key=*)
			if [ "${x#key=}" != "none" ]; then
				cryptkey=${x#key=}
			fi
			;;
		esac
	done

	cryptkeydev="/dev/${cryptkey%%/*}"
	cryptkey="${cryptkey#*/}"
}

type_key() {
	local PASS
	if [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then
		/sbin/usplash_write "TIMEOUT 180" || true
		/sbin/usplash_write "INPUTQUIET ${1:-Enter password:} "
		PASS="$(cat /dev/.initramfs/usplash_outfifo)"
	else
		/bin/stty -F /dev/console -echo
		read -p "${1:-Enter password:} " PASS < /dev/console 2> /dev/console
		/bin/stty -F /dev/console echo
	fi
		echo -n "${PASS}"
	if [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then
		# clean the text
		/sbin/usplash_write "TIMEOUT 15" || true
		/sbin/usplash_write "CLEAR"
	fi
}

fetch_key()
{
	local opts count
	opts="$1"

	if [ -z "$opts" ]; then
		return 1
	fi

	parse_options "$opts" || return 1

	# If no key device and file specified, fallback to typing the passphrase
	if [ -z "${cryptkeydev}" -o -z "${cryptkey}" ]; then
		type_key "Enter password for ${crypttarget}:"
		return 0
	else
		# Wait for udev to be ready, see https://launchpad.net/bugs/85640
		if [ -x /sbin/udevsettle ]; then
			/sbin/udevsettle --timeout=30
		fi
	
		# If the encrypted source device hasn't shown up yet, give it a little while
		# to deal with removable devices
		if [ ! -b "${cryptkeydev}" ] || ! /lib/udev/vol_id "${cryptkeydev}" >/dev/null 2>&1; then
			# We'll wait for a maximum of 10 seconds : External key devices
			# such as solid-state USB keys or SD/MMC shouldn't take longer
			# to show up...
			slumber=8
			if [ -x /sbin/usplash_write ]; then
				/sbin/usplash_write "TIMEOUT 30" || true
			fi
	
			slumber=$(( ${slumber} * 10 ))
			while [ ! -b "${cryptkeydev}" ] || ! /lib/udev/vol_id "${cryptkeydev}" >/dev/null 2>&1; do
				/bin/sleep 0.1
				slumber=$(( ${slumber} - 1 ))
				[ ${slumber} -gt 0 ] || break
			done
	
			if [ -x /sbin/usplash_write ]; then
				/sbin/usplash_write "TIMEOUT 15" || true
			fi
		fi
	
		# Fallback to typing the passphrase
		if [ ! -b "${cryptkeydev}" ]; then
			type_key "Missing boot device ${cryptkeydev}!"
			return 0
		fi

		mkdir -p /mnt/rootKey

		# Now that we've found the key device, let's check if it is
		# itself LUKS-encrypted
		if /sbin/cryptsetup isLuks ${cryptkeydev} > /dev/null 2>&1; then
			# Try to get a satisfactory password three times
			count=0
			while [ $count -lt 3 ]; do
				count=$(( $count + 1 ))
				type_key "Enter password for ${cryptkeydev}:" | /sbin/cryptsetup --readonly luksOpen ${cryptkeydev} rootKeyDev > /dev/null 2>&1
		
				if [ $? -ne 0 ]; then
					echo -e "cryptsetup: cryptsetup failed, bad password ?\n" > /dev/console
					sleep 2
					continue
				elif [ ! -b "/dev/mapper/rootKeyDev" ]; then
					echo -e "cryptsetup: unknown error setting up device mapping\n" > /dev/console
					# Fallback to typing the passphrase
					type_key "Setup of ${cryptkeydev} failed!"
					return 0
				fi
				break
			done

			if [ $count -ge 3 ]; then
				echo -e "cryptsetup: maximum number of tries exceeded\n" > /dev/console
				type_key "Failed opening ${cryptkeydev}!"
				return 0
			fi

			# Now try to mount the encrypted key container
			FSTYPE=''
	                eval $(fstype < "/dev/mapper/rootKeyDev")
			mount -t ${FSTYPE:-ext2} -o ro /dev/mapper/rootKeyDev /mnt/rootKey > /dev/null 2>&1
		else
			# Or try to mount the device
			FSTYPE=''
	                eval $(fstype < "${cryptkeydev}")
			mount -t ${FSTYPE:-ext2} -o ro ${cryptkeydev} /mnt/rootKey > /dev/null 2>&1
		fi

			if [ $? -ne 0 ]; then
				type_key "Failed mounting ${cryptkeydev}!"
				return 0

			# echo the keyfile contents
			elif [ -r "/mnt/rootKey/${cryptkey}" -a -s "/mnt/rootKey/${cryptkey}" ]; then
				cat /mnt/rootKey/${cryptkey}
			else
				type_key "Could not find ${cryptkey} on ${cryptkeydev}!"
				return 0
			fi

			# Unmount the key device
			umount /mnt/rootKey > /dev/null 2>&1
			# Wait for udev to be ready, see https://launchpad.net/bugs/85640
			if [ -x /sbin/udevsettle ]; then
				/sbin/udevsettle --timeout=30
			fi
			sleep 1
	
			# Close the encrypted device if it has been used
			[ -b "/dev/mapper/rootKeyDev" ] && /sbin/cryptsetup luksClose rootKeyDev > /dev/null 2>&1
			return 0
	fi
}

#
# Begin real processing
#

# Do we have any kernel boot arguments?
found=''
for opt in $(cat /proc/cmdline); do
	case $opt in
	cryptopts=*)
		found=yes
		fetch_key "${opt#cryptopts=}"
		;;
	esac
done

if [ -n "$found" ]; then
	if [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then
		/sbin/usplash_write "TIMEOUT 60" || true
	fi
	exit 0
fi

# Do we have any settings from the /conf/conf.d/cryptroot file?
if [ -r /conf/conf.d/cryptroot ]; then
	while read mapping; do
		fetch_key "$mapping"
	done < /conf/conf.d/cryptroot
fi

if [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then
	/sbin/usplash_write "TIMEOUT 60" || true
fi

exit 0

Make the bootcryptkey executable

chmod 755 /usr/local/sbin/bootcryptkey

Add support script for initramfs & bootcryptkey

Create file in /usr/share/initramfs-tools/hooks/copyfiles

#!/bin/sh -e
. /usr/share/initramfs-tools/hook-functions
copy_exec /bin/stty /bin
chmod 755 /usr/share/initramfs-tools/hooks/copyfiles

Modify Cryptsetup Scripts

You should have a bootable, stable server installation and and encrypted USB flash drive completed. The GG7.10 cryptsetup scripts still need a tweak.

/usr/share/initramfs-tools/scripts/local-top/cryptroot

Copy the diff into a temporary patch file and apply. vgchange doesn't exist in the initramfs so but lvm does.

vi /tmp/patch1
--- cryptroot.orig      2007-04-14 17:52:22.000000000 -0500
+++ cryptroot   2007-07-03 18:33:33.000000000 -0500
@@ -89,7 +93,7 @@
        vg="${1#/dev/mapper/}"
 
        # Sanity checks
-       if [ ! -x /sbin/vgchange ] || [ "$vg" = "$1" ]; then
+       if [ ! -x /sbin/lvm ] || [ "$vg" = "$1" ]; then
                return 1
        fi
 
@@ -104,7 +108,7 @@
        # Reduce padded --'s to -'s
        vg=$(echo ${vg} | sed -e 's#--#-#g')
 
-       vgchange -ay ${vg}
+       lvm vgchange -ay ${vg}
        return $?
 }

patch -b -l /usr/share/initramfs-tools/scripts/local-top/cryptroot < /tmp/patch1

/usr/share/initramfs-tools/scripts/init-bottom/udev

There is a quirk whereby the lvm-on-luks mappings are overwritten with the `/dev` filesystem is remounted for read write. We need `mapper` for the lvm mounts to funtion on boot. I'd requested a fix before 7.10 release but, the change didn't appear to make the cut. So, for LVM on LUKS this is still required.

vi /tmp/patch2
--- udev.orig   2007-04-10 09:03:36.000000000 -0500
+++ udev        2007-07-03 18:13:46.000000000 -0500
@@ -27,5 +27,5 @@
 # Move the real filesystem's /dev to beneath our tmpfs, then move it all
 # to the real filesystem
 mkdir -m 0700 -p /dev/.static/dev
-mount -n -o bind ${rootmnt}/dev /dev/.static/dev
+mount -n -o bind /dev/.static/dev ${rootmnt}/dev
 mount -n -o move /dev ${rootmnt}/dev
patch -b -l /usr/share/initramfs-tools/scripts/init-bottom/udev < /tmp/patch2

After patching, if backups were created, remove them so as not to 'corrupt' the initramfs build.

rm /usr/share/initramfs-tools/scripts/local-top/cryptroot.orig
rm /usr/share/initramfs-tools/scripts/init-bottom/udev.orig

Create LUKS/LVM Volumes on Unused Partition

Randomize the Unused Partition

To obscure use of the volume randomize the partition befor using it. Caution: `urandom` is not as good as `random` but will cut the time significantly. Note: This will take a considerable amount of time and is proporational to the volume size. e.g., Radomizing 1.5TB ~2Days.

dd if=/dev/urandom of=/dev/sda6

Go find something fun to do outside!

Setup LUKS on Partition

Note: I've used the largest cipher and hash available as well as key-size. The defaults are smaller. Also, for the initial setup, use the same passphrase for LUKS0.

cryptsetup luksFormat --hash=sha512 --cipher=aes-cbc-essiv:sha256 --key-size=256 /dev/sda6

Open the LUKS partition.

cryptsetup luksOpen /dev/sda6 cryptVault

Setup LVM Data Partitions

Season to taste. The volume sizes will be relevant to your system design goals. Note: When later converting to ubuntu-desktop apt required more space in /var then I had originally allocated. And rather than re-configure apt to use a different cache I just resized /var to +1024MB. The `lvsnap` volume is for creating snapshot volumes for backup purposes. It will not be referenced again in this document. It is there as a reminder to allocate for it before you slice and dice all avialable disk space. [todo: create communityDoc for BackupWithLVMSnaphot] !!! Note: The lvm volumes MUST be of the form `/dev/mapper/vg##-name`. The cryptroot script relies on this naming convention to determine whether or not a volume is LVM and to select the volume group name to activate. !!!

pvcreate /dev/mapper/cryptVault
vgcreate vg00 /dev/mapper/cryptVault
vgchange -a y vg00
lvcreate -L70G -nlvroot vg00
lvcreate -L512M -nlvtmp vg00
lvcreate -L2048M -nlvvar vg00
lvcreate -L512M -nlvhome vg00
lvcreate -L512M -nlvsnap vg00

Tip: If you will be allocating the remaining free extents to a volume do pvdisplay and find the Free PE and use that value in `ĺvcreate -l### -n#SOMEPART` Edit the crypttab. The lvm option triggers the lvm on luks during startup. This will setup the LUKS whole disk encryption with an initial passphrase. Once this works the Two Form Factor configuration follows.

echo cryptVault /dev/sda6 none luks,cipher=aes-cbc-essiv:sha256,hash=sha512,lvm=vg00-lvroot >> /etc/crypttab

Apply Filesystems to the Partitions

mkfs.ext3 /dev/vg00/lvroot
mkfs.ext2 /dev/vg00/lvtmp
mkfs.ext3 /dev/vg00/lvvar
mkfs.ext3 /dev/vg00/lvhome
mkfs.ext3 /dev/vg00/lvsnap

Migrate Temporary Installation to Encrypted Volumes

Make Mount Points and Mount LUKS Encrypted LVM Volumes

mkdir /tmp/croot
mount /dev/vg00/lvroot /tmp/croot
mkdir /tmp/croot/tmp
mkdir /tmp/croot/home
mkdir /tmp/croot/var

Note: Due to an Ubuntu quirk `/var/run` and `/var/lock` must exist on the root filesystem during bootstrap/startup. Since we're splitting `/var` from the start we need to kludge for that behavior.

$ mkdir -p -m 0700 /tmp/croot/var/run
$ mkdir -p -m 0700 /tmp/croot/var/lock
$ mount /dev/vg00/lvtmp /tmp/croot/tmp
$ mount /dev/vg00/lvvar /tmp/croot/var
$ mount /dev/vg00/lvhome /tmp/croot/home

Copy the Temporary Base Installation to the Encrypted Volumes

cp -ax / /tmp/croot

Mount Special Devices

Mount the following special devices so that when we `chroot` everything will work.

mount -t proc /proc /tmp/croot/proc
mount -o bind /dev /tmp/croot/dev
mount /dev/sda1 /tmp/croot/boot

Change ROOT

chroot /tmp/croot

Edit FSTAB

You should successfully be in the chroot environment and it will be nearly indistinguishable from the first. Don't get confused. Edit the fstab to reflect the desired filesystem layout. Season to taste. Note: The lvm volumes MUST be of the form `/dev/mapper/vg##-name`. The cryptroot script relies on this naming convention to determine whether or not a volume is LVM and to select the volume group name to activate. Also, your fstab configuration listing will likely be different then the one listed. Season to taste. This is still accurate in GG7.10

vi /etc/fstab
# /etc/fstab: static file system information.
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
/dev/sda1	 	/boot           ext3    defaults        0       2
/dev/mapper/vg00-lvroot	/               ext3    defaults	0       1
/dev/mapper/vg00-lvvar		/var            ext3    defaults	0       1
/dev/mapper/vg00-lvtmp		/tmp            ext2    defaults	0       1
/dev/mapper/vg00-lvhome	/home           ext3    defaults	0       1
proc            /proc           proc    defaults        0       0
/dev/scd0       /media/cdrom0   udf,iso9660 user,noauto     0       0

Edit /boot/grub/menu.lst

Edit grub/menu.lst and update the kopt value. Also, do yourself a favor and just turn splash off. It is nice but for now just complicates the LUKS passphrase prompting on startup. /boot/grub/menu.lst

# kopt=root=/dev/mapper/vg00-lvroot ro
...
# defoptions=quiet

Update initramfs Image

It is vital to have the FSTAB and CRYPTROOT files properly edited. The initramfs scripts for setting up the crypt initrd rely on the settings in these files to generate the appropriate image.

update-initramfs -u ALL

Update GRUB Boot Menu

To get the correct and updated `menu.lst` stanza on the bootloader.

update-grub

Exit CHROOT

If satisfied with the system setup and crypt changes exit out of the chroot environment.

exit

Unmount the New Encrypted Volumes

cd /
umount /tmp/croot/home
umount /tmp/croot/tmp
umount /tmp/croot/var
umount /tmp/croot/boot
umount /tmp/croot/proc
umount /tmp/croot/dev
umount /tmp/croot
vgchange -a n vg00

Reboot

reboot

Single Form Factor LUKS Whole Disk Encrypted Startup

You'll be prompted for the passphrase you used to create the LUKS cryptsetup on `/dev/sda6`. If successfull the system should boot without errors. If you do encounter a problem: 1. Reboot 2. Pause grub w/ <ESC> and edit kernel stanza and change `/dev/mapper/vg00-lvroot` to `/dev/sda5` (Remember we haven't deleted the un-encrypted installation yet.) 3. Boot to `/dev/sda5` 4. Cryptsetup luksOpen `/dev/sda6` 5. Remount the filesystems (Refer to previous step: `Migrate Temporary Installation to Encrypted Volumes`.) 6. Skip the copy step 7. `chroot /tmp/croot` 8. Make your changes and try again


Setup Two Form Factor LUKS Whole Disk Encryption

If you've successfully booted into the single form factor LUKS encrypted whole disk installation then you can continue setting up the system with the USB cryptKey for Two Form Factor authentication.

Edit /etc/crypttab

Edit the `/etc/crypttab` file to reflect the items for Two Form authentication. Use the #FILENAME from the random key step. Include a path if your encrypted USB flash drive filesystem has a directory structure that you are using to manage files. e.g., Under `USBCryptKey/serverkeys` or `USBCryptKey/laptopkey` etc. The #PATH is relative to the mount point. So, #PATH would be `USBCryptKey/serverkeys/#FILENAME` or `USBCryptKey/laptopkey/#FILENAME` Modify /etc/crypttab:

cryptVault /dev/sda6 USBCryptKey/#PATH/#FILENAME luks,cipher=aes-cbc-essiv:sha256,hash=sha512,lvm=vg00-lvroot,keyscript=/usr/local/sbin/bootcryptkey

Add System Key to USBCryptKey

cryptsetup luksOpen /dev/USBCryptKey cryptkeys
mount -t ext2 /dev/mapper/cryptkeys /mnt

Add Random Generated Key

Add the new key file to the root `cryptVault`. This should add to Slot 1. When you add the key you'll be prompted for a passphrase. The passphrase is the one used when setting up `/dev/sda6` not the passphrase used for the USB cryptKey.

cryptsetup luksAddKey /dev/sda6 /mnt/cryptkeys/#PATH#FILENAME

Update initramfs Image

Armed with the settings for Two Form authentication to unlock your system update the initramfs image to contain the new changes.

update-initramfs -u ALL

Close USB cryptKey

umount /mnt
cryptsetup luksClose cryptkeys

Reboot

reboot

Two Form Factor LUKS Whole Disk Encrypted Startup

Until you remove the initial Slot0 key on `/dev/sda6` you can still startup WITHOUT the USBCryptKey. So, if you have problems with the USB cryptKey initial setup, you can discontinue the cryptkeyscript and be prompted for the `/dev/sda6` Slot0 passphrase.

Insert Encrypted USB Flash Drive

1. Insert your USBCryptKey. Note: Depending on your system you may need to wait until after the `Setting up cryptograpic volume cryptVault (based on /dev/sd#)` because the USB device may be identified and assigned `/dev/sda` before the harddrive is identified accurately. 2. If cryptKey found then you'll be prompted for the 'Passphrase for /dev/USBCryptKey:' 3. If the USBCryptKey is opened successfully the bootcryptkey script will fetch the requested key and procceed to unlock `/dev/sda6` with the random generated key. 4. If you fail to open the USBCryptKey for any reason, remove the device and be prompted for the /dev/sda6 Slot0 passphrase. Login, make your changes, `update-initramfs -u ALL` and retry.

Setup Encrypted Swap

Now setup the encrypted SWAP which will replace `/dev/sda5`. Caution: Once you convert the temporary root `/dev/sda5` to `swap` you won't be able to make use of the un-encrypted volume for setup work and changes to the encrypted volumes. It'll mean you start from scratch if things go haywire.

Edit /etc/crypttab

Add:

cryptSwap /dev/sda5 /dev/random swap

If you encounter timeout issues you can change this ti /dev/urandom with the caveats regarding urandom vs. random.

Edit /etc/fstab

Add `/dev/mapper/cryptSwap none swap sw 0 0`

# /etc/fstab: static file system information.
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# /dev/sda1
/dev/sda1	 	/boot           ext3    defaults        0       2
/dev/mapper/cryptSwap		none	swap	sw	0	0
/dev/mapper/vg00-lvroot	/               ext3    defaults	0       1
/dev/mapper/vg00-lvvar		/var            ext3    defaults	0       1
/dev/mapper/vg00-lvtmp		/tmp            ext2    defaults	0       1
/dev/mapper/vg00-lvhome	/home           ext3    defaults	0       1
proc            /proc           proc    defaults        0       0
/dev/scd0       /media/cdrom0   udf,iso9660 user,noauto     0       0

Update initramfs Image

update-initramfs -u ALL

Radomize SWAP /dev/sda5

There goes the un-encrypted installation... Again, this will take about 15-30 minutes depending on the size of sda5.

dd if=/dev/urandom of=/dev/sda5

Reboot and Confirm Swap

You'll unlock everything again on reboot.

reboot

You should see cryptSwap is active. If not go back to `/etc/fstab` or `/etc/crypttab`.

cat /proc/swaps

FINALIZE with True Two Form Factor

If satisfied with the startup using the USB Crypt``Key remove the passphrase that was initially used for `/dev/sda6` on Slot0. If you remove the initial passphrase from Slot0 and rely on the random generated key stored on the USB Crypt``Key this affords some small plausable deniability. Once your remove the slot0 key form `/dev/sda3` the ONLY key which will unlock the luks device is the 256bit random keyfile located on the USB Crypt``Key device! You can add a passphrase back if you need/want to later but that somewhat defeats the whole purpose.

Mount USB cryptKey and Remove /dev/sda6 Slot0 Key

BE CONFIDENT THAT THE SYSTEM BOOTS FROM THE USB CRYPTKEY DEVICE BEFORE PROCEEDING!! With the USB Crypt``Key still inserted proceed with the Slot0 removal from `/dev/sda6`. After login...

cryptsetup luksOpen /dev/USBCryptKey cryptkeys
mount /dev/mapper/cryptkeys /mnt
cryptsetup --key-file=/mnt/#PATH#FILENAME luksDelKey /dev/sda6 0

If command successfull then you can unmount the USBCryptKey.

cd /
umount /mnt
cryptsetup luksClose cryptkeys

Optional

Install Ubuntu Desktop

It is really quite painless and effective. I'm quite impressed! Enjoy the eye-candy!

apt-get install ubuntu-desktop

Key Manipulations

The bootcryptkey script doesn't do any memory moves of the key-file. It is just fed as the key-file parameter to cryptsetup.

Potential Security Vulnerabilities/Vectors

1. Unencrypted boot on the host. With boot volume on the host kernel updates are convenient. However, without physical security of the host the initramfs image is vulnerable. That image contains the crypttab file entries exposing the cryptKey device name, the specified key-file and the keyscript file you are using. i.e.,usbcryptkey Unless you take measures to check the boot initramfs image for un-authorized changes an interloper may alter the initramfs boot image and insert code that may intercept and redirect any accessible keys/files. 2. Backup keys. (DON'T store your keys unencrypted.) 3. Caution: `urandom` is not as good as `random` but will cut the time significantly. 4. Increased probability of multiple system compromises with a single USB device containing multiple system keys.

Possible Solutions

1. Boot volume on the same usb flash drive with the keys. This would require some changes to scripts and such.. (Perhaps the 'strongest' protection to the problem. The 'keys' are more likely to stay in your possession.

A hash checksum of the boot kernel and image presented before cryptkey mounting. (Weak - adulterated initramfs image could report original numbers - fake out) It still might be advisable to checksum the /boot after /root mounted. Maybe an unnspecified script to report on the checksum and compare to the previous startup values. Brake booting if different for confirmation of changes. (thinking that the unidentified script would be outside of the initramfs ability to affect...) Encrypted /boot with GRUB able to prompt for passphrases to unlock the LUKS partitions. (Weak? - Now we have to trust GRUB hasn't been attacked. It is integral and bound to the hardrive partitions.) Could GRUB be loaded on a USB device? 2. Don't backup the random keys. Or back them up encrypted somewhere else. (But, backup keys could compromise plausible deniability if discovery of such media/medium exists.) 3. Use 'random' when you can afford the painfull time penalty for encryption. 4. Place the random system keys on individual encrypted USB devices thereby spreading the risks. However, the caveat being increased administration.

Creative Commons License

Author: James B. Crocker EMail: [email protected] [1] This work is licensed under a Creative Commons Attribution-Share Alike 3.0 License.