Encrypting Root Filesystem
From blag.wiki.aktivix.org
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
- BLAG gets installed on a small non-encrypted temporary partition.
- Reboot into the fresh install
- Create encrypted partition & format it
- Make initrd & copy it to USB device
- install grub on USB drive
- copy new blag install over to new encrypted partition
- boot into new encrypted system, blow out old temporary partition, & install whatever else you want
- 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/
