Minor spacing changes
[linux_from_scratch_hints.git] / crypt-rootfs.txt
blobfe1b320a10df026e251544168a7b399cc7c317f2
1 AUTHOR: Lars Bamberger <Lars.Bamberger at gmx dot de>
3 DATE: 2009-12-30
5 LICENSE: GNU Free Documentation License Version 1.2
7 SYNOPSIS: How to setup an encrypted file system including the rootfs.
9 DESCRIPTION:
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
13 straightforward way. 
16 PREREQUISITES:
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!
33 HINT:
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
60 2.2.1 devmapper
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.
72 2.2.3 busybox
74 Get it from http://www.busybox.net/
75 The minimum required configuration includes:
76 * cp
77 * hush (interactive shell not required)
78 * mount (with support for lots of -o flags) and
79 * switch_root.
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
96 the kernel.
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.
125 *** PITFALL ***
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
141    to access you data!
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.)
148    Do a
149    cryptsetup -c $cipher-algorithm luksFormat /dev/sd?? $keyfile
150    Replace '$cipher-algorithm', '/dev/sd??' and '$keyfile' with the
151    corresponding values.
152    
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
163    chose.
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.
170 9) Adjust /etc/fstab
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.
175    Example:
176    /dev/sda4         /home ext2 defaults 1 2
177    becomes
178    /dev/mapper/sda4  /home ext2 defaults 1 2
180 10) Mount the filesystem by 'mount /dev/mapper/sd??'
181     
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
196 partition(s).
198 Example:
200 #!/bin/sh
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
209 # Version     : 00.01
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 ########################################################################
218 . /etc/sysconfig/rc
219 . ${rc_functions}
220 PROC=/sbin/cryptsetup
222 case "${1}" in
223         start)
224                 boot_mesg "luksOpen Home..."
225                 $PROC -d /etc/crypt/home.key luksOpen /dev/sda4 sda4
226                 evaluate_retval
227         stop)
228                 boot_mesg "luksClose Home..."
229                 $PROC luksClose sda4
230                 evaluate_retval
231                 ;;
232         reload)
233                 boot_mesg "Reloading home..."
234                 $PROC reload sda4
235                 evaluate_retval
236                 ;;
237         restart)
238                 ${0} stop
239                 sleep 1
240                 ${0} start
241                 ;;
242         status)
243                 $PROC status sda4
244                 ;;
245         *)
246                 echo "Usage: ${0} {start|stop|reload|restart|status}"
247                 exit 1
248                 ;;
249 esac
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
260 expected. 
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
268 swap spaces. 
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
274 security feature.
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.
281 6. Encrypting rootfs 
282 ====================
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:
295 cp -a dev init-dev
296 In lib (and dev) put everything needed to run busybox and cryptsetup.
298 The init script is like this:
299 #!/bin/hush
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
312 boot.
314 *** PITFALL ***
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
319 tmpfs on /dev.
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
324 hush shell!
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
331 backup:
333 cryptsetup luksOpen /dev/sd?? sd??
334 $BACKUPROOTFS/mkefs.$TYPE /dev/mapper/sd??
335 mkdir /new-root
336 mount -t $FSTYPE /dev/mapper/sd?? /new-root
337 cp -a $BACKUPROOTFS /new-root
339 *** PITFALL ***
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
343 accordingly.
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
356 fstype.)
358 #!/bin/hush
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 $@
370 *** PITFALL ***
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?? ]];
378                 then
379                         boot_mesg "Making device for rootfs..."
380                         /bin/mknod -m 0600 /dev/mapper/sd?? b 254 0
381                         evaluate_retval;
382                 fi
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..."
397                 if
398                 [[ $(/bin/md5sum -b /dev/sd??) == \
399                 "$whatevermd5sum */dev/sd??" ]] \
400                         && \
401                 [[ $(/bin/sha1sum -b /dev/sd??) == \
402                 "$whatevensha1sum */dev/sd??" ]];
403                 then
404                         echo_ok;
405                 else
406                         echo_failure
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"
410         boot_mesg_flush
412 *** PITFALL ***
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
415 partition.
418 ACKNOWLEDGMENTS:
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
426 CHANGELOG:
427 [2009-12-30]
428   * Merged suggestions (typos, format and others) from Emmanuel Trillaud
429   * More verbosity on the boot partition size
430   * Some reformatting
431 [2009-11-23]
432   * list dependencies in the BLFS book
433 [2009-11-20]
434   * cryptsetup needs /dev/urandom
435   * mkefs might not work from initramfs
436   * update some URLs
437   * some minor touchups
438 [2009-02-15]
439   * Basic rewrite.
440 [2008-02-17]
441   * Initial hint.