Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to build full disk encryption with kiwi-ng #149

Closed
Hooverdan96 opened this issue Dec 8, 2023 · 5 comments · Fixed by #150
Closed

Ability to build full disk encryption with kiwi-ng #149

Hooverdan96 opened this issue Dec 8, 2023 · 5 comments · Fixed by #150

Comments

@Hooverdan96
Copy link
Member

As pointed out in a couple of threads over time, there can be a desire to have full disk encryption also for the OS drive, which Rockstor does not offer out of the box. Until/If we are going to offer a downloadable iso, we could explore kiwi-ng to allow for creating a custom image that allows LUKS during installation (for the OS drive).

I have been able to semi-successfully do this. There are a couple of things that still need to be worked out:

  • when using (recommended) LUKS2, force PBKDF to PBKDF2 instead of the default argon2id, since Grub doesn't support it (yet)

The kiwi test template shows the use of luks_pbkdf="pbkdf2", but that does cause an error in our kiwi installer (I also couldn't really find a reference to that attribute).

https://github.com/OSInside/kiwi/blob/master/test/data/example_config.xml#L61C22-L61C22

  • image size suddenly grows to 2.9 GiB. Not much of a concern when testing as a virtual iso on e.g. VirtualBox, but would be interesting to understand why it's all of a sudden way larger, especially since the pre-requisite of package=cryptsetup is already part of the original kiwi installer file.

Workaround to see implications with the full disk encryption installer was after installation, initial setup and before reboot to force the key change via cryptsetup luksConvertKey --pbkdf=PBKDF2 /dev/sda4.
Then Rockstor survived the reboot and grub recognized the partition, etc. subsequently setting up the Data Disks for a pool to Luks following the Rockstor documentation and another reboot alter seems to show all is well in LUKS land.

The WebUI shows some quirks of course in the disk view (might be expected or not, I don't know):

After the initial install, only OS disk is LUKS encrypted:
image

image

Lsblk:
NAME     MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINTS
sda        8:0    0   10G  0 disk
├─sda1     8:1    0    2M  0 part
├─sda2     8:2    0   64M  0 part  /boot/efi
├─sda3     8:3    0    2G  0 part  [SWAP]
└─sda4     8:4    0  7.9G  0 part
  └─luks 254:0    0  7.9G  0 crypt /mnt2/ROOT
                                   /var
                                   /usr/local
                                   /tmp
                                   /srv
                                   /root
                                   /opt
                                   /boot/grub2/x86_64-efi
                                   /home
                                   /boot/grub2/i386-pc
                                   /.snapshots
                                   /
sdb        8:16   0   10G  0 disk
sdc        8:32   0   10G  0 disk
sr0       11:0    1    3G  0 rom

And the LUKS config was like this:

Luca# cryptsetup luksDump /dev/sda4
LUKS header information
Version:        2
Epoch:          4
Metadata area:  16384 [bytes]
Keyslots area:  16744448 [bytes]
UUID:           9f104a78-b53e-4be7-9342-3702e5ee3b2e
Label:          (no label)
Subsystem:      (no subsystem)
Flags:          (no flags)

Data segments:
  0: crypt
        offset: 16777216 [bytes]
        length: (whole device)
        cipher: aes-xts-plain64
        sector: 512 [bytes]

Keyslots:
  0: luks2
        Key:        512 bits
        Priority:   normal
        Cipher:     aes-xts-plain64
        Cipher key: 512 bits
        PBKDF:      argon2id
        Time cost:  4
        Memory:     1048576
        Threads:    2
        Salt:       42 07 92 df 7d 9f d0 b9 a7 07 0d 6b 2e ad 6f 28
                    ad 6d 94 d1 cc d8 d1 f0 3f 4c d6 86 cb 81 93 de
        AF stripes: 4000
        AF hash:    sha256
        Area offset:32768 [bytes]
        Area length:258048 [bytes]
        Digest ID:  0
  1: luks2
        Key:        512 bits
        Priority:   normal
        Cipher:     aes-xts-plain64
        Cipher key: 512 bits
        PBKDF:      argon2id
        Time cost:  4
        Memory:     1048576
        Threads:    2
        Salt:       b8 95 5d c7 d8 9d f0 07 16 b9 64 52 c5 78 63 bc
                    4e 7e c1 34 83 09 3b 79 5a d7 58 98 16 96 03 57
        AF stripes: 4000
        AF hash:    sha256
        Area offset:290816 [bytes]
        Area length:258048 [bytes]
        Digest ID:  0

Subsequent PBKDF conversion changed the Keyslot 0 from argon2id to PBKDF2, allowing for grub to recognize and process the encrypted OS disk.

After setting up the other 2 disks under LUKS (with automatic unlocking using key file), the end result is displayed like this:

image

Changes in the rockstor.kiwi file was to add these two lines in the type definition:

				luks="c00l_Pa$$Phra$e"
				luks_version="luks2"

I also initially added the parameter from the kiwi template:

				luks_pbkdf="pbkdf2"

but that threw an error message right away, so not sure yet how to force this setting differently.

In summary,
once the above is figured out, I can either add a new profile, put it into the existing x86_64 profile, but commented out with instructions, or we add it to the installer read me on what to do if one wants full disk encryption. Discuss.

@FroggyFlox
Copy link
Member

Thanks for such a nice run-down!

I just wanted to chip in on the following in case it helps:

The kiwi test template shows the use of luks_pbkdf="pbkdf2", but that does cause an error in our kiwi installer (I also couldn't really find a reference to that attribute).

I find myself checking the schema "definition" itself rather often just in case something is not included in the docs yet. That setting is validated at the following section:

https://github.com/OSInside/kiwi/blob/ef2720b8264206451b96ab64292daf4bbb8b6e3d/kiwi/schema/kiwi.rng#L2954-L2966

    <define name="k.type.luks_pbkdf.attribute">
      <attribute name="luks_pbkdf">
        <a:documentation>When LUKS unlocks a key slot using a user provided
password, it uses a so-called key derivation function
to derive a symmetric encryption key from the password.
Not all boot loaders support all KDF algorithms, hence
this attribute can be used to select a specific algorithm.</a:documentation>
        <choice>
          <value>pbkdf2</value>
          <value>argon2i</value>
          <value>argon2id</value>
        </choice>
      </attribute>

@Hooverdan96
Copy link
Member Author

Hooverdan96 commented Dec 9, 2023

Thanks @FroggyFlox for the hint, good idea. However, that schema info implies that the above should have worked, but didn't (unless I made a mistake in the file itself). I did another round of testing. It seems, the definition needs to look like this instead. Maybe it needs even further refinement ...

        <type
                image="oem"
                primary="true"
                initrd_system="dracut"
                filesystem="btrfs"
                fsmountoptions="noatime"
                bootloader="grub2"
                firmware="efi"
                installiso="true"
                kernelcmdline="nomodeset plymouth.enable=0 rd.kiwi.oem.maxdisk=5000G"
                bootpartition="false"
                devicepersistency="by-label"
                btrfs_root_is_snapshot="true"
                btrfs_quota_groups="false"
                efipartsize="64"
+		luks="c00l_Pa$$Phra$e"
+		luks_version="luks2"
        >
+           <luksformat>
+              <option name="--pbkdf" value="PBKDF2"/>
+           </luksformat>
            <systemdisk>
            ....

so, one passes specific parameters using the luksformat tag instead (any of the cryptosetup parameters seem to be possible).

The iso is successfully created, and upon installation the correct pbkdf is used. After initial setup, and subsequent reboot (before setting up the LUKS data disks), Grub recognizes and interacts with the LUKS process correctly! So, that's great.

@FroggyFlox since you've been building some test isos for your last PR here, did you notice a "swelling" in size on 15.5?
For comparison, yesterday and today I built these 3 isos on a 15.5 desktop (not using container but within that VM itself) and here are there corresponding sizes:

Rockstor-NAS.x86_64-4.5.8-0.install.iso 973.7 MB --> vanilla with config file as is
Rockstor-NAS.x86_64-4.5.8-0.install_luk.iso 2.95 GB --> first iteration of using Luks2 (but having argon2id in there)
Rockstor-NAS.x86_64-4.5.8-0.install_luk2.iso 3.2 GB --> latest iteration using luks2 (but with "correct" pbkdf2)

Any idea why this would blow up the size so much?

For both of you, how to proceed? Add another Luks2 profile into the rockstor.kiwi file? Or a different approach?

Finally, I can open a separate issue in the rockstor-core repo, but do we want to transition the WebUI LUKS setup from luks1 to luks2? Obviously not the highest priority, but if we do, then keep track of that?

@phillxnet
Copy link
Member

@Hooverdan96

This is all great progress. I did notice that kiwi-ng introduced more LUKS capabilities a while back.

Incidentally I'm currently working on updating our back-end that builds our final installers and got a recent installer size of:

Installer size
Rockstor-Leap15.5-generic.x86_64-5.0.5-0.install.iso 891.06 MB

Could the size expansion be due to the squashfs now working with what looks like a random image (pre-decryption). I.e. kiwi-ng builds an encrypted image to transfer to target disk during the install. It is only then de-crypted on the later stages of the installer 'booting' that image. Or rather transitioning the installer kernel over to it.

Re:

... do we want to transition the WebUI LUKS setup from luks1 to luks2?

I had thought, from memory, that I chose LUKS2 by default when I implemented our LUKS support way-back actually.
But on taking another look at the initial:
core issue/pr: support full disk luks. Fixes #550 #1716
doc pr: rockstor/rockstor-doc#170
it seems not !!

Plus I had also thought we had an open issue for that from yourself actually. Can't find it currently: but do create one as this looks to be entirely viable (hopefully) and desirable. It was 6 years ago now and we were on CentOS back then! Maybe I went with the defaults at that time.

@Hooverdan96
Copy link
Member Author

@phillxnet I opened a new issue as discussed. Your installer is still roughly 80MB smaller on the vanilla compared to my test build. Wondering why that might be, but not that urgent, probably just keeping an eye on it.

Could the size expansion be due to the squashfs now working with what looks like a random image (pre-decryption). I.e. kiwi-ng builds an encrypted image to transfer to target disk during the install. It is only then de-crypted on the later stages of the installer 'booting' that image. Or rather transitioning the installer kernel over to it.

So, you think there might be a way to influence the starting size (on the iso) of that?
Again, probably not that urgent, especially if it doesn't become an official flavor for now, but only for the "roll your own" crowd that needs this additional security layer.

@phillxnet
Copy link
Member

@Hooverdan96 Thanks.
Re:

Your installer is still roughly 80MB smaller on the vanilla compared to my test build. Wondering why that might be, but not that urgent, probably just keeping an eye on it.

Probably as it was 5.0.5-0 whiich has a poetry install issue currently re Poetry version that should be fixed in testing but we are, as yet between testing rpms. But same ball-park roughly. We have also had some new dependencies re Py3.11 so there will be some difference once the dust settles and we have 5.0.6-0 out.

So, you think there might be a way to influence the starting size (on the iso) of that?

Probably not significantly. We are image based, on the install front, and once that image is scrambled (encrypted) squashfs can do little with it. Hence it appearing roughly the size of uncompressed image. I've yet to look closer at this side of things however. We could reduce the image partition size, but again that will likely have negative ramifications.

I think for now we have this as a build-your-own option where the required config is remarked out - but proven to work. That would be nice. We also have a somewhat limited upload/download space - so we just couldn't handle images of that size across so many OS and arch targets. But I'm hoping to reduce our OS version target range soon. However that ends up inevitably leaving folks with existing out-of-scope OS versions, out in the cold - something I'd like to avoid if we can. But if say we supported only latest Leap and TW that would certainly help - however I think we should have to shrink to just a single OS target to fit reasonably within our resources :) . Especially if we have such huge installer images.

So maybe a dedicated howto is the way to go in the interim, or more elegantly a dedicated Readme section within the rockstor-installer repo. I.e. "uncomment the following and change this password" before building type thing with info on ramifications re image size, required disk space to build, password importance etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants