ubuntuusers.de

Entschlüsseln mit einem USB-Schlüssel

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:

Artikel für fortgeschrittene Anwender

Dieser Artikel erfordert mehr Erfahrung im Umgang mit Linux und ist daher nur für fortgeschrittene Benutzer gedacht.

Wiki/Icons/secure_non.png So schön ein vollverschlüsseltes Ubuntu System auch ist, manchmal ist es schon sehr lästig, bei jedem Systemstart das Passwort für die Entschlüsselung eingeben zu müssen. Denn normalerweise greift hier das Prinzip: "Sicherheit und Benutzerkomfort schließen sich gegenseitig aus".

Diese Anleitung beschreibt, wie alternativ zum Passwort ein handelsüblicher USB-Stick als "Schlüssel" zum Freischalten des Systems verwenden kann, ohne dass auf diesem eine offensichtliche Schlüsseldatei angelegt werden muss.

Steckt der "richtige" USB-Stick beim Systemstart am Rechner, so wird die Festplatte automatisch entschlüsselt und das System startet ganz ohne Passworteingabe. Der USB-Stick kann weiterhin als Speichermedium verwendet werden – nur man selbst und der eigene Rechner wissen, dass es sich um einen "Schlüssel" handelt. Alternativ kann auch eine handelsübliche SD-Karte benutzt werden, wenn der Rechner mit einem Kartenleser ausgerüstet ist.

Hinweis:

Die Anleitung geht davon aus, dass bereits ein Ubuntu-System mit verschlüsselter root-Partition [1] installiert ist bzw. dass zwei oder mehr verschlüsselte Partitionen vorhanden sind. Die Option, die Festplatte mittels eines USB-Sticks oder einer SD-Karte als "Schlüssel" zu entsperren, wird dem System nachträglich hinzugefügt.

Das Passwort, das bei der Installation angegeben wurde, sollte unbedingt beibehalten werden. Der USB-Stick dient quasi nur als "Zweitschlüssel".

Achtung!

Datenverlust auf dem USB-Speicherstick respektive der SD-Karte ist möglich. Es sollte vorsichtshalber eine Sicherung der Daten gemacht werden.

Anfertigen des Schlüssels

Wenn man den USB-Stick nicht neu initialisieren bzw. formatieren will (Datenverlust!), dann gilt es einen freien Bereich zu finden, in dem man die Schlüsseldaten ablegen kann. Die meisten USB-Sticks haben ab Werk einen ausreichend großen freien Bereich zwischen dem "Master Boot Record" (MBR) und der ersten Partition.

Achtung!

Im Beispiel wird angenommen, dass der USB-Stick der Gerätedatei /dev/sdb entspricht. Die folgenden Befehle sind an die realen Verhältnisse anzupassen. Bei SD-Karten ist das häufig /dev/mmcblk0.

Am besten prüft man das im Terminal [2][3] nach (der USB-Stick muss dazu am Rechner stecken):

sudo fdisk -l /dev/sdb 
Platte /dev/sdb: 2051 MByte, 2051013632 Byte
...
Einheiten = Sektoren von 1 × 512 = 512 Bytes
...
Gerät  boot.     Anfang        Ende     Blöcke   Id  System
/dev/sdb1   *          62     4003711     2001825    c  W95 FAT32 (LBA)

In diesem Fall ist also der Bereich von Sektor 2 bis Sektor 61 ungenutzt, also 60 * 512 Byte = 30 KiB. Da das für den Schlüssel mehr als ausreicht, wird dieser Platz benutzt. Für den Schlüssel selbst brauchen wir nur ca. 4 bis 6 Sektoren, damit der Schlüsselbereich aber einem eventuellen "neugierigen Angreifer" nicht sofort ins Auge sticht, wird ein deutlich größerer Bereich mit Zufallszahlen initialisiert [4].

sudo dd if=/dev/urandom of=/dev/sdb bs=512 seek=1 count=60 
60+0 Datensätze ein
60+0 Datensätze aus
30720 Bytes (31 kB) kopiert, 0,00665825 s, 4,6 MB/s

Der Schlüssel ist jetzt fertig. Am besten lässt man ihn aber noch am Rechner stecken, denn er wird gleich wieder gebraucht.

Vorbereiten des Schlosses

