Difference between revisions of "Suspend to Cryptodisk"

From C4 Wiki
Jump to: navigation, search
m
m (umlautify)
Line 1: Line 1:
 
= Einleitung =
 
= Einleitung =
  
Frueher war alles besser, da hat sich noch das BIOS in einem Laptop um das Suspenden auf
+
Früher war alles besser, da hat sich noch das BIOS in einem Laptop um das Suspenden auf
die Festplatte gekuemmert. Heute haben alle Laptops ACPI, und das Betriebssystem muss sich
+
die Festplatte gekümmert. Heute haben alle Laptops ACPI, und das Betriebssystem muss sich
selber kuemmern.  Das hat den Vorteil, dass man sich wirklich um alle Kleinigkeiten
+
selber kümmern.  Das hat den Vorteil, dass man sich wirklich um alle Kleinigkeiten
kuemmern kann, aber gleichzeitig auch muss.
+
kümmern kann, aber gleichzeitig auch muss.
  
Das grosse Problem fuer den sicherheitsbewussten Anwender ist, dass der Inhalt des
+
Das große Problem für den sicherheitsbewussten Anwender ist, dass der Inhalt des
Arbeitsspeichers unverschluesselt auf der Festplatte landet, und damit saemtliche
+
Arbeitsspeichers unverschlüsselt auf der Festplatte landet, und damit sämtliche
Festplattenverschluesselung ausgehebelt wird, da natuerlich der Key fuer diese
+
Festplattenverschlüsselung ausgehebelt wird, da natürlich der Key für diese
Verschluesselung irgendwo im RAM liegt.
+
Verschlüsselung irgendwo im RAM liegt.
  
Dieses Howto will eine Anleitung sein, wie man unter Debian GNU/Linux (aktuell
+
Dieses How-To will eine Anleitung sein, wie man unter Debian GNU/Linux (aktuell
Etch/testing) auf eine verschluesselte Festplatte suspendet, so dass dort keinerlei Daten
+
Etch/testing) auf eine verschlüsselte Festplatte suspendet, so dass dort keinerlei Daten
 
im Klartext rumfliegen.
 
im Klartext rumfliegen.
  
Line 23: Line 23:
 
* USB-Stick fuer den Schluessel
 
* USB-Stick fuer den Schluessel
  
= Schluessel anlegen =
+
= Schlüssel anlegen =
  
 
USB-Stick ist unter /mnt/usb gemountet, der gpg Privatekey liegt unter /mnt/usb/.gnupg und
 
USB-Stick ist unter /mnt/usb gemountet, der gpg Privatekey liegt unter /mnt/usb/.gnupg und
Schluessel werden unter /mnt/usb/dm abgelegt. Die Keyid des GPG-Keys ist 0x12345678
+
Schluessel werden unter /mnt/usb/dm abgelegt. Die Key-ID des GPG-Keys ist 0x12345678
  
Dann erzeugt man einen Schluessel fuer 256Bit AES:
+
Dann erzeugt man einen Schluessel für 256Bit AES:
  
 
  $ export GNUPGHOME=/mnt/usb/.gnupg
 
  $ export GNUPGHOME=/mnt/usb/.gnupg
Line 35: Line 35:
 
= initramfs bauen =
 
= initramfs bauen =
  
Das Swap-Device, wohin nachher suspendet werden soll und was waehrend des Betriebs als
+
Das Swap-Device, wohin nachher suspendet werden soll und was während des Betriebs als
normaler (natuerlich encrypteter) Swap dient, ist /dev/sda3.  Beim Booten muss nun im
+
normaler (natürlich encrypteter) Swap dient, ist /dev/sda3.  Beim Booten muss nun im
 
initramfs der Key vom USB-Stick gelesen, decryptet und zum aufsetzen des Swaps verwendet
 
initramfs der Key vom USB-Stick gelesen, decryptet und zum aufsetzen des Swaps verwendet
 
werden.
 
werden.
Line 197: Line 197:
 
  fi
 
  fi
  
Danach wird fuer die aktuelle Kernelversion (hier 2.6.17) eine initramfs gebaut:
+
Danach wird für die aktuelle Kernelversion (hier 2.6.17) eine initramfs gebaut:
  
 
  $ update-initramfs -v -c -k 2.6.17
 
  $ update-initramfs -v -c -k 2.6.17
Line 217: Line 217:
 
  Adding module /lib/modules/2.6.17/kernel/drivers/acpi/thermal.ko
 
  Adding module /lib/modules/2.6.17/kernel/drivers/acpi/thermal.ko
  
