[dm-crypt] The future of disk encryption with LUKS2

Sven Eschenberg sven at whgl.uni-frankfurt.de
Mon Feb 8 18:27:02 CET 2016



Am 08.02.2016 um 07:09 schrieb f-dm-c at media.mit.edu:
>      > Date: Mon, 8 Feb 2016 05:32:14 +0100
>      > From: Sven Eschenberg <sven at whgl.uni-frankfurt.de>
>
>      > Of course, that's what I usually do anyway. But we'll have to at least
>      > consider an average user aswell, having a normal desktop, using a magic
>      > mumbo jumbo installer with LVM on top of dm-crypt setup. It's not about
>      > covering your or my use case, but rather those of as many users as
>      > possible, without sacrificing i.e. security though.
>
> Right.  And the average user is using an installer that might want to
> expand a partition.  If that doesn't work, LUKS is a nonstarter there.

Honestly, I am just imagining the average user, starting its installer 
for the first time and going like: Darn, there's that LUKS-partition 
from my last install - It's a pitty it cannot be resized.

Seriously, the task of resizing ANY partition during installation is far 
from being average user's standard task and ALWAYS imposes immediate 
threat to the data, no matter if we talk about LUKS, a plain filesystem, 
lvm+fs or whatsoever.

> Even if it -could- work, but installers suddenly have to be aware of
> which version of LUKS they're talking so they can supply magic random
> options, then that's a situation where it's very likely that installers
> will screw it up.  And installers screwing it up is -precisely- why
> we're talking about having header redundancy in the first place.
> Let's please not -encourage- screwups of rare-and-not-well-tested
> actions that can lose data.

But the same holds true for all non-LUKS cases too. Replace partition 
holding LUKS-container by device holding disklabel. There's a complete 
zoo of disklabels. Take GPTs for instance - either the installer does 
update both copies and can handle displaced secondary copies by itself, 
or it will at least need to talk to one of the many partitioning tools 
that does this job. And it will need to know how to 'instruct' the tool 
to do the job. And an installer does not talk to LUKS nor is it aware of 
what version of LUKS is used, it 'gently asks' the tools responsible for 
handling the operation to do it.

>
> Also, the -average- user is not experiencing multiple megabytes of
> corruption at the beginning of partitions.  C'mon.  The -average-
> user is experiencing a bad Ubuntu installer deciding to put a
> partition table on top of a LUKS header or some other handful-
> of-sectors corruption.  Not a megabyte, much less ten or more.

Possibly, but maybe the ubuntu installer puts LVM metadata there, 
creates a LV and a filesystem, and all the sudden we talk about 1+ MByte 
of corrupted data. (Unfortunately some distributions consider LVM the 
default)

>
>      > Of course overcomplicating things is not an option. But you should
>      > always remember: A damaged header is a total loss, a damaged fs can
>      > quite often be recovered easily enough. And other tools need 'special
>      > instructions' for every fs, dm-layer and task. There's no generic
>      > resize() IOCTL for all your block layers.
>
> But all the rest of them do assume that they can use the entire
> container unless you say not to, and that expansion works.

Maybe I am not getting your point here, but for dm-crypt this does hold 
true. A filesystem tool that operates on the partition container will 
happily trash mdadm headers on the partition, if it is not aware of the 
presence of the metadata.

Anyhow for resizing each layer and each corresponding tool needs to be 
able to resize, agreeed. But there's no difference to cryptsetup then. 
Resizing with two metadatacopies can be done, it just needs extra work. 
Same holds true for other layers, if you thing about it:
GPT, backing store scales up -> secondary metadata is displaced. Move 
secondary metadata, update primary metadata. Doing this right and 
resilient needs caution. On a scale down the secondary metadata is lost 
altogether (and can be recreated from the primary metadata). Better 
first scale down the contents of the container.
mdadm: only one array metadata copy on each device and a per device 
metadata section. What happens if all backing devices grow? In the cases 
where metadata is at device's end you'll certainly run into trouble.
LVM - resize is a non worker for multiple metadata copies.


>
> Every single layer of what -I- do -is- resizeable---I can resize
> partitions, and LVM, and LUKS, and ext4.  Any solution in which LUKS
> can no longer be resized (especially grown) means that LUKS will be
> instantly heaved overboard in favor of something else that can,
> because it's the only thing in the stack which would fail that test.
>
>      > I don't mind keeping it simple. Really simple and secure was already
>      > mentioned: You do have a backup anyway, just recreate the container and
>      > pull back the backup and you are done ;-). Resizing (growing) is just a
>      > convenient thing to do.
>
> Did you actually read my original message?  As I said, in my use case,
> it is simply not an option to "back up, blow away, resize, and put
> back," because having to do that offline means multiple days of
> downtime to do two entirely-pointless block-level copies, one in each
> direction, on a -dismounted- FS.  Those multiple days are clearly not
> required if LUKS can grow---I've done it before without downtime,
> precisely because all layers can grow.

