Gentoo Wiki ArchivesGentoo Wiki

SECURITY_Encrypting_Root_Filesystem_with_DM-Crypt

This article is part of the Security series.


Please format this article according to the guidelines and Wikification suggestions, then remove this notice {{Wikify}} from the article


Contents

Introduction

There're probably many threads out there on how to encrypt your root file system. And I'm probably a n00b, but anyway, here is my mini-contribution. Make sure you backup your system first, and if you trash it (highly probable!) then don't blame me.

Update: The newer method of doing this is using LUKS:

Assumptions

  1. Kernel 2.6.6: disk driver builtin, ext2/reiserfs filesystem drivers builtin, device mapper/encryption modules dm-crypt/dm-mod builtin, aes builtin, ramdisk and initial ramdisk (initrd) builtin.
Linux Kernel Configuration: Kernel 2.6.6
File systems  --->
  <*> Second extended fs support
  <*> Reiserfs support
Device Drivers  --->
  Block devices  --->
    <*> Loopback device support
    < >   Cryptoloop Support
    (4096) Default RAM disk size (kbytes)
    [*]   Initial RAM disk (initrd) support
  Multi-device support (RAID and LVM)  --->
    <*>   Device mapper support
    <*>     Crypt target support
Cryptographic options  --->
    <*>   AES cipher algorithms (i586)
  1. Boot partition on /dev/hda1 filesystem is ext2.
  2. Root partition on /dev/hda2 filesystem is reiserfs.
  3. You will be prompted for encryption passphrase at boot time.
  4. You are using udev.
  5. You are using grub boot loader.
  6. You're logged in as root.

Requirements

You'll need to emerge device-mapper:

emerge device-mapper

You'll need to download and install cryptsetup available at http://www.saout.de/misc/dm-crypt/:

emerge cryptsetup


If you have udev you will also need the multipath-tools

emerge multipath-tools

Creating the Initrd Image

Now we need to create our initrd, I'll call it myinitrd. It's a simple task once you played around a bit with it. I highly recommed playing with initrd's before you go actually and encrypt your root (last step in this mini-howto). First create the image, I'm using a 4MB initrd but feel free to expand that if you need more, just remember to set the option in your kernel configuration for the maximum ramdisk size properly.

cd /mnt
touch myinitrd
dd if=/dev/zero of=myinitrd bs=1024k count=4
losetup /dev/loop0 myinitrd
mke2fs /dev/loop0
mkdir /mnt/initrd
mount /dev/loop0 /mnt/initrd

Now populate the image with required directories and files:

cd /mnt/initrd
mkdir etc dev lib bin sbin proc new
touch etc/fstab
touch linuxrc
chmod +x linuxrc
touch devmap_mknod.sh
chmod +x devmap_mknod.sh

Linuxrc is where the action will be. It's a script file to be loaded by linux on initial boot, more below. Now you need to copy necessary files into bin and lib. For bin, copy the following from your current system:

cd /bin
cp sh cat mount umount mkdir chroot cryptsetup sleep mknod sed rm /sbin/pivot_root /sbin/blockdev /mnt/initrd/bin
# You also want to add /sbin/fsck.your_rootfs -Mikko Kortelainen
cp /sbin/fsck.jfs /mnt/initrd/bin

For lib, you'll need to find out which lib files are needed by each of the binaries above. The way to do it is to run 'ldd' for each file above and copy the required libs over. Example:

ldd /bin/mount
   linux-gate.so.1 =>  (0xffffe000)
   libc.so.6 => /lib/libc.so.6 (0x4002e000)
   /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
cp /lib/libc.so.6 /mnt/initrd/lib/
cp /lib/ld-linux.so.2 /mnt/initrd/lib/

And so on for the rest of the binaries. Here's a quick perl script to do this for you. Checks what libs are needed for every file in /mnt/initrd/bin, and copies them from /lib to /mnt/initrd/lib

#!/usr/bin/perl
chdir "/mnt/initrd/bin";
$lol = `ldd \`ls\``; #ldd of every bin
@lines = split /\n/, $lol; #put each line in array
foreach(@lines){
  if($_ =~ /\/lib\/(\S+)/){ #find "/lib/*"
    $hash{ $1 } = 0; #use hash to prevent duplicates
  }
}
@files = keys %hash; #pull the files out of the hash
foreach (@files){ #step through each
  `cp /lib/$_ /mnt/initrd/lib` #copy to initrd lib dir
}

Now, we need to create necessary devices under dev directory:

mknod /mnt/initrd/dev/console c 5 1
mknod /mnt/initrd/dev/null c 1 3
mknod /mnt/initrd/dev/hda2 b 3 2
mknod /mnt/initrd/dev/tty c 5 0

