Things I Learned the Hard Way Doing Full Disk Encryption on Gentoo with DM-Crypt LUKS

The documentation for setting up full disk encryption on Gentoo is specific at best, spotty at worst and confusing in general. Without re-living the immense pain it was to configure over again in detail, here are some of the things I wish I knew before I started:

  • The 2TB partition size limit is not a Windows-only limitation. It comes from the old BIOS style partition scheme. You can either use parted to create >2T GPT partitions or use the whole raw disk if you plan on using it for a single mount point or if you fancy putting DM/LVM on top. Obviously that isn't an option if you plan on booting from this device.
  • If you don't think you need LVM you probably don't, especially if this is a workstation or personal computer. It's way easier to skip all of that and use old-fashioned device nodes directly.
  • Having a newline character in your keyfile is deadly. The init script that genkernel rolls into your initramfs uses cryptsetup luksOpen /dev/whatever whatever -d - or --keyfile - instead of simply piping the output of gpg as the wiki article has you do when you luksFormat. The former stops reading the input at a newline, the latter incorporates it into your key. This is a problem if, say, you took the output of openssl rand -base64 96 because you wanted to generate a 512 bit or larger key. There is already a newline in the middle of the cleartext, so I thought I was clever when I removed it. Not so; nano and many other text editors will always leave a newline at the end of the file. If you cat the cleartext and your command prompt doesn't run on to the end of it you still have a newline in there. Pipe your keyfile through tr -d '\n' before you do anything to be safe.
  • genkernel will make mrproper unless you use the --no-clean or --no-mrproper flags. It will back up your .config and start building your kernel the way it wants to unless you specify ramdisk.
  • The plain64 IV doesn't take arguments, specifying sha512 as the hash is redundant.
  • Genkernel will not magically read /etc/conf.d/dmcrypt and import your keyfiles or their locations. You may need to add the following to your kernel command line, replacing {UUID} with the UUID of your /boot partition (or wherever you are keeping the keyfile). You can obtain the UUID by running blkid. Using a UUID instead of a path will allow you to store your keyfile on removable media which may not have the same device node from time to time.
    real_root=/dev/mapper/root crypt_root=/dev/sda2 root_key=root.gpg root_keydev=UUID={UUID}

    If you are using grub2 append this to your GRUB_CMDLINE_LINUX variable in /etc/default/grub and if you are booting Xen remember to ALSO append it to your GRUB_CMDLINE_LINUX_XEN_DEFAULT variable.

  • Non-root partitions will be luksOpened and mounted during bootup by the dmcrypt init script.

Zombie Disk Image is Loopback-Mounted in a Guest Domain and can't be Mounted

Chances are if you're reading this you've just pulled yourself out of a xend crash or a similar event which has left one or more zombie VM disk images attached to their loop device. You're trying to restart the VM but you keep getting this message:

Error: Device 2049 (vbd) could not be connected.
File /xen/vm/disk.img is loopback-mounted through /dev/loop/5,
which is mounted in a guest domain,
and so cannot be mounted now.

losetup will only tell you what you already know:

# losetup -d /dev/loop/5
loop: can't delete device /dev/loop/5: Device or resource busy

If you don't know the ID number of the VM before it tanked you can find it in your xend logs. Execute this command to free the loop device:

# xenstore-rm backend/vbd/{VM ID}

How to Disable PHP mail() Per-Domain/Vhost without Suhosin or FPM/suEXEC

So I'm tired of my goddamned WordPress blog (yep, this one) getting compromised and being used as a platform for spammers or phishers and so on.

Getting pwn't every so often is pretty much just a fact of using popular shrinkwrapware and being a lazy updater. But that's no reason to change our ways when we can just mitigate the damage - namely getting your web server's IP on to all those friendly RBLs and interrupting legit e-mail notification delivery.

The good news is you can use disable_functions in your php.ini to disable functions globally.

The bad news is you can't set disable_functions on a per-domain or vhost basis unless you're using FPM/suEXEC or the like.

The worse news is suhosin, a really sweet PHP security patch that I've written about before and which would give us the ability to do this has been abandoned for about two years now and there is no official support for php 5.4 and later.

So I'd like to give Dave Lachapelle a big round of applause for pointing out that even if you can't kill mail() you can at least cripple it. From http://www.davelachapelle.ca/2009/08/05/php-mail-abuse/:

...PHP doesn’t support setting disable_functions in the php_admin_value flag.

So, after a bit of searching, I decided to just add the following to each site’s .htaccess files:

php_admin_value sendmail_path "/dev/null"

Essentially sending all e-mail to /dev/null for that particular site. Perhaps not the most elegant solution, but it was effective...

Maybe not elegant, but surely classy.

Stay classy, Dave.