Jetzt hat man zwar einen Schlüssel, aber nun gilt es sicherzustellen, dass dieser auch "sperrt". Dazu muss erst einmal festgelegt werden, welcher Bereich der oben generierten Zufallszahlen als Luks-Schlüssel [5] dienen soll.

Im Beispiel steht ein Bereich von 60 Sektoren, beginnend bei Sektor 2 zur Verfügung. Es wird nun der Bereich von Sektor 2 bis Sektor 5 als Luks-Schlüssel festgelegt, d.h. 4 Sektoren à 512 Byte = 2048 Byte, direkt anschließend an den MBR.

Hinweis:

Sollen mehrere USB-Schlüssel für den gleichen Rechner benutzt werden, ist sicherzustellen, dass exakt der selbe Bereich auf allen USB-Schlüsseln als Luks-Schlüssel benutzt werden kann.

Achtung!

Im Beispiel wird angenommen, dass die verschlüsselte Partition über die Gerätedatei /dev/sda5 und der USB-Stick über die Gerätedatei /dev/sdb zu finden ist. Der Befehl ist an die realen Verhältnisse anzupassen.

Nun wird der verschlüsselten Platte der Schlüssel hinzugefügt:

sudo dd if=/dev/sdb bs=512 skip=1 count=4 > tempKeyFile.bin 
4+0 Datensätze ein
4+0 Datensätze aus
2048 Bytes (2,0 kB) kopiert, 7,8013e-05 s, 26,3 MB/s
sudo cryptsetup luksAddKey /dev/sda5 --key-file=- tempKeyFile.bin 
Geben Sie irgendeinen Passsatz ein:

Wer will, kann die Datei tempKeyFile.bin für späteren Gebrauch an einem sicheren Ort aufbewahren. Sie wird aber hier nicht mehr gebraucht und kann jetzt gelöscht werden:

sudo rm -f tempKeyFile.bin 

Das "Schloss" ist jetzt auch fertig vorbereitet. Jetzt muss das System so eingestellt werden, dass es beim Systemstart selbstständig "den Schlüssel im Schloss umdreht".

Vorbereiten eines zweiten Schlosses

Wenn man mehrere LVM verschlüsselte Partitionen hat, wie etwa eine verschlüsselte Root-Partition und eine separate, ebenfalls verschlüsselte Home-Partition, so muss ein zweiter Schlüssel erzeugt werden. Diesmal wird bei "skip=" 4 eingetragen, damit der bereits zuvor erstellte Schlüssel, der bis Sektor 4 geht, nicht überschrieben wird. Außerdem muss der Dateiname der Schlüsseldatei auf tempKeyFile2.bin geändert werden.

Achtung!

Wenn man jedoch nur eine verschlüsselte Partition hat, dann bitte diese Schritte bis zum nächsten Punkt überspringen.

Schlüsseldatei erzeugen:

sudo dd if=/dev/sdb bs=512 skip=4 count=4 > tempKeyFile2.bin 
4+0 Datensätze ein
4+0 Datensätze aus
2048 Bytes (2,0 kB) kopiert, 7,8013e-05 s, 26,2 MB/s

Achtung!

In diesem Beispiel wird davon ausgegangen, dass die Home-Partition den Pfad /dev/sda6 hat. Dieser Wert muss natürlich angepasst werden, wenn er vom Beispiel abweicht.

Neuen Schlüssel mit Schlüsseldatei hinzufügen.

sudo cryptsetup luksAddKey /dev/sda6 --key-file=tempKeyFile2.bin 
Geben Sie irgendeinen Passsatz ein:

Auch der zweite Schlüssel kann gelöscht werden, wenn man ihn nicht weiter aufbewahren will.

sudo rm -f tempKeyFile2.bin 

Anlegen der nötigen Konfigurationsdateien

Es gilt nun dem System beizubringen, woran es einen Schlüssel erkennen soll, und die getroffenen Festlegungen bezüglich der Position des Luks-Schlüssels mitzuteilen. Dafür legt man zunächst ein eigenes Konfigurationsverzeichnis unter /etc/ an.

sudo mkdir /etc/decryptkeydevice 