I did read your mail and yes I do see your use case and yes, I do have 
this use case too. As I stated in another mail, it is also possible to 
ditch a secondary header, recreate at the new location and update the 
mapping. There's no magic in there, except it is not completely safe. Or 
rather, it is as unsafe as now.

By the way, do you really think it is safe to update a disklabel to grow 
a partition? While it is only one sector for MBR, a failure during 
update is fatal. On GPT you do have a secondary copy. But if the device 
grows updating the GPT properly needs complicated extra work aswell.

>
> Let me try to summarize:  The reason we are having this conversation
> at all is because proposals to increase the robustness of LUKS headers
> almost immediately allowed the perfect to become the enemy of the good
> ---to the point where increasing their robustness lead to comments like
> "well, let's just kill the ability of LUKS to grow because it's too
> hard to figure out how to preserve the multiple headers in that case."
> That is a big warning sign that the proposal is too complex.

It is always hard to solve problems which consist of opposing design 
goals. Unfortunately...

>
> One other thing:  One problem with putting a redundant header at the
> end is that something which resizes the container out from under LUKS
> (prime candidate for "something just corrupted the container") means
> that LUKS (and any user trying to find that header by hand) has no
> idea where to look for it, short of scanning every single block on
> the disk for something that looks like a header.  Putting it near the
> front means that LUKS either has only one option, or at the very least
> only a very small number of blocks to scan, before it concludes that
> it's either found the header or there isn't one.

mdadm suffers from this problem by the way, at least for metadata 
versions 0.9 and 1.0. Anyhow, desaster recovery is not LUKS' intrinsic 
task. If you need to recover from such a failure, you know the old size 
of the container (approx) and instruct the recovery process to scan at 
the whereabouts of that place.

A similiar issue arises at the front of the container, it is just less 
common. Growing the preceeding partition imposes exactly this type of 
threat.

>
> [For example, and to take into account "OMG but what if massive giant
> corruptions and/or mislayered tables at start," have these as defaults:
> (a) FS < 10 meg --> no extra header
> (b) 10 meg < FS < 100 meg --> extra header after 1 meg gap
> (c) 100 meg < FS < 10 gig --> extra header after 10 meg gap
> (d) fs > 10 gig --> extra header after 100 meg gap
> (where "gap" means "really unused---don't give it to the FS" or maybe
> even "put a backup header every n megabytes all through the gap"), and
> have --redundant-header-at=[none|offset-in-meg] option for those who
> insist on putting it somewhere magic.  Now LUKS has at most 3 places
> to look even if it doesn't know how big the FS was, or a scan if the
> user used --redundant-header-at.  But the code is still very simple,
> online resizing works the way it always did, and people who are super-
> paranoid about corrupting a gig at the start of their partition can
> throw away an entire gig by pushing it farther in or something.  Or
> putting it at the end, but then LUKS has to treat the gap as actual FS
> storage area, which is again more complicated, so I don't recommend it.]

I do see a chance of Joe Average complaining about the 'lost' (unsused) 
space. Another problem with configureable offset is, that you'd again 
have to store the location information in the primary header. If that 
gets corrupted, the secondary header would be dangling and you'd have to 
scan for that.

Anyhow, as I see it, this discussion is about the choice of sane 
defaults. Question, do more people value the safety of an extra header, 
without any extra params or do more people value online resizing without 
extra parameters and effort.

Variants:
--no-secondary - during format. No extra safety, easy online resizing
--scratch secondary - first trashes secondary header, updates the 
secondary header, remaps, recreate secondary header. Gives you the 
safety of the backup header, while having the exact same online resizing 
ability as single header and same dangers of course during the resize phase.
Have secondary header and do onlinze resizing, implementation needs 
extra effort.

And last but not least, I am not sure if it is a good idea to base 
behavior on FS size. So (a) is probably a really bad idea as it behaves 
differently from the others. (b) could be a close call for LVM (metadata 
size 1Mbyte + whatever the next, upper, layer would additionally 
destroy) and possibly mdadm.

Regards

-Sven


More information about the dm-crypt mailing list