[pkg-cryptsetup-devel] Bug#838001: Bug#838001: cryptsetup does not support ZFS

Richard Laager rlaager at wiktel.com
Sun Sep 18 00:37:23 UTC 2016


On 09/17/2016 06:45 PM, Guilhem Moulin wrote:
> On Fri, 16 Sep 2016 at 04:32:24 -0500, Richard Laager wrote:
>> The attached patch adds ZFS support to cryptsetup.
> 
> Thanks the patch.  Unfortunately I can't test it easily, and I know
> nothing about ZFS, but I'll try to review your patch anyway.

Thanks for taking the time to look at this. I'm happy to help in
whatever way I can. Whatever you need, just ask, and I'll do my best.

You might find the upstream ZFS-on-Linux project's root-on-ZFS HOWTO
(which I maintain) informative, even though it's written for Ubuntu:
https://github.com/zfsonlinux/zfs/wiki/Ubuntu-16.04-Root-on-ZFS

I have changes all ready-to-go for supporting LUKS, but this "bug"
(read: feature request) is a blocker. It is possible to work-around this
with (otherwise unused) /etc/fstab entries, but I don't want to
encourage that in the wild, lest it cause some other problem in the future.

My general approach to using LUKS with ZFS is that GRUB prompts for the
passphrase, unlocks LUKS, which ZFS is inside, and reads the kernel and
initrd. When the kernel boots, the initrd contains a keyfile which is
used to unlock LUKS again. This maintains the goal of having everything
including /boot, but excluding GRUB, on ZFS.

However, I am aware that it deviates from the Ubuntu approach of an
unencrypted /boot with an initrd that prompts for the LUKS passphrase.
So I'm forced to choose between two major goals: 1) everything on ZFS &
2) stay as close to normal Ubuntu as possible.

Here are some selected parts of the diff, which outline how I'm using
LUKS, ZFS, and cryptsetup.

+    # cryptsetup luksFormat -c aes-xts-plain64 -s 256 -h sha256 \
+          /dev/disk/by-id/scsi-SATA_disk1-part1
+    # cryptsetup luksOpen /dev/disk/by-id/scsi-SATA_disk1-part1 luks1
+    # zpool create -o ashift=12 \
+          -O atime=off -O canmount=off -O compression=lz4 -O
normalization=formD \
+          -O mountpoint=/ -R /mnt \
+          rpool /dev/mapper/luks1


+    # mkdir /etc/keys
+    # dd bs=64 count=1 if=/dev/urandom of=/etc/keys/root.key
+    # chmod 600 /etc/keys/root.key
+    # cryptsetup luksAddKey /dev/disk/by-id/scsi-SATA_disk1-part1
/etc/keys/root.key
+    # echo luks1 UUID=$(blkid -s UUID -o value \
+          /dev/disk/by-id/scsi-SATA_disk1-part1) /etc/keys/root.key \
+          luks,discard > /etc/crypttab
+
+    # vi /etc/initramfs-tools/initramfs.conf
+    Add these lines:
+    export KEYFILE_PATTERN="/etc/keys/*.key"
+    UMASK=077

On a side note, it'd be nice if cryptsetup would automatically set UMASK
when a keyfile is found. And it'd be nice if there as a default where it
looked for keyfiles.


As another resource, here's the upstream HOWTO for Debian, which someone
else maintains:
https://github.com/zfsonlinux/zfs/wiki/HOWTO-install-Debian-GNU-Linux-to-a-Native-ZFS-Root-Filesystem

The HOWTOs share some history, but are not developed in lock-step. The
packaging for Debian and Ubuntu has also been different historically.
Now that ZFS has been accepted into both Ubuntu and Debian, people are
working on reducing the differences.

>> +	zfs list -H -o name,canmount,mountpoint 2>/dev/null | \
> 
> Looks like there is support for ZFS filesystems in the /etc/fstab
> <https://wiki.freebsd.org/RootOnZFS#Alternate_.2Fetc.2Ffstab>.  Since
> it's what other FS are using, I think that's what we should use for ZFS
> too.

ZFS does not normally use /etc/fstab. That's not to say it's impossible
(obviously, it is), but that is absolutely not what users expect of ZFS
nor how it is used in practice.

I don't know why that wiki page leans so heavily on mountpoint=legacy
and /etc/fstab. You won't find that in other ZFS documentation for any
OS, including the more up-to-date FreeBSD documentation linked from the
header on that page.

> Don't the ‘name’ and ‘mountpoint’ columns of your ‘zfs list’
> command respectively correspond to the first and second columns of
> fstab(5)?

Yes.

>> +			for dev in $(zpool status -P "${name%%/*}" 2>/dev/null | awk '($1 ~ /\//) {print $1}'); do
> 
> This looks rather brittle, as the ‘status’ command seems to be intended
> for humans not parsers.

It's not ideal, I admit, but it's "how it's done". The -P flag was added
specifically because the output of `zpool status` is frequently parsed.
Parsing `zpool status` is exactly how GRUB handles ZFS. If its output
changes, GRUB breaks too.

Ideally, there'd be a -H flag that omits extraneous output and spaces,
like on the zfs command.

> Isn't there a more robust way to retrieve the
> underlying device list of a ZFS pool?

Using libzfs is another way, if your application is compiled. However,
that can be a problem for certain applications because of licensing. For
example, GRUB uses libzfs on Solaris where they can take advantage of
the system library exception in the GPL, but they parse `zpool status`
on other OSes, including Linux.

Since cryptsetup is a shell script, a C library is a non-starter anyway.

-- 
Richard

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: OpenPGP digital signature
URL: <http://lists.alioth.debian.org/pipermail/pkg-cryptsetup-devel/attachments/20160917/9b8ad309/attachment.sig>


More information about the pkg-cryptsetup-devel mailing list