1 AUTHOR: Lars Bamberger <Lars.Bamberger at gmx dot de>
5 LICENSE: GNU Free Documentation License Version 1.2
7 SYNOPSIS: How to setup an encrypted file system including the rootfs.
10 This describes one possible way of encrypting your hard drive, including the
11 root file system. It is intended for experienced users and tries to
12 circumnavigate the pitfalls of encrypting your root file system in a
17 This hint requires that you have sufficient knowledge of BeyondLinuxFromScratch
18 and reasonably up to date software. You must be comfortable building software,
19 finding, reading and understanding other pertinent documentation.
20 You must know how to set up an initramfs. (See
21 'filesystems/ramfs-rootfs-initramfs.txt' in the kernel's documentation.)
22 You must be aware why you'd want an encrypted file system and you must
23 understand the nature of the threat you're trying to protect yourself against.
24 You must also understand shortcomings and security issues if you follow the
25 instructions contained in this hint.
27 You must have a complete backup of you system somewhere safe! That includes an
28 alternative boot device.
30 You ABSOLUTELY MUST READ AND UNDERSTAND THIS HINT BEFORE YOU MODIFY YOUR SYSTEM!
35 1. What is this about?
36 ======================
38 This is about encrypting all but one of your hard drive partitions using LUKS
39 for dm-crypt. We'll boot from one small unencrypted partition using initramfs in
40 order to decrypt the rootfs.
41 This hint assumes that a small partition from where to boot from is already set
42 up. This partition should be 10 to 15 MB in size in order to store more than
43 one kernel and more than one initramfs image for testing and upgrading
44 purposes. Avoid any larger partition because during every boot we'll calculate
45 a checksum for this partition, a time consuming process.
48 2. Required software and dependencies
49 =====================================
51 2.1 Software in the BLFS book
53 You need to install 'Popt' as 'cryptsetup' depends on this.
54 Furthermore you need 'uuencode' to create key files. 'uuencode' is included in
55 'sharutils' and 'GMime' which has further dependencies mentioned in the BLFS
56 book. To create the initramfs, you need 'Cpio'.
58 2.2 Software not in the BLFS book
62 Get it from http://packages.debian.org/stable/source/devmapper
63 Compile and install it. Required for 'cryptsetup'.
66 2.2.2 cryptsetup with LUKS extension
68 Get it from http://code.google.com/p/cryptsetup/
69 Compile and install it. Required to handle encrypted partitions.
74 Get it from http://www.busybox.net/
75 The minimum required configuration includes:
77 * hush (interactive shell not required)
78 * mount (with support for lots of -o flags) and
81 Compile it, but DO NOT install it. Keep the binary and name it
82 'busybox-minimum'. Next, reconfigure busybox for a full-blown desktop system.
83 You will need all the standard tools and utilities for the purpose of initially
84 encrypting your root partition and for troubleshooting. (Don't forget 'mkefs'.)
85 Name this binary 'busybox-large' or something similar. Again, it is not
86 required to install it.
89 3. Recompiling the kernel
90 =========================
92 Decide what algorithm you would like to use to encrypt your hard drive
93 with. Note that this is a crucial decision and you should read more background
94 information on this. (See ACKNOWLEDGMENTS below.)
95 The appropriate modules need to be compiled (hard-coded, not as modules) into
97 As an example you could use the "twofish-cbc-essiv:sha256" method.
99 Also, from the 'Device Drivers' -> 'Multiple devices driver support' menu in
100 the kernel configuration, select the 'Device mapper support' and the 'Crypt
101 target support' as well.
103 Under 'Device Drivers' -> 'Block devices', select 'RAM block device support'
104 and from 'General setup', select 'Initial RAM filesystem and RAM disk'.
106 NOTE: You must boot this new kernel before proceeding.
109 4. Encrypting partitions partitions other than rootfs and other than swap
110 =========================================================================
112 You need to modify your system in order for it to be able to handle encrypted
113 partitions. In the first step, we modify the system so that it can handle
114 encrypted partitions OTHER than the rootfs. It is strongly suggested that you
115 keep a backup of all files you modify in the process.
117 4.1 Encrypting the partitions
119 NOTE: This document describes how to encrypt every partition separately. If you
120 have more than one HDD in your system, you might consider encrypting the
121 whole device including the partition table. Using the method described in
122 this document leaves the partition table unencrypted and thus may be
123 exposed to an attack. Consider this a potential security risk.
126 If /usr is a separate partition, cryptsetup and all libraries needed to run
127 cryptsetup must be on the root partition. Use 'ldd cryptsetup' to find out.
128 It may be necessary to switch to runlevel 1 because you need to be able to
129 unmount /usr. Also, make sure that root's shell does not use any libs on that
130 partition. If required, compile a statically linked shell for root's use.
132 The process is as follows for every partition:
134 1) Create as many keys as you like for the partition, for example:
135 head -c 2880 /dev/urandom | uuencode -m - | head -n-1 | tail -n+2 > keyfile
136 or use an easy to remember passphrase.
138 2) Make a secure backup of your keys and secure the keyfile by 'chmod 0400' or
139 so. Your backup keys must be absolutely secure (i.e. not on your computer).
140 Remember: If you lose your key, you will absolutely, definitely NOT be able
143 3) Make a backup of the data on the partition.
145 4) Un-mount the partition.
147 5) Create an encrypted partition. (All data will be lost on that partition.)
149 cryptsetup -c $cipher-algorithm luksFormat /dev/sd?? $keyfile
150 Replace '$cipher-algorithm', '/dev/sd??' and '$keyfile' with the
151 corresponding values.
153 6) Optionally, add more keys to the partition. Do a
154 cryptsetup -y -d $keyfile luksAddKey /dev/sd??
155 Replace '$keyfile' with the same as above and '/dev/sd??' with the
156 corresponding partition.
158 7) Open the encrypted partition. Do a
159 cryptsetup -d $keyfile luksOpen /dev/sd?? sd??
160 Replace '$keyfile' and '/dev/sd??' with the corresponding values. Replace
161 'sd??' with a meaningful name. If everything worked out, the unencrypted
162 partition will appear as '/dev/mapper/sd??' with sd?? being the name you
165 8) Create a filesystem on the partition. Do a
166 mkefs.$WHATEVER /dev/mapper/sd??
167 Replace '$WHATEVER' with the type of filesystem you would like to use
168 (e.g. ext2) and '/dev/mapper/sd??' with the corresponding partition.
171 Because the device for the partition has changed, you need to
172 tell the system where to find it. Change the device by inserting
173 "mapper/" in the device field.
176 /dev/sda4 /home ext2 defaults 1 2
178 /dev/mapper/sda4 /home ext2 defaults 1 2
180 10) Mount the filesystem by 'mount /dev/mapper/sd??'
182 11) Copy the data back to the partition.
185 4.2 Making the system automatically decrypt and mount the partition(s)
187 Create a bootscript that will decrypt your encrypted partition. It is assumed
188 that the passphrases are stored in /etc/crypt for example. Note that storing the
189 passphrases on disk might pose a security problem! Use the template for
190 bootscripts included with BLFS and make it do:
192 /sbin/cryptsetup -d /etc/crypt/$PARTITION.key luksOpen \
193 /dev/$PARTITION $PARTITION
195 for every encrypted partition other than the root partition and the swap
201 ########################################################################
202 # Begin $rc_base/init.d/cryptsetup
204 # Description : Make encrypted filesystems available for mounting
205 # And clean up afterwards
207 # Authors : Lars Bamberger
211 # Notes : This should never be automatically called with any
212 # argument other than "start". During shutdown and reboot,
213 # it is sufficient to umount the filesystems. /dev/mapper/*
214 # will be gone when the kernel stops or reboots.
216 ########################################################################
220 PROC=/sbin/cryptsetup
224 boot_mesg "luksOpen Home..."
225 $PROC -d /etc/crypt/home.key luksOpen /dev/sda4 sda4
228 boot_mesg "luksClose Home..."
233 boot_mesg "Reloading home..."
246 echo "Usage: ${0} {start|stop|reload|restart|status}"
250 # End $rc_base/init.d/cryptsetup
252 Now, before proceeding, make sure everything works as expected up until now.
253 Become familiar with encrypting your partitions this way.
254 Make an appropriate softlink so that this script is called at boottime:
256 # cd /etc/rc.d/rcsysinit.d
257 # ln -s ../init.d/cryptsetup S19cryptsetup
259 Double-check everything so that booting, rebooting, shutting down etc. works as
263 5. A word about encrypting the swap partition(s)
264 ================================================
266 Do not omit encrypting your swap partitions. Lot's of interesting data can be
267 found on swap spaces. Do not consider you data safe if you don't use encrypted
269 In theory, the data on the swap partition(s) does not need to be consistent
270 between reboots. This means we could create a swap space anew during boottime,
271 using a random (and thus different) cryptokey every time the system boots. This
272 way you don't have to bother with managing swap's cryptokeys and you won't have
273 to store them anywhere (except in memory). This can be considered an additional
275 However, if you suspend your system (either to RAM or to disk), data in
276 swap space must remain consistent. Therefore you have to treat the swap
277 partition(s) just as if they were a regular partition, meaning you should
278 encrypt them like explained above.
284 You can't just encrypt the rootfs the way the other partitions were encrypted
285 because the system is running on it. The idea is to create an initramfs
286 containing everything you need to encrypt (and decrypt) the rootfs. (Details can
287 be found in the kernel's documentation:
288 'filesystems/ramfs-rootfs-initramfs.txt'.)
290 You'll need the standard directories (bin, sbin, usr/{bin,sbin}, proc, sys,
291 dev, lib). In bin we put our busybox-large (rename to busybox) and a softlink to
292 busybox named hush. Copy cryptsetup to sbin.
293 In dev put some useful devices: console, null, urandom, sd?? and a directory
294 'mapper' containing 'control'. Then make a copy of dev:
296 In lib (and dev) put everything needed to run busybox and cryptsetup.
298 The init script is like this:
300 /bin/busybox mount -t proc proc /proc
301 /bin/busybox mount -t sysfs sysfs /sys
302 /bin/busybox mount -t tmpfs tmpfs /dev
303 /bin/busybox cp -a /init-dev/* /dev
304 /bin/busybox --install -s
305 exec /bin/busybox hush
307 Put all this into one directory (init goes there as well and not into sbin). Cd
308 into this directory and create the image using
309 find . | cpio --quiet -H newc -o | gzip -9 -n > /boot/initramfs.img
310 Pass the appropriate initrd argument (e.g. initrd (hd0,0)/initramfs.img) to the
311 kernel when booting and this will drop you into the hush shell after system
315 Cryptsetup needs /proc and /sys mounted. It also requires the /dev directory.
316 As we want to save /dev when we switch_root later, we mount it as tmpfs. This
317 means that the devices in /dev will be gone, so copy them back into /dev. Be
318 aware that you need at least 'null' and 'console' in /dev before mounting
321 Once in the shell, encrypt your rootfs like any other partition as described
322 above. Don't forget the backup! ABSOLUTELY, POSITIVELY make certain that you are
323 able to mount and access the unencrypted backup of the rootfs from within the
326 Next, create the encrypted root partition. Note that the passphrase won't be
327 stored anywhere on disk, so do:
328 cryptsetup -y -c $cipher-algorithm luksFormat /dev/sd??
329 to create the encrypted rootfs. Replace '$cipher-algorithm' and '/dev/sd??' with
330 the respective values. Next, open the partition, format it and recover the
333 cryptsetup luksOpen /dev/sd?? sd??
334 $BACKUPROOTFS/mkefs.$TYPE /dev/mapper/sd??
336 mount -t $FSTYPE /dev/mapper/sd?? /new-root
337 cp -a $BACKUPROOTFS /new-root
340 Since your old rootfs isn't mounted, you might not be able to to run 'mkefs' do
341 to missing libraries. Either copy everything needed to where the linker can
342 find it, or use the 'mkefs' from busybox. Be sure to configure busybox
345 Next, modify /etc/fstab (on /new-root) to reflect the new device for the rootfs.
346 Also modify the cryptsetup script as described below (7. PITFALL).
349 7. Decrypting the rootfs on subsequent boots
350 ============================================
352 Like in 6., create an initramfs. The difference is that now the
353 "busybox-minimum" binary is used and you'll need an additional directory
354 new-root. Don't forget the 'hush' softlink.
355 The init is like this: (Replace 'sd??' with your root-device and adjust for the
359 /bin/busybox mount -t proc proc /proc
360 /bin/busybox mount -t sysfs sysfs /sys
361 /bin/busybox mount -t tmpfs tmpfs /dev
362 /bin/busybox cp -a /init-dev/* /dev
363 /sbin/cryptsetup luksOpen /dev/sd?? sd??
364 /bin/busybox mount -r -t ext2 /dev/mapper/sd?? /new-root
365 /bin/busybox mount --move /proc /new-root/proc
366 /bin/busybox mount --move /sys /new-root/sys
367 /bin/busybox mount --move /dev /new-root/dev
368 exec /bin/busybox switch_root /new-root /sbin/init $@
371 You want to keep /proc, /sys and /dev after switch_root because cryptsetup uses
372 them. Hence the 'mount --move' commands. Note that /dev/mapper/sd?? (the root
373 device) will be gone once you mount the true root partition, switch_root and the
374 rootfs proper starts udev. That's the reason why this device needs to be
375 recreated. So, modify the cryptsetup bootscript to include
377 if [[ ! -b /dev/mapper/sd?? ]];
379 boot_mesg "Making device for rootfs..."
380 /bin/mknod -m 0600 /dev/mapper/sd?? b 254 0
384 in the start section of the script.
387 8. Making sure security is not compromised
388 ==========================================
390 Once everything works as it should, remove the unencrypted backup of your
391 rootfs. Protect your bootloader (and possibly the BIOS) with a password to
392 disable unauthorized fiddling with the boot parameters.
393 Create a bootscript (checkbootfs) that makes sure that the unencrypted partition
394 we booted from was not compromised. Use something like:
396 boot_mesg "Checking integrity of boot FS..."
398 [[ $(/bin/md5sum -b /dev/sd??) == \
399 "$whatevermd5sum */dev/sd??" ]] \
401 [[ $(/bin/sha1sum -b /dev/sd??) == \
402 "$whatevensha1sum */dev/sd??" ]];
407 boot_mesg -n "FAILURE:\n\nThe boot file system seems to have been
408 altered!\n\n" ${FAILURE}
409 boot_mesg -n " DO NOT TRUST THIS SYSTEM!\n\n"
413 Make sure this is the very last thing you implement, as the hashsums will
414 change as we go on. The hashsums will also change if you run a fsck on the boot
419 * Emmanuel Trillaud for some suggestions and pointers.
420 * Various for the Gentoo-Wiki at
421 http://en.gentoo-wiki.com/wiki/DM-Crypt_with_LUKS
422 * Clemens Fruhwirth (http://clemens.endorphin.org/) for LUKS for dm-crypt:
423 http://code.google.com/p/cryptsetup
428 * Merged suggestions (typos, format and others) from Emmanuel Trillaud
429 * More verbosity on the boot partition size
432 * list dependencies in the BLFS book
434 * cryptsetup needs /dev/urandom
435 * mkefs might not work from initramfs
437 * some minor touchups