In diesem Ordner erstellt man nun mit Root-Rechten zwei Dateien [6]. Zum einen die Konfiguration /etc/decryptkeydevice/decryptkeydevice.conf selbst. Hier werden alle getroffenen Festlegungen eingetragen. Beispiel:

  • der Luks-Schlüssel startet bei Sektor 2, es wird also 1 Sektor übersprungen:

    DECRYPTKEYDEVICE_SKIPBLOCKS="1"
  • Der Luks-Schlüssel im Beispiel ist 4 Sektoren lang:

    DECRYPTKEYDEVICE_READBLOCKS="4"
  • Sektorgröße 512 Byte passt eigentlich immer:

    DECRYPTKEYDEVICE_BLOCKSIZE="512"
  • Welche USB-Speichersticks bzw. SD-Karten Schlüssel sind:

    DECRYPTKEYDEVICE_DISKID="mmc-XXX_0x0AAABBBCCCDDD   usb-XyzFlash_XYZDFGHIJK_XXYYZZ00AA-0:0"

Die Schlüssel sollen dabei anhand ihrer vom System vergebenen Disk-ID erkannt werden. Die Disk-ID(s) des(der) verwendeten Schlüssel(s) werden mit Leerzeichen getrennt in der Zeile DECRYPTKEYDEVICE_DISKID=" " eingetragen.

Die Disk-ID des verwendeten USB-Sticks ermittelt der folgenden Befehl:

sudo ls -l /dev/disk/by-id 
lrwxrwxrwx 1 root root 13 2011-12-20 21:27 mmc-XXX_0x0AAABBBCCCDDD -> ../../mmcblk0
lrwxrwxrwx 1 root root 15 2011-12-20 21:27 mmc-XXX_0x0AAABBBCCCDDD-part1 -> ../../mmcblk0p1
...
lrwxrwxrwx 1 root root  9 2011-12-20 21:36 usb-XyzFlash_XYZDFGHIJK_XXYYZZ00AA-0:0 -> ../../sdb
lrwxrwxrwx 1 root root 10 2011-12-20 21:36 usb-XyzFlash_XYZDFGHIJK_XXYYZZ00AA-0:0-part1 -> ../../sdb1

Verwendet wird nur die Disk-ID des "rohen" Geräts, also im Beispiel die von sdb und nicht die von sdb1. Für die SD-Karte ist das dementsprechend mmcblk0 und nicht mmcblk0p1. Diese Disk-IDs werden zusammen mit den anderen Daten gespeichert. Beispiel der Datei /etc/decryptkeydevice/decryptkeydevice.conf:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# configuration for decryptkeydevice
#

# ID(s) of the USB/MMC key(s) for decryption (sparated by blanks)
# as listed in /dev/disk/by-id/
DECRYPTKEYDEVICE_DISKID="mmc-XXX_0x0AAABBBCCCDDD usb-XyzFlash_XYZDFGHIJK_XXYYZZ00AA-0:0"

# blocksize usually 512 is OK
DECRYPTKEYDEVICE_BLOCKSIZE="512"

# start of key information on keydevice DECRYPTKEYDEVICE_BLOCKSIZE * DECRYPTKEYDEVICE_SKIPBLOCKS
DECRYPTKEYDEVICE_SKIPBLOCKS="1"

# length of key information on keydevice DECRYPTKEYDEVICE_BLOCKSIZE * DECRYPTKEYDEVICE_READBLOCKS
DECRYPTKEYDEVICE_READBLOCKS="4"

Nun fehlt noch die zweite Datei, und zwar ein "Key-Skript" für cryptsetup. Dieses kleine Skript wird dann beim Systemstart aufgerufen, um das System zu entschlüsseln. Inhalt von /etc/decryptkeydevice/decryptkeydevice_keyscript.sh:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/bin/sh
#
# original file name crypto-usb-key.sh
# heavily modified and adapted for "decryptkeydevice" by Franco
#
### original header :
#
# 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

# Updated by Dominique Bellenger <dev at domesdomain dot de>
# for usage with Ubuntu 10.04 Lucid Lynx
# - Removed non working USB device check
# - changed vol_id to blkid, changed sed expression
# - changed TRUE and FALSE to be 1 and 0
# - changed usplash usage to plymouth usage
# - removed possibility to read from an encrypted device (why would I want to do this? The script is unnecessary if I have to type in a password)
#
### original header END

