Difference between revisions of "LUKS"

From YobiWiki
Jump to navigation Jump to search
Line 180: Line 180:
 
9:2345:respawn:/sbin/getty -L -n -l /usr/local/sbin/autologin 38400 tty9
 
9:2345:respawn:/sbin/getty -L -n -l /usr/local/sbin/autologin 38400 tty9
 
This will launch another getty on tty9 without login prompt but a call to a handmade script /usr/local/sbin/autologin:
 
This will launch another getty on tty9 without login prompt but a call to a handmade script /usr/local/sbin/autologin:
  +
<source lang=bash>
#!/bin/sh
+
#!/bin/sh
/bin/login -f phil AUTOX=true
+
/bin/login -f phil AUTOX=true
  +
</source>
 
And so if you want startx to be called automatically you can add to your ~/.bash_profile:
 
And so if you want startx to be called automatically you can add to your ~/.bash_profile:
  +
<source lang=bash>
if [[ $AUTOX = true ]]
+
if [[ $AUTOX = true ]]
then
+
then
AUTOX=false
 
startx
+
AUTOX=false
logout
+
startx
  +
logout
fi
+
fi
  +
</source>
 
This method was inspired by Linux Mag France no 107. I added the AUTOX=false otherwise calls to "xterm -ls" in the graphical session would fail.
 
This method was inspired by Linux Mag France no 107. I added the AUTOX=false otherwise calls to "xterm -ls" in the graphical session would fail.

Revision as of 12:41, 28 June 2008

Documentation

To encrypt the swap

apt-get install cryptsetup

Follow instructions of /usr/share/doc/cryptsetup/CryptoSwap.HowTo
The diff is that I had to destroy the content of the swap partition before /etc/init.d/cryptdisks otherwise cryptsetup refuses to work.

To encrypt disks

Creation

cryptsetup luksFormat /dev/hdaX
cryptsetup luksOpen /dev/hdaX hdaX
mkfs.ext3 /dev/mapper/hdaX
cryptsetup luksClose hdaX

Usage

cryptsetup luksOpen /dev/hdaX hdaX && mount -t ext3 /dev/mapper/hdaX /mnt/
umount /mnt && cryptsetup luksClose hdaX

To encrypt the root fs

Get packages

To use the XTS block chaining method we need a recent kernel (>=2.6.24 and 2.6.24 had apparently a bug related to XTS on some CPUs so I went for 2.6.25)

apt-get install initramfs-tools cryptsetup linux-image-2.6.25-2-686

If you didn't have a separate /boot partition, make one in clear as we cannot boot on an encrypted kernel & initrd!

Have /boot on a separate partition

If it's not yet done, it's time!
Moving /boot to a separate partition involves a crucial step:
Recreating the MBR stage1 so it founds the new location of stage2
cf http://www.troubleshooters.com/linux/grub/grubpartition.htm
Assuming your /boot partition is /dev/[hs]da1, here's how you do it:

grub
grub> root (hd0,0)
grub> setup (hd0)
grub> quit

/boot/grub/menu.lst needs the following changes:

# groot=(hd0,0)
# splashimage=(hd0,0)/grub/...

FYI and to understand my instructions, here's my intended layout:

# /dev/sda1 /boot
# /dev/sda2 will be the encrypted /
# /dev/sda5 encrypted swap
# /dev/sda6 /home

reboot to your temp / after you've altered the table of partitions

Creation of the encrypted volume

Backup the original partition

dd if=/dev/sda2 of=./sda2.img bs=1024k

Fill it with random data

dd if=/dev/urandom of=/dev/sda2

Create a LUKS volume

cryptsetup luksFormat -c aes-xts-plain -s 256 /dev/sda2
YES
my_boot_password

Edit /etc/crypttab and add a ref to our new partition

echo "croot /dev/sda2 none luks" >> /etc/crypttab

