Encrypting Root Filesystem

From blag.wiki.aktivix.org

Jump to: navigation, search

Contents

Introduction

NOTE: This does not work with 2.6.18 kernel in 50k nor 60k. ANOTHER NOTE: It apparently does if you add "ramdisk_size=32768 ramdisk_blocksize=1024" to the kernel boot line.

This documents how to encrypt the root filesystem of your BLAG box using a USB key.

It's a bit involved...You'll need to be handy on the command line, know grub, mke2fs, etc.


The idea behind this setup is to have /no/ unencrypted data on your hard drive, except the partitioning information. The system requires a USB drive (e.g. a small USB "junk drive") to boot from. Your computer must be able to boot from a USB drive.


The USB device contains grub, the kernel, an initrd, and the passphrase-protected key to the root filesystem. The computer boots off USB, goes to grub, loads the kernel (from the USB drive), prompts you for the password to your encrypted partition, and then boots up normally.


The BLAG kernel and userspace tools are already provided, so you don't have to use a custom kernel or compile new packages. You do need to make an initrd and copy stuff over. This is meant for a fresh install, but it could be done on an existing installation as well, as long as you have an empty partition as large as the partition you want to encrypt...


Note, it is possible to have an encrypted root partition without a USB drive, but /boot needs to be unencrypted in that case. Adjust these docs accordingly. :)

Don't do this with any un-backed up data...

Outline

  1. BLAG gets installed on a small non-encrypted temporary partition.
  2. Reboot into the fresh install
  3. Create encrypted partition & format it
  4. Make initrd & copy it to USB device
  5. install grub on USB drive
  6. copy new blag install over to new encrypted partition
  7. boot into new encrypted system, blow out old temporary partition, & install whatever else you want
  8. do cheap hack to use encrypted swap


Fill Drive with Random Data

Before you format & use an encrypted drive/partition, you'll want to fill it with random noise. Otherwise it is easy to see how much data is stored on the device. Boot off CD in "linux rescue" mode. Running this command three times or so should put a few nice layers of random data on the drive (note, this command will ERASE /everything/ on the device).

shred -n 3 -v /dev/sda

This will take a loooooooong time to run. Like a few hours for a 100 gig drive.

Install BLAG

Do a smallish install of BLAG. If you're going to be using X, it may be easiest to install it, but leave out as much as you can as the install gets put on a temporary un-encrypted partition, which won't be used for the root partition later. Set up partitions something like:

/dev/sda1 2 gigs or so for temp root partition
/dev/sda2 the rest of your partition

Note. Don't set up a swap partition at this point. The /dev/sda1 partition will be reclaimed later as swap. (Of course you can partition anyway you want, this is just a suggestion...)

Reboot.

Create initrd

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

Fill initrd

cd /mnt/initrd
mkdir etc dev lib bin proc new-root modules .gnupg
touch etc/fstab
touch linuxrc
chmod 755 linuxrc

cp files to /bin

cp -p /bin/{sh,cat,mount,umount,mkdir,awk} /mnt/initrd/bin/
cp -p /usr/sbin/chroot /mnt/initrd/bin/
cp -p /sbin/{cryptsetup,pivot_root,insmod,busybox,dmsetup,e2fsck,fsck} /mnt/initrd/bin/
cp -p /usr/bin/gpg /mnt/initrd/bin/

NOTE: check on udev stuff...

set up handy symlinks for busybox

This ain't necessarily needed, but having busybox available is handy sometimes (e.g. if you use `sh` to drop into a shell for debugging in linuxrc)... Some of the above binaries could be replaced with busybox symlinks too.

cd /mnt/initrd/bin
ln -s busybox chmod
ln -s busybox chown
ln -s busybox clear
ln -s busybox df
ln -s busybox dmesg
ln -s busybox echo
ln -s busybox env
ln -s busybox expr
ln -s busybox find
ln -s busybox free
ln -s busybox grep
ln -s busybox halt
ln -s busybox init
ln -s busybox kill
ln -s busybox killall
ln -s busybox ln
ln -s busybox ls
ln -s busybox lsmod
ln -s busybox mknod
ln -s busybox more
ln -s busybox mv
ln -s busybox ps
ln -s busybox pwd
ln -s busybox reboot
ln -s busybox rm
ln -s busybox rmmod
ln -s busybox sleep
ln -s busybox sort
ln -s busybox sync
ln -s busybox syslogd
ln -s busybox tail
ln -s busybox touch
ln -s busybox true
ln -s busybox uname
ln -s busybox uptime
ln -s busybox vi
ln -s busybox wc
ln -s busybox which
ln -s busybox whoami
ln -s busybox yes
ln -s busybox and so on.........