Anschliessend muss der Kernel beim Booten noch ein paar Argumente (vor allem das
+
Anschließend muss der Kernel beim Booten noch ein paar Argumente (vor allem das
USB-Stick-Device, hier sbd1 (OHNE "/dev/"!)) und natuerlich das initramfs mitbekommen, im
+
USB-Stick-Device, hier sbd1 (OHNE "/dev/"!)) und natürlich das initramfs mitbekommen, im
Grub koennte das zb. so aussehen:
+
GRUB könnte das z.B. so aussehen:
  
 
  title 2.6.17-crypt RESUME
 
  title 2.6.17-crypt RESUME

Revision as of 02:30, 14 July 2006

Einleitung

Früher war alles besser, da hat sich noch das BIOS in einem Laptop um das Suspenden auf die Festplatte gekümmert. Heute haben alle Laptops ACPI, und das Betriebssystem muss sich selber kümmern. Das hat den Vorteil, dass man sich wirklich um alle Kleinigkeiten kümmern kann, aber gleichzeitig auch muss.

Das große Problem für den sicherheitsbewussten Anwender ist, dass der Inhalt des Arbeitsspeichers unverschlüsselt auf der Festplatte landet, und damit sämtliche Festplattenverschlüsselung ausgehebelt wird, da natürlich der Key für diese Verschlüsselung irgendwo im RAM liegt.

Dieses How-To will eine Anleitung sein, wie man unter Debian GNU/Linux (aktuell Etch/testing) auf eine verschlüsselte Festplatte suspendet, so dass dort keinerlei Daten im Klartext rumfliegen.

Voraussetzungen

  • Linux
  • Kernel mit Device-Mapper, crypt-Target und aes Support
  • installierte "initramfs-tools" und "gnupg" Packages
  • vorhandener GPG-Key
  • USB-Stick fuer den Schluessel

Schlüssel anlegen

USB-Stick ist unter /mnt/usb gemountet, der gpg Privatekey liegt unter /mnt/usb/.gnupg und Schluessel werden unter /mnt/usb/dm abgelegt. Die Key-ID des GPG-Keys ist 0x12345678

Dann erzeugt man einen Schluessel für 256Bit AES:

$ export GNUPGHOME=/mnt/usb/.gnupg
$ dd if=/dev/random bs=1 count=32 | gpg -r 0x1234568 -e > /mnt/usb/dm/secretkey

initramfs bauen

Das Swap-Device, wohin nachher suspendet werden soll und was während des Betriebs als normaler (natürlich encrypteter) Swap dient, ist /dev/sda3. Beim Booten muss nun im initramfs der Key vom USB-Stick gelesen, decryptet und zum aufsetzen des Swaps verwendet werden.

Dazu werden die entsprechenden Scripte und Hooks unter /etc/mkinitramfs installiert:

/etc/mkinitramfs/hooks/suspend2:

#!/bin/sh
#
# initramfs hooks file for encrypted suspend2

PREREQ=""

prereqs()
{
	echo "$PREREQ"
}

case $1 in
prereqs)
	prereqs
	exit 0
	;;
esac

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

manual_add_modules aes

copy_exec /usr/local/sbin/suspend2ui_fbsplash /sbin
copy_exec /usr/local/sbin/suspend2ui_text /sbin
copy_exec /usr/bin/gpg /bin
copy_exec /sbin/cryptsetup /sbin
copy_exec /bin/loadkeys /bin

# dump current keyboard layout
dumpkeys > ${DESTDIR}/conf/keymap

/etc/mkinitramfs/scripts/local-top/suspend2

#!/bin/sh
#
# initramfs script file for encrypted suspend2

# color functions

RED="�[31m"
GREEN="�[32m"
YELLOW="�[33m"
BLUE="�[34m"
NORMAL="�[0m"

warn() {
    echo "${YELLOW}$*${NORMAL}"
}

message() {
    echo "${GREEN}$*${NORMAL}"
}

error() {
    echo "${RED}error: $*${NORMAL}"
    echo "${RED}rebooting${NORMAL}"
    exit 0
}


# dependencies

PREREQ=""
prereqs()
{
echo "$PREREQ"
}

case $1 in
prereqs)
     prereqs
     exit 0
     ;;
esac

# Begin real processing below this line

. /scripts/functions

if [ -e /conf/keymap ]; then
    loadkeys /conf/keymap || warn "unable to load custom keymap"
fi

if [ ! "$swap" ]; then
    error "no swap partition, \$swap is empty!"
fi

if [ ! -x /sbin/cryptsetup ]; then
    error "no cryptsetup in /sbin??"
fi