Start the encrypted root filesystem (don't worry if your swap is already started)

/etc/init.d/cryptdisks start
my_boot_password

Setup the filesystem

mkfs.ext3 /dev/mapper/croot

Mount the device

mount /dev/mapper/croot /mnt/disk

Copy your root filesystem into place, sth like this in the simplest case

cp -axv / /mnt/disk

Make sure the root device is listed in /etc/fstab

/dev/mapper/croot / ext3 defaults 0 1

/boot/grub/menu.lst needs to point to /dev/mapper/croot:

# kopt=root=/dev/mapper/croot ro vga=791

Regenerate the initramfs image

dpkg-reconfigure linux-image-2.6.25-2-686

Reboot

Avoiding to type many times the LUKS password

One major drawback on my setup (you don't see it here) is that I've several partitions encrypted as such and it leads to some problems:

  • At boot time I've to enter the passphrase for each of the partitions
  • I tried the "noauto" keyword in /etc/crypttab to avoid mounting some of the partitions but it didn't work, I've to find out why.
  • One solution is to use a keyfile stored in the root partition to decrypt the other partitions but I don't want to give access to all partitions to those I give access to my rootfs (e.g. my homedir to my employer)
  • Another solution is to use keyfiles stored on a USB stick, which means I've to wear such USB stick and not getting it stolen aside my laptop...
  • The last solution I see is to implement something like the gpg or ssh agents to remember briefly my passphrase during boot time and try it against all partitions.
    • quintuple-agent could be used for example, but it has to be integrated into the initrd
    • maybe a simple environment variable would be enough

That's finally the last solution I implemented, composed of one part that will join the initramfs and capture the LUKS password to tmpfs and one part that will use it during rc stage:

[{{#file:cryptoroot_persist}} /etc/initramfs-tools/hooks/cryptoroot_persist] (make it executable)

#!/bin/sh

# List the soft prerequisites here.  This is a space separated list of
# names, of scripts that are in the same directory as this one, that
# must be run before this one can be.
#
PREREQ=""

prereqs()
{
	echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
	prereqs
	exit 0
	;;
esac

. /usr/share/initramfs-tools/hook-functions

# Fix bug #486916 that copies /lib/cryptsetup/askpass to /lib/cryptsetup
if [ -x /lib/cryptsetup/askpass ] && [ -f "$DESTDIR/lib/cryptsetup" ]; then
    rm -f "$DESTDIR/lib/cryptsetup"
    copy_exec /lib/cryptsetup/askpass
fi

# Patch cryptroot script to export LUKS passphrase
cat << EOF | patch -p0
--- $DESTDIR/scripts/local-top/cryptroot	2008-06-13 23:58:53.000000000 +0200
+++ $DESTDIR/scripts/local-top/cryptroot	2008-06-13 23:45:27.000000000 +0200
@@ -182,8 +182,10 @@
 	# Prepare commands
 	if /sbin/cryptsetup isLuks \$cryptsource > /dev/null 2>&1; then
 		cryptcreate="/sbin/cryptsetup -T 1 luksOpen \$cryptsource \$crypttarget"
+		cryptpersist=true
 	else
 		cryptcreate="/sbin/cryptsetup -T 1 -c \$cryptcipher -s \$cryptsize -h \$crypthash create \$crypttarget \$cryptsource"
+		cryptpersist=false
 	fi
 	cryptremove="/sbin/cryptsetup remove \$crypttarget"
 	NEWROOT="/dev/mapper/\$crypttarget"
@@ -205,6 +207,11 @@
 			usplash_write "INPUTQUIET Enter password for \$crypttarget: "
 			PASS="\$(cat /dev/.initramfs/usplash_outfifo)"
 			echo -n "\$PASS" | \$cryptcreate > /dev/null 2>&1
+			\$cryptpersist && echo -n "PASS=\$PASS" > /dev/.initramfs/pass
+		elif \$cryptpersist; then
+			PASS=\$(/lib/cryptsetup/askpass "Enter passphrase:" < /dev/console 2> /dev/console)
+			echo -n "\$PASS" | \$cryptcreate > /dev/console 2>&1
+			echo -n "PASS=\$PASS" > /dev/.initramfs/pass
 		else
 			\$cryptcreate < /dev/console > /dev/console 2>&1
 		fi
EOF

if [ $? -ne 0 ];
then
	echo "An error occured in $0: patching cryptroot script failed" >&2
	exit 1
fi

exit 0

And a [{{#file:cryptdisks.functions.diff}} patch for /lib/cryptsetup/cryptdisks.functions]

--- /lib/cryptsetup/cryptdisks.functions	2008-03-31 16:36:32.000000000 +0200
+++ /lib/cryptsetup/cryptdisks.functions	2008-06-13 23:51:39.000000000 +0200
@@ -299,6 +299,8 @@
 			tried=$(( $tried + 1 ))
 		done
 	else
+		[ "$PASS" != "" ] && \
+		echo -n "$PASS" | cryptsetup $PARAMS luksOpen "$src" "$dst" || \
 		cryptsetup $PARAMS luksOpen "$src" "$dst" <&1 || tried="$TRIES"
 	fi
 
@@ -576,6 +578,10 @@
 	modprobe -qb dm-crypt || true
 	dmsetup mknodes > /dev/null 2>&1 || true
 	log_action_begin_msg "Starting $INITSTATE crypto disks"
+	if [ -f /dev/.initramfs/pass ]; then
+	    . /dev/.initramfs/pass
+	    rm /dev/.initramfs/pass
+	fi
 	mount_fs
 
 	egrep -v "^[[:space:]]*(#|$)" "$TABFILE" | while read dst src key opts; do

We can go one step further by

Enabling autologin

Indeed we already did the hardest security step: providing the LUKS password, so why should I prove I know my user password as well, sth so easy to circumvent with a LiveCD...
To enable autologin, you can use GDM or KDM facilities or (as I'm used of launching startx manually) you can choose a lighter way:
Add to /etc/inittab:

9:2345:respawn:/sbin/getty -L -n -l /usr/local/sbin/autologin 38400 tty9

This will launch another getty on tty9 without login prompt but a call to a handmade script /usr/local/sbin/autologin:

#!/bin/sh
/bin/login -f phil AUTOX=true

And so if you want startx to be called automatically you can add to your ~/.bash_profile:

if [[ $AUTOX = true ]]
then
    AUTOX=false
    startx
    logout
fi

This method was inspired by Linux Mag France no 107. I added the AUTOX=false otherwise calls to "xterm -ls" in the graphical session would fail.