If you are using hda3 replace the numbers above with "b 3 3". If you are unsure of the major/minor numbers you should use mount /proc and cat /proc/devices. This should be done off the ram drive (more about that later).

Finally we need to create linuxrc and devmap_mknod.sh scripts. The linuxrc script should setup dm-crypt and mount root on it, then start the real init of the system. Here's it is:

#!/bin/sh
export PATH=/bin:/sbin

# Get cmdline from proc
mount -t proc proc /proc
CMDLINE=`cat /proc/cmdline`
# Create /dev/mapper/control nod for udev systems
sh devmap_mknod.sh
# umount /proc NO IDIOT NO cryptsetup needs proc
# -Mikko Kortelainen
# Mount real root and change to it
sleep 1
cryptsetup -y create root /dev/hda2
# mounting a filesystem is not ok without checking it -Mikko Kortelainen
# change fsck.jfs > fsck.your_rootfs
fsck.jfs /dev/mapper/root
mount /dev/mapper/root /new
cd /new
mkdir initrd
# Now its safe to umount it
umount /proc 
pivot_root . initrd

# Start init and flush ram device
exec chroot . /bin/sh <<- EOF >/dev/console 2>&1
umount initrd
rm -rf initrd
blockdev --flushbufs /dev/ram0
exec /sbin/init ${CMDLINE}
EOF

Now look at devmap_mknod script. It has to create /dev/mapper/control node with good values providing with by /proc/devices.

#!/bin/sh

# Startup script to create the device-mapper control device
# on non-devfs systems.
# Non-zero exit status indicates failure.
DM_DIR="mapper"
DM_NAME="device-mapper"

set -e

DIR="/dev/$DM_DIR"
CONTROL="$DIR/control"

# Check for devfs, procfs
if test -e /dev/.devfsd ; then
        echo "devfs detected: devmap_mknod.sh script not required."
        exit
fi
if test ! -e /proc/devices ; then
        echo "procfs not found; please create $CONTROL manually."
        exit 1
fi
# Get major, minor, and mknod
MAJOR=$(sed -n 's/^ *\([0-9]\+\) \+misc$/\1/p' /proc/devices)
MINOR=$(sed -n "s/^ *\([0-9]\+\) \+$DM_NAME\$/\1/p" /proc/misc)

if test -z "$MAJOR" -o -z "$MINOR" ; then
        echo "$DM_NAME kernel module not loaded: can't create $CONTROL."
        exit 1
fi

mkdir -p --mode=755 $DIR
test -e $CONTROL && rm -f $CONTROL

echo "Creating $CONTROL character device with major:$MAJOR minor:$MINOR."
mknod --mode=600 $CONTROL c $MAJOR $MINOR

Done with initrd. Test all bin files in it by chrooting and running them one by one. You should get no error messages about missing libraries:

chroot /mnt/initrd /bin/sh
/bin/chroot --help
/bin/mkdir --help
....

Unmount initrd and copy it over to /boot. Since I'm using bootsplash I've appended my bootsplash initrd to it. Note that you can still mount/unmount the image and play with it event after cat'ing bootsplash image to it. mount knows it's start and end.

umount /mnt/initrd
mount /boot
cat /boot/bootsplash-initrd >> myinitrd
cp myinitrd /boot/
umount /boot

Modifying FSTAB & GRUB.CONF

We need to modify /etc/fstab to point to our new root. Here's my new fstab:

/dev/mapper/root   /   reiserfs   noatime   0 1
/dev/hda1   /boot   ext2 noauto   0 0
/dev/hda4   none   swap   sw   0 0
none   /proc   proc   defaults   0 0
none   /dev/shm   tmpfs   defaults   0 0

And here's my new grub.conf:

default 1
timeout 5
splashimage=(hd0,0)/grub/splash.xpm.gz

title=Gentoo Linux (2.6.6)
  root (hd0,0)
  kernel (hd0,0)/vmlinuz-2.6.6 root=/dev/ram0 rw init=/linuxrc
  initrd (hd0,0)/myinitrd

Encrypting the Filesystem

Now to encrypting the file system (make sure you have a backup!!!). How you encrypt it depends on you. Here I'm assuming you've enough space in hda3, and you've a linux boot CD or linux installed on a another partition, and you've booted from that. One important note, you won't be able to change your pass very easy for an encrypted partition. To change it you'll have to copy all data off of it and remap the device, then create a new filesystem on the mapped device. So think about the password you choose.