cp libs to /lib

In BLAG80k like:

cp -p /lib/{libc.so.6,ld-linux.so.2,libselinux.so.1,libtermcap.so.2,libdl.so.2,libblkid.so.1,libuuid.so.1,libdevmapper.so.1.02,libsepol.so.1,libresolv.so.2,libacl.so.1,libattr.so.1,,libtinfo.so.5,libpopt.so.0,libcryptsetup.so.0,libgcrypt.so.11,libgpg-error.so.0,libnsl.so.1}  /mnt/initrd/lib/
cp -p /usr/lib/{libz.so.1,libbz2.so.1,libreadline.so.5,libusb-0.1.so.4,libtinfo.so.5} /mnt/initrd/lib/

In BLAG60k this is more like:

cp -p /lib/{libc.so.6,ld-linux.so.2,libselinux.so.1,libtermcap.so.2,libdl.so.2,libblkid.so.1,libuuid.so.1,libdevmapper.so.1.02,libsepol.so.1,libresolv.so.2,libacl.so.1,libattr.so.1}  /mnt/initrd/lib/
cp -p /usr/lib/{libz.so.1,libbz2.so.1,libreadline.so.5,libusb-0.1.so.4} /mnt/initrd/lib/

Older:

cp -p /lib/tls/libc.so.6 /mnt/initrd/lib/
cp -p /lib/{ld-linux.so.2,libselinux.so.1,libtermcap.so.2,libdl.so.2}  /mnt/initrd/lib/
cp -p /usr/lib/{libz.so.1,libbz2.so.1} /mnt/initrd/lib/


For 64-bit use "lib64" instead of "lib" above. Add:

cp -p /lib64/ld-linux-x86-64.so.2 /mnt/initrd/lib/
cp -p /lib64/libm.so.6 /mnt/initrd/lib/
cd /mnt/initrd ; ln -s lib lib64

cp needed kernel modules to /modules/

cp -p /lib/modules/`uname -r`/kernel/crypto/{sha256.ko,twofish.ko} /mnt/initrd/modules/
cp -p /lib/modules/`uname -r`/kernel/drivers/md/{dm-crypt.ko,dm-mod.ko} /mnt/initrd/modules/
cp -p /lib/modules/`uname -r`/kernel/fs/jbd/jbd.ko /mnt/initrd/modules/
cp -p /lib/modules/`uname -r`/kernel/fs/ext3/ext3.ko /mnt/initrd/modules/

make /dev devices

mknod /mnt/initrd/dev/console c 5 1
mknod /mnt/initrd/dev/null c 1 3
mknod /mnt/initrd/dev/sda1 b 3 1
mknod /mnt/initrd/dev/sda2 b 3 2
mknod /mnt/initrd/dev/sda3 b 3 3
mknod /mnt/initrd/dev/sda4 b 3 4
mknod /mnt/initrd/dev/sda5 b 3 5
mknod /mnt/initrd/dev/sda6 b 3 6
mknod /mnt/initrd/dev/tty c 4 0
mkdir /mnt/initrd/dev/mapper
mknod /mnt/initrd/dev/mapper/control c 10 63  

Note: for my SATA system (I think that was the difference) the major number is 8 not 3. So it would be like `mknod sda1 b 8 1` etc.

