Howto: Setup a LUKS encrypted root file system on GoFlex/Dockstar and unlock it during the boot process via SSH October 11, 2011 06:10PM |
Registered: 13 years ago Posts: 128 |
sudo -s cd ~ mkdir /media/original_rootfs mount /dev/sdb1 /media/original_rootfs cd /media/original_rootfs tar --one-file-system -cpf ~/original_rootfs.tar *Connect the auxiliary flash drive and (let's call it /dev/sdc) and run gparted to create a single ext3 partition (/dev/sdc) on it. Mount that partition and copy the content of the original flash drive onto it.
mkdir /media/auxiliary_rootfs mount /dev/sdc1 /media/auxiliary_rootfs cd /media/auxiliary_rootfs tar -xpf ~/original_rootfs.tar cd ~ umount /media/auxiliary_rootfs umount /media/original_rootfs tune2fs -L "rootfs" /dev/sdc1Disconnect the auxiliary flash drive and use it to boot your GoFlex/Dockstar. It should boot flawlessly. At this point we're going to create encrypted rootfs using our Linux system. But first we need to wipe the original flash drive properly. Open gparted, delete all partitions on the original flash drive and create a single ext3 partition (/dev/sdb1).
shred -v -n3 /dev/sdb1This will take some time. After this is done, open gparted once again and use the following schema for creating partitions
/dev/sdb1: An ext3 partition about 200MB large /dev/sdb2: An ext4 partiton that will become our encrypted rootfs. Needs to be at least 2-3GB /dev/sdb3: A swap partition. The experience shows that 512MB are more than enoughThe rest can be a separate data partition or you can simply make your encrypted rootfs as large as possible. Let's encrypt /dev/sdb2 and make it an ext4 partition
cryptsetup -c aes-cbc-essiv:sha256 -y -s 256 luksFormat /dev/sdb2 cryptsetup luksOpen /dev/sdb2 rootfs_crypt mkfs.ext4 /dev/mapper/rootfs_crypt tune2fs -L "rootfs" /dev/mapper/rootfs_crypt cryptsetup luksClose /dev/mapper/rootfs_cryptDisconnect the original flash drive and connect it to your GoFlex/Dockstar that was booted using the auxiliary flash drive.
apt-get install cryptsetup busybox dropbearBe sure to save the id_rsa key as you will need it to unlock the partition via ssh.
cat /etc/initramfs-tools/root/.ssh/id_rsaI just pasted the output to "/home/my_usual_username/.ssh/myserver_rsa" on my Linux laptop that I use to unlock my GoFlex
nano /home/my_usual_username/.ssh/myserver_rsa -> paste the key, save and exit chmod 600 /home/my_usual_username/.ssh/myserver_rsa chown my_usual_username:my_usual_username /home/my_usual_username/.ssh/myserver_rsa touch /home/my_usual_username/.ssh/myserver_known_hosts chmod 600 /home/my_usual_username/.ssh/myserver_known_hosts chown my_usual_username:my_usual_username /home/my_usual_username/.ssh/myserver_known_hostsOf course, "my_usual_username" is the name of the non-root user who will use ssh to unlock the device.
nano /etc/initramfs-tools/initramfs.confand replace "DEVICE=" by "DEVICE=eth0" to make sure that the initramfs has network access. Futhermore, we need to find out the UUID of the encrypted partition. To do thus run
blkidand look for something like
/dev/sdb2: UUID="bbb2c58e-1084-4d1a-b9f8-79179d25743c" TYPE="crypto_LUKS"Now edit /etc/crypttab
nano /etc/crypttaband paste a line looking like this (depends on what your UUID is)
rootfs_crypt UUID=bbb2c58e-1084-4d1a-b9f8-79179d25743c none luksAlso edit /etc/fstab
nano /etc/fstaband make it look like this
# <file system> <mount point> <type> <options> <dump> <pass> /dev/mapper/rootfs_crypt / ext4 rw,noatime,nouser_xattr,noacl,errors=remount-ro 0 1 tmpfs /tmp tmpfs defaults 0 0Mount the encrypted rootfs so that update-initramfs can determine the cipher
cryptsetup luksOpen /dev/sdb2 rootfs_cryptThis should be enough to create a proper initramfs, so let's do it
mkdir -p /lib/modules/3.0.0-goflex/kernel/arch update-initramfs -c -k 3.0.0-goflex -tIt's very important that this works without any warnings or errors. Especially warnings or errors containing the words "device-mapper" or "cryptsetup" indicate that you did something wrong. It's even more important that our initrd knows, where to look for the encrypted rootfs. So we'll apply my ugly initrd hack. This hack works for all devices independently of their bootloader and doesn't involve changing anything via fw_setenv. Run
cd /boot mkdir initrd.img-new && cp initrd.img-3.0.0-goflex initrd.img-new/ cd initrd.img-new/ && gzip -dc initrd.img-3.0.0-goflex | cpio -id rm -r /boot/initrd.img-new/lib/modules/3.0.0-goflex/kernel/drivers/crypto rm initrd.img-3.0.0-goflex nano initreplace
if [ -n "${noresume}" ]; then export noresume unset resume else resume=${RESUME:-} fiby
if [ -n "${noresume}" ]; then export noresume unset resume else resume=${RESUME:-} fi ROOT="/dev/mapper/rootfs_crypt"and do
find ./ | cpio -H newc -o > ../initrd.img-3.0.0-goflex_arc gzip ../initrd.img-3.0.0-goflex_arc mv ../initrd.img-3.0.0-goflex_arc.gz ..//initrd.img-3.0.0-goflex_mod cd .. rm -r initrd.img-new mkimage -A arm -O linux -T ramdisk -C gzip -a 0 -e 0 -n Linux-3.0.0 -d /boot/initrd.img-3.0.0-goflex_mod /boot/uInitrdOf course, we also need to create the kernel image
mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e 0x00008000 -n Linux-3.0.0 -d /boot/vmlinuz-3.0.0-goflex /boot/uImageFine, now shutdown your GoFlex/Dockstar via
cryptsetup luksClose /dev/mapper/rootfs_crypt shutdown -h nowand disconect both flash drives. Connect them to your Linux box. Once again I assume that the original flash drive is /dev/sdb, whereas the auxiliary flash drive is /dev/sdc. For the sake of safety let's create a backup of the rootfs on the auxiliary flash drive
mount /dev/sdc1 /media/auxiliary_rootfs cd /media/auxiliary_rootfs tar --one-file-system -cpf ~/auxiliary_rootfs.tar *Now we are going the copy the auxiliary rootfs to the original flash drive.
mkdir /media/rootfs_crypt cryptsetup luksOpen /dev/sdb2 rootfs_crypt mount /dev/mapper/rootfs_crypt /media/rootfs_crypt cp -a /media/auxiliary_rootfs/* /media/rootfs_crypt rm -r /media/rootfs_crypt/boot/*We cleared the boot folder, because our uImage and uInitrd will be located not there, but on a separate unencrypted partition (the small 200MB ext3 partition we created before)
mkdir /media/unenc_boot mount /dev/sdb1 /media/unenc_boot cp -a /media/auxiliary_rootfs/boot/* /media/unenc_boot mkdir /media/unenc_boot/boot cd /media/unenc_boot/boot ln -s ../uInitrd uInitrd ln -s ../uImage uImage cd ~ umount /media/unenc_boot/ umount /media/rootfs_crypt umount /media/auxiliary_rootfs cryptsetup luksClose rootfs_cryptLet's clean up the mess
rmdir /media/auxiliary_rootfs rmdir /media/unenc_boot rmdir /media/rootfs_crypt rmdir /media/original_rootfsThat's it. Now connect the original flash to GoFlex/Dockstar and boot it. If you monitor the boot process via netconsole, you'll observe the following. After "Starting kernel ..." you have to wait for about 20 seconds before the kernel messages appear. When you see something like this
[ 29.683821] device-mapper: uevent: version 1.0.3 [ 29.690027] device-mapper: ioctl: 4.20.0-ioctl (2011-02-02) initialised: dm-devel@redhat.comthen the initramfs is waiting for you to supply the LUKS password. Remember the id_rsa key we saved to "~/.ssh/myserver_rsa"? Well, it's on time to use it. Futhermore the usual Linux' OpenSSH client might become a bit confused, because the fingerprint of the dropbear SSH server running on the initramfs is different from the usual OpenSSH fingerprint of your GoFlex/Seagate. So we should better use a special known_hosts file for that. What about the LUKS password? Let's suppose you password is
debian_rulesThen the command to unlock your device will be
ssh -o "UserKnownHostsFile=~/.ssh/myserver_known_hosts" -i ~/.ssh/myserver_rsa root@ip-of-your-device "echo -ne \"debian_rules\" > /lib/cryptsetup/passfifo"The slashes and quotation marks should look exactly like this. For more information on the syntax check out "/usr/share/doc/cryptsetup/README.remote.gz" on your GoFlex/Dockstar. You can read the manual via
zless /usr/share/doc/cryptsetup/README.remote.gzAfter having submitted the password, on the netconsole you will see something like
[ 53.805822] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null) [ 55.327002] udev[256]: starting version 164 [ 56.909229] EXT4-fs (dm-0): re-mounted. Opts: (null) [ 57.093194] EXT4-fs (dm-0): re-mounted. Opts: nouser_xattr,noacl,errors=remount-ro ... [ 58.490091] kjournald starting. Commit interval 5 seconds ...After a few seconds you should be able to ssh into you device the usual way. Having done this, you should do some further modifications. If your kernel contains mv_cesa remove the module. mv_cesa doesn't work properly with 3.0.x kernels and will give you segfaults.
mv /lib/modules/3.0.0-goflex/kernel/drivers/crypto/mv_cesa.ko /lib/modules/3.0.0-goflex/kernel/drivers/crypto/mv_cesa.old
UUID=393ac665-f5c2-488d-b601-b59ba1d5675b /boot ext3 defaults 0 1to your /etc/fstab. We also want to activate the encrypted swap partition. It's very easy to find the swap partition since you already know what is your root partition. Since swap is the third primary partition, you just have to replace one number. For example, if your crypto_LUKS is located on /dev/sdc2, then swap will be /dev/sdc3. Another way is to look for the id of your usb flash
ls /dev/disk/by-id/For instance, in my case the id looks like this
/dev/disk/by-id/usb-SanDisk_Cruzer_Blade_20051740220F36703394-0\:0-part3Note the appropriate location and add a line looking like this (use your id!)
swap_crypt /dev/sdc3 /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256or like this
swap_crypt /dev/disk/by-id/usb-SanDisk_Cruzer_Blade_20051740220F36703394-0\:0-part3 /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256to /etc/crypttab. Finally add
/dev/mapper/swap_crypt none swap sw 0 0to /etc/fstab
/etc/init.d/cryptdisks start mount -a swapon -a freeThe output of free should look like this
total used free shared buffers cached Mem: 125404 123836 1568 0 3012 76560 -/+ buffers/cache: 44264 81140 Swap: 524284 5772 518512
/dev/mapper/rootfs_crypt / ext4 rw,noatime,nouser_xattr,noacl,errors=remount-ro 0 1by
/dev/mapper/rootfs_crypt / ext4 rw,noatime,nouser_xattr,noacl,commit=15,errors=remount-ro 0 1Also run
echo "vm.dirty_writeback_centisecs = 1500" >> /etc/sysctl.confReboot your device for the tweaks to take effect. For more information on the ext4 mount parameters you might want to check out the documentation
unset HISTFILE ssh -o "UserKnownHostsFile=~/.ssh/myserver_known_hosts" -i ~/.ssh/myserver_rsa root@ip-of-your-device "echo -ne \"debian_rules\" > /lib/cryptsetup/passfifo" exitthis way the ssh command will not be added to the history
[ 29.778658] mv643xx_eth_port mv643xx_eth_port.0: eth0: link up, 1000 Mb/s, full duplex, flow control disabled [ 29.789733] console [netcon0] enabled [ 29.793438] netconsole: network logging started [ 29.867747] NET: Registered protocol family 10 [ 29.914938] device-mapper: uevent: version 1.0.3 [ 29.921044] device-mapper: ioctl: 4.20.0-ioctl (2011-02-02) initialised: dm-devel@redhat.com [ 54.681398] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null) [ 54.878703] Kernel panic - not syncing: Attempted to kill init! [ 54.884759] [<c0035be8>] (unwind_backtrace+0x0/0xec) from [<c02e35f0>] (panic+0x54/0x18c) [ 54.893031] [<c02e35f0>] (panic+0x54/0x18c) from [<c00491cc>] (do_exit+0xb8/0x6dc) [ 54.900657] [<c00491cc>] (do_exit+0xb8/0x6dc) from [<c004987c>] (do_group_exit+0x8c/0xc0) [ 54.908917] [<c004987c>] (do_group_exit+0x8c/0xc0) from [<c0057b40>] (get_signal_to_deliver+0x390/0x3d0) [ 54.918482] [<c0057b40>] (get_signal_to_deliver+0x390/0x3d0) from [<c0032598>] (do_signal+0xb0/0x5ac) [ 54.927776] [<c0032598>] (do_signal+0xb0/0x5ac) from [<c0032aac>] (do_notify_resume+0x18/0x60) [ 54.936466] [<c0032aac>] (do_notify_resume+0x18/0x60) from [<c0030334>] (work_pending+0x24/0x28)It happens exactly the moment when run-init is performed in the init script. Somehow switching to the rootfs breaks mv_cesa and since the rootfs encryption is handled via mv_cesa, the kernel panics. If mv_cesa is not loaded, the encryption is handled by the kernel itself (no hardware offloading). In this case everything works well. Note, that although mv_cesa doesn't "accelerate" root, it does work for the swap partition. That's because swap is mounted after switching to the rootfs, so at that moment it's safe to use mv_cesa. If you use aes-cbc-essiv:256 to encrypt some other partitions, hardware offloading will work for them too. It's only the rootfs where mv_cesa fails. This is why it's better to create a rather small root partition containing only the bare minimum and keep all other stuff like backups, music, documents, etc. on another encrypted partition. In this case that data partition will benefit from mv_cesa.
Re: Howto: Setup a LUKS encrypted root file system on GoFlex/Dockstar and unlock it during the boot process via SSH October 13, 2011 06:04PM |
Registered: 14 years ago Posts: 264 |
Re: Howto: Setup a LUKS encrypted root file system on GoFlex/Dockstar and unlock it during the boot process via SSH October 13, 2011 06:29PM |
Registered: 13 years ago Posts: 128 |
rm -r /boot/initrd.img-new/lib/modules/3.0.0-goflex/kernel/drivers/cryptowhile performing the initrd hack part.
[ 29.778658] mv643xx_eth_port mv643xx_eth_port.0: eth0: link up, 1000 Mb/s, full duplex, flow control disabled [ 29.789733] console [netcon0] enabled [ 29.793438] netconsole: network logging started [ 29.867747] NET: Registered protocol family 10 [ 29.914938] device-mapper: uevent: version 1.0.3 [ 29.921044] device-mapper: ioctl: 4.20.0-ioctl (2011-02-02) initialised: dm-devel@redhat.com [ 54.681398] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null) [ 54.878703] Kernel panic - not syncing: Attempted to kill init! [ 54.884759] [<c0035be8>] (unwind_backtrace+0x0/0xec) from [<c02e35f0>] (panic+0x54/0x18c) [ 54.893031] [<c02e35f0>] (panic+0x54/0x18c) from [<c00491cc>] (do_exit+0xb8/0x6dc) [ 54.900657] [<c00491cc>] (do_exit+0xb8/0x6dc) from [<c004987c>] (do_group_exit+0x8c/0xc0) [ 54.908917] [<c004987c>] (do_group_exit+0x8c/0xc0) from [<c0057b40>] (get_signal_to_deliver+0x390/0x3d0) [ 54.918482] [<c0057b40>] (get_signal_to_deliver+0x390/0x3d0) from [<c0032598>] (do_signal+0xb0/0x5ac) [ 54.927776] [<c0032598>] (do_signal+0xb0/0x5ac) from [<c0032aac>] (do_notify_resume+0x18/0x60) [ 54.936466] [<c0032aac>] (do_notify_resume+0x18/0x60) from [<c0030334>] (work_pending+0x24/0x28)It happens exactly the moment when run-init is performed in the init script. Somehow switching to the rootfs breaks mv_cesa and since the rootfs encryption is handled via mv_cesa, the kernel panics. If mv_cesa is not loaded, the encryption is handled by the kernel itself (no hardware offloading). In this case everything works well.
Re: Howto: Setup a LUKS encrypted root file system on GoFlex/Dockstar and unlock it during the boot process via SSH October 14, 2011 02:41PM |
Registered: 13 years ago Posts: 128 |
Re: Howto: Setup a LUKS encrypted root file system on GoFlex/Dockstar and unlock it during the boot process via SSH October 15, 2011 03:18PM |
Registered: 13 years ago Posts: 128 |