| View previous topic :: View next topic |
| Author |
Message |
BradN Advocate


Joined: 19 Apr 2002 Posts: 2270 Location: Wisconsin (USA)
|
Posted: Sat May 28, 2011 10:23 pm Post subject: Fair warning for those playing with cryptsetup/LUKS |
|
|
[edit] Turns out it was probably my fault. Still, my point stands - when working with partition level stuff, make sure you've got backups because all it takes is one screw up and you might lose more data than you expect.
Be very careful using an initrd initial mounting approach for the root filesystem and a second encrypted partition anywhere. After creating the second encrypted partition, something got confused and directed all access to the second encrypted device to the FIRST encrypted device, completely fucking everything up.
Make a backup before trying. You've been warned.
Last edited by BradN on Sun May 29, 2011 8:14 pm; edited 1 time in total |
|
| Back to top |
|
 |
Hu Watchman

Joined: 06 Mar 2007 Posts: 6827
|
Posted: Sat May 28, 2011 11:10 pm Post subject: |
|
|
| I have used these successfully in the past, so this sounds like it could be a regression. Could you describe in more detail the commands you executed that resulted in data corruption? What versions of the kernel and relevant tools were you using? |
|
| Back to top |
|
 |
BradN Advocate


Joined: 19 Apr 2002 Posts: 2270 Location: Wisconsin (USA)
|
Posted: Sun May 29, 2011 12:20 am Post subject: |
|
|
in use at the time Kernel 2.6.39-gentoo (r0)
(LUKS partition was probably created with 2.6.37-r1)
cryptsetup-1.1.3-r3
Here is the booting arrangement:
FreeDOS hosted grub4dos on a standard PC style MBR/partition table, kernel and initrd (squashfs format) in high memory loaded ram-disk
initrd uses squashfs/xz
kernel is built nearly fully modular, with USB drivers and USB disk support built-in
filesystems reiserfs, squashfs built-in
devtmpfs is enabled and used on the initrd
file arrangement
/bin/cryptsetup
/bin/busybox
/bin/sh -> busybox
/dev
/modules
/modules/0lib-ata.ko (not 100% sure on these two filenames, building a new kernel with squashfs to check)
/modules/1ata-piix.ko
/proc
/realroot
/sbin
/sbin/init
/sys
actual contents of /sbin/init once I get a squashfs kernel set up again
Basically /sbin/init does these things:
uses devtmpfs
waits for encrypted LUKS volume to appear as a device by calling findfs until it shows up (searching by UUID)
does luksOpen with that device and name 'cryptstick'
mounts /dev/mapper/cryptstick to /realroot
executes a fun procedure to switch /realroot to be the new root filesystem, with /realroot/tmp holding the initrd, then unmounting the initrd using sh from the real root partition
Basically the problem occurred as I was trying to use my encrypted USB stick to permanently install the environment to the laptop's HDD it was running from. I had luksFormat'd the new partition and then opened it (I'm 99% sure I had the right device identifier, but if I hadn't, should it have warned me that the device was already in use?), and then at that point mkreiserfs on /dev/mapper/cryptdisk (the second device set up for the main HDD's encrypted root) would actually be writing to /dev/mapper/cryptstick. I could see the light on the memory stick blink and everything.
Unfortunately the machine's not running anymore and the filesystem lost so I can't get the bash history.
I'm nearly positive I arrowed up and double checked the devices specified afterwards (/dev/sda was the memory stick, and /dev/sdb was the internal hdd).
Actually... now that I think about that aspect... it's possible I had booted the system initially from the hard drive and not the memory stick at that point - the devices could have been reversed due to the newer initrd that instantly loaded the ata-piix driver before the USB drivers had registered the USB stick.
So maybe I had double checked that the device was what I was expecting, just I was expecting the wrong device. That's my best theory right now. But should cryptsetup allow mounting the same volume twice at the same time? |
|
| Back to top |
|
 |
BradN Advocate


Joined: 19 Apr 2002 Posts: 2270 Location: Wisconsin (USA)
|
Posted: Sun May 29, 2011 2:30 am Post subject: |
|
|
Update: Here's the init script:
| Code: | #!/bin/sh
EncUUID=2b4a6a4b-ee01-40b9-9574-2da36fdfd364
bailout()
{
echo Something failed. Please accept this shell as a substitute.
exec /bin/sh
}
echo Init script running...
echo Mounting virtual filesystems to support cryptsetup...
mount -n -t devtmpfs devtmpfs /dev || bailout
mount -n -t proc proc /proc || bailout
CMDLINE=`cat /proc/cmdline`
echo Now loading modules...
cd /modules
for x in *
do
echo -n " Loading ${x}..."
insmod ${x} && echo "OK" || echo "--FAILED--"
done
echo "Finished loading modules."
until findfs UUID=${EncUUID}
do
echo Waiting for encrypted volume device...
sleep .5
done
echo Encrypted volume found!
echo Now unlocking encrypted volume...
cryptsetup luksOpen `findfs UUID=${EncUUID}` cryptstick || bailout
echo Now attempting to mount encrypted volume...
mount -n -o ro /dev/mapper/cryptstick /realroot || bailout
echo Now unmounting virtual filesystems...
umount /dev /proc || echo Warning: could not unmount all virtual filesystems
echo Switching into encrypted root...
cd /realroot
pivot_root . tmp # use /tmp in encrypted FS as placeholder for initrd filesystem
exec chroot . /bin/sh <<- EOF > /dev/console 2>&1
umount tmp
blockdev --flushbufs /dev/ram0
exec /sbin/init ${CMDLINE} |
I can think of some improvements to be made to the script (missing EOF at the end, using devtmpfs during the initrd but not on the encrypted filesystem (this could be done to avoid needing /dev entries in the encrypted root filesystem).
I'm about to do some testing to see if cryptsetup really does allow formatting and mounting a device already in use.
Edit: Yes, turns out cryptsetup 1.1.3 allows setting up the same backing device twice with different settings. Maybe this is worth checking against at least to prevent stupid mistakes? |
|
| Back to top |
|
 |
Hu Watchman

Joined: 06 Mar 2007 Posts: 6827
|
Posted: Sun May 29, 2011 3:14 am Post subject: |
|
|
| BradN wrote: | | Code: | bailout()
{
echo Something failed. Please accept this shell as a substitute.
exec /bin/sh
} |
| You could omit the exec so that the user has a chance to fix the problem, exit the shell, and allow the boot to resume.
| BradN wrote: | | Code: | until findfs UUID=${EncUUID}
|
| You could save the value of findfs into a variable so that you do not need to call it again for luksOpen.
| BradN wrote: | | Code: | cd /realroot
pivot_root . tmp # use /tmp in encrypted FS as placeholder for initrd filesystem
exec chroot . /bin/sh <<- EOF > /dev/console 2>&1
umount tmp
blockdev --flushbufs /dev/ram0
exec /sbin/init ${CMDLINE} |
| Why not use switch_root to do all this for you?
| BradN wrote: | | Yes, turns out cryptsetup 1.1.3 allows setting up the same backing device twice with different settings. Maybe this is worth checking against at least to prevent stupid mistakes? | Yes, that sounds like a worthy improvement, if it can be detected readily. |
|
| Back to top |
|
 |
BradN Advocate


Joined: 19 Apr 2002 Posts: 2270 Location: Wisconsin (USA)
|
Posted: Sun May 29, 2011 3:41 am Post subject: |
|
|
Using "exec" in the error path: I had thought about this, but I figured if something went wrong, I would be preserving the most usefulness of the environment by starting a fully fresh shell - if exec'ing the new /sbin/init is to be possible, it can only be done by the first process. I didn't want that first process to be stuck in the middle of executing a script.
| Quote: | | You could save the value of findfs into a variable so that you do not need to call it again for luksOpen. |
Noted I'll make this modification - it adds a little more atomicity to the way it works, even though it really shouldn't matter.
About switch_root:
switch_root apparently only works on true initrd (cpio style, not using squashfs). I tried this. A lot. First I had to add /init as a regular file to pass one test. Then it has a test against the filesystem magic that doesn't work with squashfs. So I had to find another way to switch the root.
To be honest, I wanted to use a xz'd cpio archive (probably makes a bit smaller initrd than squashfs), but I had problems making the xz utility compress the data with the x86 BCJ filter enabled. So I just went back to squashfs (which I could get to use the settings I wanted). |
|
| Back to top |
|
 |
balkira Tux's lil' helper


Joined: 25 Dec 2004 Posts: 99 Location: /local/pub
|
Posted: Sun May 29, 2011 9:05 am Post subject: |
|
|
Hi,
1) why making an initrd (deprecated) and not an initramfs, the later being more robust and easier to maintain?
2) pivot_root usually is for initrd, switch_root for initramfs. You should use switch_root.
3) you should use the Gentoo's linuxrc scripts as a base by default and then expand (or adapt) its features (if needed) from there.
4) switch_root+squashfs is ok.
5) to use xz with an initramfsf you need the kernel builtin for it.
I totally understand the need of a custom initramfs but why not using the linuxrc from Gentoo (the one shipped in genkernel)? It handles most of every need for a custom initramfs (passing kernel options for extra features) AND you still have a somewhat 'official' boot kernel interface (at least you can apply the Gentoo docs for the mystical boot options). Drop it inside your initramfs it just works (don't forget initrd.scripts and initrd.defaults to put in /etc for the linuxrc to work).
I'm using cryptsetup for a few years already and never experienced data corruption (else than corruption of the disk itself).
My laptop has 2 SSD disks. The first one is / the second is /home. I use cryptsetup-1.2.0-r1.
When booting the initramfs opens / and after switch_root /home gets opened (so I type 2 passphrases).
I've rewritten 90% of genkernel's features (and a few genkernel doesn't have - like adding dropbear to the initramfs to reboot fully luks'd remote servers via ssh) in a python project called KIGen and since then I've never had a single headache about cryptsetup and/or initramfs (I use it weekly for the past year almost).
You could try using https://github.com/r1k0/kigen (latest 0.3.0 ebuild in download section) it's user friendly and has a lot of configurable features - lvm2,disklabel,dmraid,dropbear for remote SSH booting,keymap,splash and others - and creates a rich / environment from which you can boot painlessly.
Note that the whole initramfs fs is readable in /var/tmp/kigen/work after each build so you can create a consistent base and then finish the work manually if you want or let the software handle the job for you.
Good luck _________________ no way to happiness, happiness is the way |
|
| Back to top |
|
 |
BradN Advocate


Joined: 19 Apr 2002 Posts: 2270 Location: Wisconsin (USA)
|
Posted: Sun May 29, 2011 7:08 pm Post subject: |
|
|
I'm pretty sure the data loss was my fault at this point, especially since retesting and finding cryptsetup does allow format/open on a device already in use.
I'm a little confused what the difference between initrd / initramfs actually is? I've seen references to making a cpio archive, and it seems like this route would actually work with switch_root. What exactly is an initramfs?
To point out what I was talking about with switch_root, here is some of the kind of code busybox has for its switch_root:
| Code: | #ifndef RAMFS_MAGIC
#define RAMFS_MAGIC 0x858458f6
#endif
#ifndef TMPFS_MAGIC
#define TMPFS_MAGIC 0x01021994
#endif
|
| Code: | // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE
// we mean it. (I could make this a CONFIG option, but I would get email
// from all the people who WILL eat their filesystems.)
if (lstat("/init", &st1) || !S_ISREG(st1.st_mode) || statfs("/", &stfs) ||
(stfs.f_type != RAMFS_MAGIC && stfs.f_type != TMPFS_MAGIC) ||
getpid() != 1)
{
bb_error_msg_and_die("not rootfs");
}
// Zap everything out of rootdev
delete_contents("/"); |
How can you possibly delete files on a squashfs??? |
|
| Back to top |
|
 |
Hu Watchman

Joined: 06 Mar 2007 Posts: 6827
|
Posted: Sun May 29, 2011 10:14 pm Post subject: |
|
|
| Since squashfs is read-only, I do not think you can clear it out. For kernels where I want an initramfs, I let the kernel build it into the kernel image. I do not compress the initramfs explicitly, but do benefit from it being in the kernel image, which is then compressed. |
|
| Back to top |
|
 |
BradN Advocate


Joined: 19 Apr 2002 Posts: 2270 Location: Wisconsin (USA)
|
Posted: Sun May 29, 2011 10:52 pm Post subject: |
|
|
I was mostly replying to balkira's comment: | Quote: | | 4) switch_root+squashfs is ok. |
Looking at the code, I don't see how it would possibly work. Even if it would pass the filesystem magic test, it's the wrong approach for such a filesystem. The space is freed not by unlinking the files but by freeing the ram block device it's residing in.
Anyway, initramfs is where you specify a folder for the kernel to include inside itself? |
|
| Back to top |
|
 |
Hu Watchman

Joined: 06 Mar 2007 Posts: 6827
|
Posted: Mon May 30, 2011 3:16 am Post subject: |
|
|
| Yes. You can also specify a file that describes a virtual folder, which will be constructed and embedded. This can be useful if you do not want to keep separate copies of all the files that you include. |
|
| Back to top |
|
 |
|