mkdir /mnt/partition2 /mnt/partition3
mount /dev/hda2 /mnt/partition2
mount /dev/hda3 /mnt/partition3
# cp -r -p -v /mnt/partition2/* /mnt/partition3/ 
# tar makes this more easier and cleaner, add compression if you need/like
# also you can pipe it to other host via ssh like this:
# http://www.cyberciti.biz/faq/howto-use-tar-command-through-network-over-ssh-session/
# -Mikko Kortelainen
cd /
tar -cvvpPf /mnt/partition3/root_partition.tar /mnt/partition2/
umount /mnt/partition2
shred -v -n 2 /dev/hda2
cryptsetup -y create root /dev/hda2
--> enter passphrase when prompted
mkreiserfs /dev/mapper/root
mount /dev/mapper/root /mnt/partition2
# cp -r -p -v /mnt/partition3/* /mnt/partition2
# tar again by Mikko Kortelainen (blame me if i am not right to kordex@gmail.com)
cd /
tar xvf /mnt/partition3/root_partition.tar

The above simply copies your current root to another partition, sets up an encrypted filesystem there (accessible through /dev/mapper/root from now on), and copies back files to it. Shredding the root parition is optional (and can take a long time, depending on partition size), but recommended, since fragments not overwritten by dm-crypt can still be recovered.

Next, we need to create necessary devices which will be needed at the initial phase of booting before the real system starts and udev takes over. It's important.

# if you used tar you can skip this
mknod /mnt/partition2/dev/console c 5 1
mknod /mnt/partition2/dev/null c 1 3


Back to If you have udev:

  1. new udev has this done? verification needed.

now there is one more thing you'll have to do: open /mnt/partition2/etc/udev/rules.d/40-multipath.rules with your favorite editor

nano -w /mnt/partition2/etc/udev/rules.d/40-multipath.rules

in there you will find this line:

KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c"

you should change it to

KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="mapper/%c"

then everything will work just fine

That's it! Unmount all.

Encrypting Swap

Follow the official guide. See specifically "3. Starting easy - Encrypting swap devices".

We want the swap partition to use a random key everytime we boot up. We will not be able to recover the swap partition after it is unmounted (reboot), and we should also not need to (unless of course you like to hibernate). This adds slightly better security and more importantly another password you wont have to remember.

One more important thing, if you boot up and your system seems to hang mapping to the device this is because /dev/random ran out of entropy. Read more about this on wikipedia, a quick solution is to use /dev/urandom. This is not quite as random as /dev/random but is probably more random than your key for your root partition so I wouldn't lose sleep over it. When using /dev/random you can also move your mouse around to generate entropy, "cat /dev/random" notice how it eventually stops, now move your mouse to see what I mean.

Notes

  1. If you can't find a bootable CD with all ingredients in to encrypt your root, no problem! Just change your grub.conf line above to 'init=/bin/sh'. Now when you boot you'll get a nice little shell inside a ram disk that you can work from. Of course you'll need all necessary tools in the initrd image (e.g. mkreiserfs, fdisk, etc.).
    • Finnix is a 100MB LiveCD that includes all utilities necessary to follow this guide.
  2. If you have the default gentoo behaviour of saving '/dev' at reboot and restoring it at boot, make sure that your '/dev/mapper' directory contains a 'root' entry with major 254 minor 0 (mknod /dev/mapper/root b 254 0) just before your last reboot into the new encrypted root. Otherwise, it'll fail at boot time. (Check if your major number is 254 while installing the encryption! The major number is 253 on my system.)
  3. If you're running a modular kernel, no problem! Add a modules directory to myinitrd, say '/mod'. Copy the modules you'll need to it. Copy 'insmod' and requited libs to '/bin' and '/lib' and that's it. Just don't forget to modify 'linuxrc' to insert the modules before 'cryptsetup' line. Example, 'insmod /mods/dm-mod.ko' .. and so on.
  4. If you get "Command failed: Invalid argument" errors be sure to double check your major/minor numbers for /dev/mapper/root and /dev/mapper/control. A good way to troubleshoot is to comment everything out of linuxrc except "exec /bin/sh" then manually type the commands in at boot time. After you mount proc when booting off the ram drive run "cat /proc/devices" to see the numbers to devices. Some other users were successful with 253/0 for root and 10/62 for control.
  5. If you find yourself getting kernel panics regarding init trying to be killed, or you are always being prompted for 'Give root password for maintenance (or press Ctrl+D for normal startup)' and Ctrl-D reboots, try manually adding a permanent console device (mknod 5 1) to /dev on your encrypted root -- sometimes udev won't catch up to the pivot_root right away.

Discussion

Can be found here

Retrieved from "http://www.gentoo-wiki.info/SECURITY_Encrypting_Root_Filesystem_with_DM-Crypt"

Last modified: Mon, 04 Aug 2008 19:07:00 +1000 Hits: 47,409

Created by NickStallman.net, Luxury Homes Australia
Real estate agents should list their apartments, townhouses and units in Australia.