(is it necessary to chmod 'em?)

chmod -R o-r /mnt/initrd/dev/

linuxrc

Copy this to the linuxrc file, substituting your drive partition for whatever you want the encrypted partition to be (e.g. replace sda2 with the future encrypted fs).

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

# Get cmdline from proc
mount -t proc proc /proc
CMDLINE=`cat /proc/cmdline`
umount /proc

# Insert needed modules
insmod /modules/dm-mod.ko
insmod /modules/dm-crypt.ko
insmod /modules/jbd.ko
insmod /modules/ext3.ko
insmod /modules/twofish.ko
insmod /modules/sha256.ko
 
# Mount real root and change to it
gpg -q --cipher-algo TWOFISH --decrypt /rootfs-key.gpg | cryptsetup -v --key-size=256 --cipher=twofish-cbc-essiv:sha256 create root /dev/sda2
mkdir -p /new-root
mount /dev/mapper/root /new-root
cd /new-root
mkdir -p old-root
pivot_root . old-root


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

This is a more recent linuxrc to take for a test drive. It may require a few more binaries.

#!/bin/sh

export PATH=/bin:/sbin:/usr/bin:/usr/sbin

# Get cmdline from proc
mount -n -t proc proc /proc
# cp -p /sbin/insmod.static insmod
# 50k mkdir /sys....
echo "mount -n -t sysfs /sys /sys"
mount -n -t sysfs /sys /sys
CMDLINE=`cat /proc/cmdline`
#echo "umount /proc"
#umount /proc

#sleep 1

#echo "start_udev"
#start_udev
#sleep 1

# Insert needed modules
echo "Insert needed modules"
insmod /modules/dm-mod.ko
insmod /modules/dm-crypt.ko
insmod /modules/jbd.ko
insmod /modules/ext3.ko
insmod /modules/twofish.ko
insmod /modules/sha256.ko
echo "Done inserting modules..."
#sleep 5

# For debugging...
#echo "dropping into a shell...."
#echo
#sh

# Mount real root and change to it
echo "now run the huge gpg crypt command..."
gpg -q --no-options --cipher-algo TWOFISH --decrypt /rootfsn-key.gpg | cryptsetup -v --key-size=256 --cipher=twofish-cbc-essiv:sha256 create root /dev/sda2

echo "mkdir -p /new-root"
mkdir -p /new-root

echo "e2fsck -C -V -t -t /dev/mapper/root"
e2fsck -C -V -t -t /dev/mapper/root

echo "mount /dev/mapper/root /new-root"
mount /dev/mapper/root /new-root

echo "cd /new-root"
cd /new-root

echo "mkdir -p old-root"
mkdir -p old-root

echo "pivot root..........."
pivot_root . old-root

# Start init and flush ram device
echo "exec chroot . /bin/sh <<- EOF >dev/console 2>&1"
exec chroot . /bin/sh <<- EOF >dev/console 2>&1
umount /old-root/sys
umount /old-root/proc
umount /old-root
rmdir  /old-root
echo "blockdev --flushbufs /dev/ram0"
blockdev --flushbufs /dev/ram0
exec /sbin/init ${CMDLINE}
EOF

# awww
echo "el fin de linuxrc"

Test in chroot

Test all bin files in it by chrooting and running them one by one. You should get no error messages about missing libraries. `ldd /bin/whatever` will show what libs are needed.

chroot /mnt/initrd /bin/sh

/bin/cat --help
/bin/mount --help
/bin/umount --help
/bin/mkdir --help
/bin/chroot --help
/bin/cryptsetup --help
/bin/pivot_root --help


Set up USB drive

Insert your USB device, it will likely come up as /dev/sdb. Create a 20 meg partition on it (or so, I create 100 megs).

fdisk /dev/sdb
n
p
1
<enter>
+20M
a
1
w

Then format the new USB partition (you don't want a journaled fs here) and mount it.

mke2fs -m0 /dev/sdb1
mkdir /mnt/usbdrive
mount /dev/sdb1 /mnt/usbdrive

Set up grub

cd /mnt/usbdrive/
grub-install --root-directory=. /dev/sdb
cp -p /boot/grub/grub.conf /mnt/usbdrive/boot/grub/
cp -p /boot/grub/splash.xpm.gz /mnt/usbdrive/boot/grub/

Edit grub.conf for new setup:

vi /mnt/usbdrive/boot/grub/grub.conf

grub.conf:

default=0
timeout=10
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
title BLAGcrypt (2.6.10-1.770_FC3)
 root (hd0,0)
 kernel /vmlinuz-2.6.10-1.770_FC3 root=/dev/ram0 rw init=/linuxrc
 initrd /cryptinitrd  



create new encrypted root fs

Pick a damn good password/passphrase for this (it can be the weakest link...):

mkdir /root/.gnupg
openssl rand -base64 32 | cut -c 3-34 | gpg -c --no-random-seed-file --cipher-algo TWOFISH > /mnt/initrd/rootfs-key.gpg
chmod 400 /mnt/initrd/rootfs-key.gpg

The rootfs-key.gpg is a file encrypted with your password. The unencrypted contents of that file are used as the password that cryptsetup uses to encrypt the drive. Very important file. Don't lose it or the passphrase to it, or your data is lost. :)


Enter your new password when prompted:

gpg -q --cipher-algo TWOFISH --decrypt /mnt/initrd/rootfs-key.gpg | cryptsetup -v --key-size=256 --cipher=twofish-cbc-essiv:sha256 create root /dev/sda2

Then actually format the partition (make damn sure you have the right partition above, or you may wipe data...)

mke2fs -j /dev/mapper/root
mkdir /mnt/crypto
mount /dev/mapper/root /mnt/crypto

Copy over your existing installation to the new encrypted partition (adding lib64 if you're doing 64bit):

cd /
cp -a bin boot etc home initrd lib misc opt root sbin selinux srv tmp usr var /mnt/crypto/
mkdir /mnt/crypto/proc /mnt/crypto/mnt /mnt/crypto/sys /mnt/crypto/media /mnt/crypto/dev
sync

Set up some needful things in the new /dev

mknod /mnt/crypto/dev/console c 5 1
mknod /mnt/crypto/dev/null c 1 3
mknod /mnt/crypto/dev/ram0 b 1 0
chmod 600 /mnt/crypto/dev/console
chmod 666 /mnt/crypto/dev/null
chown root.disk /mnt/crypto/dev/ram0
chmod 660 /mnt/crypto/dev/ram0


Unmount initrd...

cd
umount /mnt/initrd
losetup -d /dev/loop0

Copy over the initrd you made and a kernel:

cp -p /mnt/cryptinitrd /mnt/usbdrive/
cp -p /boot/vmlinuz-2.6.10-1.770_FC3 /mnt/usbdrive/

set up new fstab

Change the /etc/fstab on the new partition.

vi /mnt/crypto/etc/fstab

And change:

LABEL=/              /         ext3     defaults       1 1

To:

/dev/mapper/root     /         ext3     defaults       0 1

And DELETE the swap line.

rc.sysinit

The stock rc.sysinit tries to do a fsck on the currently mounted volume, so if you boot up without modifying it, it borks. Here is a /very/ cheap way to get around this (the linuxrc should probably do the fsck).

cp -p /mnt/crypto/etc/rc.d/rc.sysinit /mnt/crypto/etc/rc.d/rc.sysinit.orig
vi /mnt/crypto/etc/rc.d/rc.sysinit

And change:

fsck -T -a $rootdev $fsckoptions > /etc/rhgb/temp/rhgb-console

To:

echo "egahd! skipping fsck of /"

Change:

initlog -c "fsck -T -a $rootdev $fsckoptions"

To:

echo "egahd! skipping fsck of /"

Note: if you upgrade initscripts, you will need to modify this file again.


wrapping it up

umount /mnt/crypto
cryptsetup remove root
umount /mnt/usbdrive

reboot

good luck :)


Swap

For swap, we'll reuse the partition we initially installed on. Once you know that you can boot into your encrypted system fine, run this to dump random data on the old install / partition:

dd if=/dev/urandom of=/dev/sda1

You should run it a few times to make sure it erases all layers.

Then set up swap like this cheep way: http://wiki.blagblagblag.org/Encrypted_swap


Links

The original basis for this article: http://gentoo-wiki.com/SECURITY_Encrypting_Root_Filesystem_with_DM-Crypt

https://wiki.slugbug.org.uk/Encrypted_partitions

Some other notes... http://docs.indymedia.org/view/Local/UkCrypto#Filesystem

Notes about using suspend (but uses loop-aes instead): http://wiki.suspend2.net/EncryptedSwapAndRoot

Different approach: http://linux.ioerror.us/2006/09/encrypting-your-root-partition-on-fedora-core-5/

Here's another way to do it on Fedora 8 from the tummy folks  :) http://www.tummy.com/Community/Articles/cryptoroot-f8/

Personal tools