# read decryptkeydevice Key configuration settings
DECRYPTKEYDEVICE_DISKID=""
if [ -f /etc/decryptkeydevice/decryptkeydevice.conf ] ; then
		.  /etc/decryptkeydevice/decryptkeydevice.conf
fi

TRUE=1
FALSE=0

# set DEBUG=$TRUE to display debug messages, DEBUG=$FALSE to be quiet
DEBUG=$FALSE

PLYMOUTH=$FALSE
# test for plymouth and if plymouth is running
if [ -x /bin/plymouth ] && plymouth --ping; then
        PLYMOUTH=$TRUE
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 0 ]; then
	STTY=$TRUE
	STTYCMD="busybox stty"
fi

# print message to plymouth or stderr
# usage: msg "message" [switch]
# switch : switch used for echo to stderr (ignored for plymouth)
# when using plymouth the command will cause "message" to be
# printed according to the "plymouth message" 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 [ $PLYMOUTH -eq $TRUE ]; then
				/bin/plymouth message --text="$1 $LINE"		
			#else
				# use stderr for all messages
				echo $3 "$2" >&2
			fi
		done
	fi
}

dbg ()
{
	if [ $DEBUG -eq $TRUE ]; then
		msg "$@"
	fi
}

# read password from console or with plymouth
# usage: readpass "prompt"
readpass ()
{
	if [ $# -gt 0 ]; then
		if [ $PLYMOUTH -eq $TRUE ]; then
			PASS=`/bin/plymouth ask-for-password --prompt="$1"`
		else
			[ $STTY -ne $TRUE ] && msg "WARNING stty not found, password will be visible"
			echo -n "$1" >&2
			$STTYCMD -echo
			read -s PASS </dev/console >/dev/null
			[ $STTY -eq $TRUE ] && echo >&2
			$STTYCMD echo
		fi
	fi
	echo -n "$PASS"
}

# flag tracking key-file availability
OPENED=$FALSE

# decryptkeydevice configured so try to find a key
if [ ! -z "$DECRYPTKEYDEVICE_DISKID" ]; then
	msg "Checking devices for decryption key ..."
	# Is the USB driver loaded?
	cat /proc/modules | busybox grep usb_storage >/dev/null 2>&1
	USBLOAD=0$?
	if [ $USBLOAD -gt 0 ]; then
		dbg "Loading driver 'usb_storage'"
		modprobe usb_storage >/dev/null 2>&1
	fi
	# Is the mmc_block driver loaded?
	cat /proc/modules | busybox grep mmc >/dev/null 2>&1
	MMCLOAD=0$?
	if [ $MMCLOAD -gt 0 ]; then
		dbg "Loading drivers for 'mmc'"
		modprobe mmc_core >/dev/null 2>&1
		modprobe ricoh_mmc >/dev/null 2>&1
		modprobe mmc_block >/dev/null 2>&1
		modprobe sdhci >/dev/null 2>&1
	fi

	# give the system time to settle and open the devices
	sleep 5

	for DECRYPTKEYDEVICE_ID in $DECRYPTKEYDEVICE_DISKID ; do
		DECRYPTKEYDEVICE_FILE="/dev/disk/by-id/$DECRYPTKEYDEVICE_ID"
		dbg "Trying disk/by-id/$DECRYPTKEYDEVICE_FILE ..."
		if [ -e $DECRYPTKEYDEVICE_FILE ] ; then
			dbg " found disk/by-id/$DECRYPTKEYDEVICE_FILE ..."
			OPENED=$TRUE
			break
		fi
		$DECRYPTKEYDEVICE_FILE=""
	done
fi

if [ $OPENED -eq $TRUE ]; then
	/bin/dd if=$DECRYPTKEYDEVICE_FILE bs=$DECRYPTKEYDEVICE_BLOCKSIZE skip=$DECRYPTKEYDEVICE_SKIPBLOCKS count=$DECRYPTKEYDEVICE_READBLOCKS 2>/dev/null
	if [ $? -eq 0 ] ; then
		dbg "Reading key from '$DECRYPTKEYDEVICE_FILE' ..."
	else
		dbg "FAILED Reading key from '$DECRYPTKEYDEVICE_FILE' ..."
		OPENED=$FALSE
	fi
fi

if [ $OPENED -ne $TRUE ]; then
	msg "FAILED to find suitable Key device. Plug in now and press enter, or"
	readpass "Enter passphrase: "
	msg " "
else
	msg "Success loading key from '$DECRYPTKEYDEVICE_FILE'"
fi

Diese Datei muss ausführbar sein:

sudo chmod +x /etc/decryptkeydevice/decryptkeydevice_keyscript.sh 

Hinweis:

Wenn mehrere Schlüssel für den gleichen Rechner benutzt werden und beim Systemstart gleichzeitig angesteckt sind, wird nur der zuerst gefundene USB-Schlüssel benutzt.

Dies ist kein Problem, da zum Entschlüsseln der Platte nur ein gültiger Schlüssel benötigt wird.

Anpassen von /etc/crypttab

Jetzt muss dem System noch mitgeteilt werden, dass das eben erstellte "Key-Skript" auch zum Entschlüsseln der Partition verwendet werden soll. Zu diesem Zweck wird in die Datei /etc/crypttab die Option "keyscript=/etc/decryptkeydevice/decryptkeydevice_keyscript.sh" eingefügt. Beispiel:

# <target name>	<source device>		<key file>	<options>
lvm UUID=xxYYzz0011-xyz4-1x2y-xxx-xyxyxyxyxyxyzzz none luks,tries=3,keyscript=/etc/decryptkeydevice/decryptkeydevice_keyscript.sh

Bei zwei verschlüsselten Partitionen, muss auch beim zweiten Eintrag, die Option "keyscript=/etc/decryptkeydevice/decryptkeydevice_keyscript.sh" eingefügt werden.

# <target name>	<source device>		<key file>	<options>
lvm UUID=xxYYzz0011-xyz4-1x2y-xxx-xyxyxyxyxyxyzzz none luks,tries=3,keyscript=/etc/decryptkeydevice/decryptkeydevice_keyscript.sh
lvm UUID=xxYYzz0012-xyz5-2x3y-xxx-yxyxyxyxyxyxzzz none luks,tries=3,keyscript=/etc/decryptkeydevice/decryptkeydevice_keyscript.sh

Konfiguration des initramfs

Jetzt muss die oben vorgenommene Anpassung noch in das initramfs integriert werden, denn der Schlüssel soll schließlich schon beim Systemstart gefunden und benutzt werden. Dazu legt man einen sog. "hook" an: ein Skript, das die benötigten Dateien in das initramfs "zieht". Inhalt der Datei /etc/initramfs-tools/hooks/decryptkeydevice.hook:

1
2
3
4
5
6
#!/bin/sh
# copy decryptkeydevice files to initramfs
#

mkdir -p $DESTDIR/etc/
cp -rp /etc/decryptkeydevice $DESTDIR/etc/

Diese Datei muss ausführbar sein:

sudo chmod +x /etc/initramfs-tools/hooks/decryptkeydevice.hook 

Damit sind alle Vorbereitungen abgeschlossen.

Neues initramfs erzeugen

Achtung!

Ein beschädigtes initramfs kann dazu führen, dass sich das System nicht mehr starten lässt.

Es wird dringend empfohlen, eine Kopie des originalen initramfs in der /boot/ Partion anzulegen, damit man im Notfall damit das System wieder starten kann.

Als letzter Schritt muss nur noch das neue initramfs erzeugt werden:

sudo update-initramfs -k `uname -r` -c 

Beim nächsten Neustart wird der USB-Key dann automatisch erkannt und die Platte entschlüsselt.

Abschließende Anmerkungen

Es existieren etliche unterschiedliche Anleitungen für die Verwendung von USB-Sticks zum automatischen Entsperren des Systems während des Startvorgangs. Die hier vorgestellte Methode unterscheidet sich von den meisten anderen vor allem dadurch, dass auf dem als Schlüssel verwendeten USB-Stick keine offensichtliche Schlüsseldatei angelegt wird. Ein Finder eines verlorengegangenen USB-Sticks wird nicht vermuten, dass es sich um einen Schlüssel handelt.

Der Einfachheit halber sind alle hier vorgestellten Dateien in ein tar.gz-Archiv gepackt, das sich als decryptkeydevice.tar.gz {dl} herunterladen lässt.

Diese Revision wurde am 14. April 2013 18:18 von frustschieber erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: Systemverschlüsselung, Sicherheit, Vollverschlüsselung, Installation, System