if [ "$usb" -a "$no_swap" != "1" ]; then
    message "waiting for usb device \"$usb\""
    TIMEOUT=30
    while ! test -b /dev/$usb; do
        echo -n "."
        sleep 1
        TIMEOUT=$(($TIMEOUT -1))

        if [ "$TIMEOUT" = "0" ]; then
            error "timeout"
            break
        fi
    done

    echo "mounting usb"
    mkdir /usb
    mount -t vfat -o shortname=lower /dev/$usb /usb || error "unable to mount /dev/$usb to /usb"

    if [ ! "$keyfile" -o ! -e "/usb/$keyfile" ]; then
        error "\$keyfile (\"$keyfile\") empty or keyfile not found"
    fi

    echo "trying to setup swap using /usb"
    # tty fix
    rm /dev/tty
    ln -s /dev/console /dev/tty

    export GNUPGHOME=/usb/.gnupg
    gpg --decrypt /usb/$keyfile | cryptsetup -d /proc/self/fd/0 -c aes-cbc-essiv:sha256 -s 256 create swap $swap || error "cryptsetup failed"

    echo "umounting usb, remove now"
    umount /usb

else
    echo "${RED}please enter passphrase for device "$swap" ${NORMAL}"
    while ! cryptsetup -y -c aes create swap $swap; do
        warn "passphrases do not match, try again"
    done
fi

if [ "$do_resume" != "1" ]; then
    message "not resuming, \$do_resume is \"$do_resume\""
else

    message "waiting for swap mapper device"
    TIMEOUT=30
    while ! test -b /dev/mapper/swap; do
        echo -n "."
        sleep 1
        TIMEOUT=$(($TIMEOUT -1))

        if [ "$TIMEOUT" = "0" ]; then
            error "timeout"
            break
        fi
    done

    echo /usr/local/sbin/suspend2ui_text > /proc/suspend2/userui_program
    echo swap:/dev/mapper/swap > /proc/suspend2/resume2
    echo > /proc/suspend2/do_resume
fi

Danach wird für die aktuelle Kernelversion (hier 2.6.17) eine initramfs gebaut:

$ update-initramfs -v -c -k 2.6.17
Generating /boot/initrd.img-2.6.17
Adding module /lib/modules/2.6.17/updates/loop.ko
Adding module /lib/modules/2.6.17/kernel/crypto/aes.ko
Adding module /lib/modules/2.6.17/kernel/drivers/usb/core/usbcore.ko
Adding module /lib/modules/2.6.17/kernel/drivers/usb/host/ehci-hcd.ko
Adding module /lib/modules/2.6.17/kernel/drivers/usb/host/uhci-hcd.ko
Adding module /lib/modules/2.6.17/kernel/drivers/usb/input/usbhid.ko
Adding module /lib/modules/2.6.17/kernel/drivers/usb/storage/usb-storage.ko
Adding module /lib/modules/2.6.17/kernel/drivers/net/e1000/e1000.ko
Adding module /lib/modules/2.6.17/kernel/drivers/net/slhc.ko
Adding module /lib/modules/2.6.17/kernel/drivers/scsi/dpt_i2o.ko
Adding module /lib/modules/2.6.17/kernel/drivers/scsi/scsi_transport_fc.ko
Adding module /lib/modules/2.6.17/kernel/drivers/scsi/scsi_transport_spi.ko
Adding module /lib/modules/2.6.17/kernel/drivers/acpi/fan.ko
Adding module /lib/modules/2.6.17/kernel/drivers/acpi/processor.ko
Adding module /lib/modules/2.6.17/kernel/drivers/acpi/thermal.ko

Anschließend muss der Kernel beim Booten noch ein paar Argumente (vor allem das USB-Stick-Device, hier sbd1 (OHNE "/dev/"!)) und natürlich das initramfs mitbekommen, im GRUB könnte das z.B. so aussehen:

title		2.6.17-crypt RESUME
root		(hd0,0)
kernel		/vmlinuz-2.6.17-crypt root=/dev/sda2 ro swap=/dev/sda3 do_resume=1 usb=sdb1 acpi_sleep=s3_bios,s3_mode keyfile=/dm/secretkey
initrd          /initrd.img-2.6.17-crypt
boot

title		2.6.17-crypt NORMAL
root		(hd0,0)
kernel		/vmlinuz-2.6.17-crypt root=/dev/sda2 ro swap=/dev/sda3 do_resume=0 usb=sdb1 acpi_sleep=s3_bios,s3_mode keyfile=/dm/secretkey
initrd          /initrd.img-2.6.17-crypt
boot

title		2.6.17-crypt noinitrd
root		(hd0,0)
kernel		/vmlinuz-2.6.17-crypt root=/dev/sda2 ro acpi_sleep=s3_bios,s3_mode
boot

Suspenden

Suspendet wird dann auf /dev/mapper/swap, was vorher per mkswap initialisiert werden muss und dann auch als swap eingebunden werden kann.

fertig.