Chrysostomus / manjaro-architect

Development branch of the Architect Installation Framework
GNU General Public License v2.0
86 stars 18 forks source link

[Encryption LVM on LUKS] Add the possibility to create a physical LVM volume #217

Closed mhham closed 6 years ago

mhham commented 7 years ago

When creating a LUKS partition and mounting it, there should be an option to create a physical LVM volume (# cryptsetup open /dev/sdaX cryptolvm then # pvcreate /dev/mapper/cryptolvm from archwiki). Indeed it is not straightforward that the default mounting device of the LUKS partition will always be /dev/mapper/cryptroot, and I had some trouble configuring GRUB to decrypt the correct partition at boot (using cryptdevice=UUID=device-UUID:cryptolvm root=/dev/mapper/MyVol-root). I ended up using cryptdevice=UUID=device-UUID:cryptroot root=/dev/mapper/MyVol-lroot, which worked. But it is not straightforward, especially when you choose another name than cryptroot in the manjaro-architect installer

Chrysostomus commented 7 years ago

Ok. This sounds reasonable. It is probably going to take a while, because I know lvm and luks poorly.

Chrysostomus commented 7 years ago

Could you share the relevant part of lsblk from a sustem where physical LVM volume has been created properly? I'm now doing a test install with lvm on luks, using the existing system. lsblk looks like this:

└─sdb2                8:18   1  28,5G  0 part
  └─cryptor         254:0    0  28,5G  0 crypt
    └─logic-lvmroot 254:1    0  28,5G  0 lvm   /mnt

I chose nondefault names for cryptdevice and lvm volume group to see if that works at all...

mhham commented 7 years ago

I used the archwiki to learn about encryption, especially LVM on LUKS, which is what is installed on my devices.

I am copying here the parts that answer your question :

Disk layout example :

+-----------------------------------------------------------------------+ +----------------+
| Logical volume1       | Logical volume2       | Logical volume3       | |                |
|/dev/mapper/MyVol-swap |/dev/mapper/MyVol-root |/dev/mapper/MyVol-home | | Boot partition |
|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _| | (may be on     |
|                                                                       | | other device)  |
|                        LUKS encrypted partition                       | |                |
|                          /dev/sdaX                                    | | /dev/sdbY      |
+-----------------------------------------------------------------------+ +----------------+

lsblk on my setup (virtualbox arch guest)

NAME             MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda                8:0    0   15G  0 disk  
├─sda1             8:1    0    8M  0 part  
├─sda2             8:2    0  600M  0 part  /boot
└─sda3             8:3    0 14,4G  0 part  
  └─cryptolvm    254:0    0 14,4G  0 crypt 
    ├─MyVol-swap 254:1    0    1G  0 lvm   [SWAP]
    └─MyVol-root 254:2    0 13,4G  0 lvm   /
sr0               11:0    1 1024M  0 rom   

PS: this was not a EFI setup

Chrysostomus commented 7 years ago

Thanks. while testing, I noticed that the script does not recognize the need for crypt setting if there is lvm on LUKS. Fixing that now, it shoud possibly fix also this issue.

mhham commented 7 years ago

Also I had to manually add the mkinicpio hooks and configure grub default file (sources: archwiki lvm on luks, and encrypted swap):

Configuring mkinitcpio Add the keyboard, encrypt and lvm2 hooks to mkinitcpio.conf: /etc/mkinitcpio.conf

HOOKS="... keyboard block encrypt lvm2 ... filesystems ..."

Configuring the boot loader In order to unlock the encrypted root partition at boot, the following kernel parameter needs to be set by the boot loader:

cryptdevice=UUID=device-UUID:cryptolvm root=/dev/mapper/MyVol-root

Swap encryption - LVM on LUKS

A simple way to realize encrypted swap with suspend-to-disk support is by using a swap LVM device on the same encryption layer as the root volume, so that both are opened by the encrypt hook at boot. Follow the instructions on Dm-crypt/Encrypting an entire system#LVM on LUKS and then just configure the required kernel parameters.

Assuming you have setup LVM on LUKS with a swap logical volume (at /dev/MyStorage/swap for example), all you need to do is add the resume mkinitcpio hook, and add the resume=/dev/MyStorage/swap kernel parameter to your boot loader. For GRUB, this can be done by appending it to the GRUB_CMDLINE_LINUX_DEFAULT variable in /etc/default/grub.

/etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="... resume=/dev/MyStorage/swap"

then run grub-mkconfig -o /boot/grub/grub.cfg to update GRUB's configuration file. To add the mkinitcpio hook, edit the following line in mkinitcpio.conf

/etc/mkinitcpio.conf

HOOKS="... encrypt lvm2 resume ... filesystems ..."

then run mkinitcpio -p linux to update the initramfs image.

Chrysostomus commented 7 years ago

Yeah, there is already code for automatically adding these hooks. Problem is, they rely on a faulty method, which misses the need for encryption option if there is lvm on top of LUKS. It basically checks if the part type of the thing mounted on /mnt or /mnt/boot is crypt in lsblk output, but on lvm, crypt is on another line. I'm modifying it so that it looks for "crypt" in all lines between the mountpoint and the the physical disk. So instead of looking at line

     └─MyVol-root 254:2    0 13,4G  0 lvm   /

it looks at the lines


└─sda3             8:3    0 14,4G  0 part  
  └─cryptolvm    254:0    0 14,4G  0 crypt 
    ├─MyVol-swap 254:1    0    1G  0 lvm   [SWAP]
    └─MyVol-root 254:2    0 13,4G  0 lvm   /
mhham commented 7 years ago

Nice !

I guess the only thing remaining would be to correctly modify /etc/default/grub to point to the correct cryptdevice uuid (sda3 in my case), with the root=/dev/mapper/MyVol-root and optionnaly swap=/dev/mapper/MyVol-swap if hibernation is wanted

mhham commented 7 years ago

Also I am currently trying to reinstall using manjaro-architect on a virtual machine, using the same encrypted layout. I chose /boot/efi as a mount point for EFI partition (/dev/sda1 512Mb vfat ef00 partition), which is not encrypted.

Grub-install doesn't like this:

#grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=grub --recheck

Installing for x86_64-efi platform
File descriptor 4 (/dev/sda1) leaked on vgs invocation. Parent PID 60:
   WARNING: Failed to connect to lvmetad. Falling back to device scanning.
File descriptor 4 (/dev/sda1) leaked on vgs invocation. Parent PID 60:
   WARNING: Failed to connect to lvmetad. Falling back to device scanning.
grub-install: error: attempt to install to encrypted disk without cryptodisk enabled. Set `GRUB_ENABLE_CRYPTODISK=y` in file `/etc/default/grub`

This is weird since /boot/efi is NOT encrypted. However /boot/ is.

Maybe it would be relevant to remove the option to mount the EFI partition in /boot/efi, and only keep /boot (when LUKS encryption is used), so that grub-install does not think it is encrypted. The command should then become

#grub-install --target=x86_64-efi --efi-directory=/boot/ --bootloader-id=grub --recheck

This issue is weird since my previous install (same LVM on LUKS encryption) on my laptop worked with EFI partition mounted as /boot/efi

Chrysostomus commented 7 years ago

Okay, I now fixed (hopefully) the lvm on LUKS detection. Doing now a testinstall with following steps:

1) use default partitioning scheme 2) create a LUKS device in LUKS menu 3) create lvm volume group on the lvm menu

For encrypted boot to work with grub, you need to have this line in /etc/default/grub:

  GRUB_ENABLE_CRYPTODISK=y

This is usually inserted automatically, but not in your case, because LUKS was not detected by the installer.

Chrysostomus commented 7 years ago

Long story short, it still doesn't work properly. Encrypt hook was not set automatically. Grub installs and boots. Manjaro itself does not, but that seems to be because I tested it on faulty hardware. Further tests and foxes are needed.

mhham commented 7 years ago

For encrypted boot to work with grub, you need to have this line in /etc/default/grub:

GRUB_ENABLE_CRYPTODISK=y

This is usually inserted automatically, but not in your case, because LUKS was not detected by the installer.

I think an encrypted /boot partition needs more configuring than just adding GRUB_ENABLE_CRYPTODISK=y to /etc/default/grub ( GRUB_ENABLE_CRYPTODISK=y ) (cf. here)

Long story short, it still doesn't work properly. Encrypt hook was not set automatically. Grub installs and boots. Manjaro itself does not, but that seems to be because I tested it on faulty hardware. Further tests and foxes are needed.

What I ended up doing to make things work perfectly on my setup was mount the EFI partition as /boot instead of /boot/efi. Both grub and grub-related commands (grub-mkconfig) worked like a charm this way, since the /boot partition was not encrypted.

That is why, as a first step for the manjaro-architect installer, I would suggest you to make /boot as the default EFI partition mountpoint in case of an encrypted setup.

Otherwise, you may look at the archwiki (previous link), in order to design a more comprehensive and robust procedure for encrypted boot partitions on the manjaro-architect

Chrysostomus commented 6 years ago

Okay, it seems I can't get the original code for lvm detection to work. I'm now writing a new function to detect it at the end of mount function. Originally it tested each partition for lvm/Luks when they are mounted. Now it checks after the whole thing if / or /boot are encrypted. This way it is easier to troubleshoot.

I have now written it for / and it seems to work. Now writing it for /boot. After that we need something to generate cryptab in case someone has encrypted /home.

Chrysostomus commented 6 years ago

Okay, boot section is done, moving to the testing phase.

mhham commented 6 years ago

Nice! Let me now if can be of some help

Chrysostomus commented 6 years ago

Well, I'm not yet sure how to implement the encryption of /home. Should it be decrypted at boot time (adding it to cryptab) or at login time with Pam. Or should the user be provided with option to choose from them?

mhham commented 6 years ago

If the computer is single user, decrypting everything at boot time seems reasonable (that is using crypttab).

However, I would like to point out that having a LVM on LUKS setup with all the LVM volumes (/ , /home , swap but not /boot) inside the LUKS container removes the need to decrypt /home separately in crypttab or pam.

Chrysostomus commented 6 years ago

Yes. So does keeping everything in one partition (/) or using btrfs subvolumes on Luks device. But I think some people still keep separate encrypted /home, so I'd like to add support for that at some point.

Ecryptfs is also one possibility, which lets you have encrypted $HOME, but that is hard to implement at installer level.

The cryptab is probably the easiest to implement, so I'll probably go with that.

Chrysostomus commented 6 years ago

Something like this:

For every encrypted partition whose mountpoint starts with /mnt, except /mnt and /mnt/boot, do

This probably best done automatically after fstab creation.

mhham commented 6 years ago

Something like this:

For every encrypted partition whose mountpoint starts with /mnt, except /mnt and /mnt/boot, do

Add entry to cryptab
Amend fstab to point to the right mapper device

This probably best done automatically after fstab creation.

This looks ok !

Also, if the user does not want to type as many passwords as there are encrypted partitions, you may add the possibility to use a key located on the root encrypted partition (cf. here)

Chrysostomus commented 6 years ago

Keyfile support is planned also for avoiding need to input the password twice with grub. Maybe we should add that option to the Luks menu...

mhham commented 6 years ago

Yes, that would be a nice addition to the LUKS menu !

Chrysostomus commented 6 years ago

Okay, with the current git code

So, getting there, but there is still work to be done.

Chrysostomus commented 6 years ago

Okay, this now SHOULD work as of #d2bbb3b . I'll do one more test installation with it...

Chrysostomus commented 6 years ago

But man is that code ugly and redundant... I'll have to clean it up at some point.

Chrysostomus commented 6 years ago

And it still does not work as it should. It now writes reliably the right boot option to /tmp/.luks_dev, and the line that should update /etc/default/grub with it works, but for some reason that whole line did not get triggered.

mhham commented 6 years ago

This looks great! Just an additionnal remark. In case the /boot partition is encrypted or contained in an encrypted root, this means that everything will be decrypted before entering grub. This could be problematic for some situations, like dualbooting on UEFI computers for instance, where users would not want to decrypt the whole manjaro install to access the other OSes.

Creating a separate non encrypted /boot, could be a good solution if the UEFI ESP partition is mounted as /boot/efi. Or mounting the unencrypted ESP as /boot. These two solutions seem to be already accessible with the latest script.

In case the user has an encrypted setup, and mounts ESP on /boot/efi, I would suggest you to pop a warning if there is no separate unencrypted /boot:

"Warning! You have an encrypted setup with an encrypted /boot. In case you want to access your bootloader without a password, consider creating a separate unencrypted /boot partition, or mounting your ESP partition at /boot instead of /boot/efi"

(More generally, having an encrypted /boot seems to be relevant only for highly secure setups which would undergo some serious attacks. An unencrypted boot with an encrypted setup seems sufficient for most privacy related uses.)

PS: I am a beginner at bash, but would be happy to help (just forked the repo). If you have any advice or suggestions to start contributing, please tell me.

Chrysostomus commented 6 years ago

In case the user has an encrypted setup, and mounts ESP on /boot/efi, I would suggest you to pop a warning if there is no separate unencrypted /boot:

Maybe, not sure about that. The installer expects the user to know what they are doing.

PS: I am a beginner at bash, but would be happy to help (just forked the repo). If you have any advice or suggestions to start contributing, please tell me.

Can you figure out why the function install_grub_uefi fails to set the right root right in /etc/default/grub? The function starts at line 383 in util-base.sh and the line 403 should apply the setting.

Chrysostomus commented 6 years ago

Okay, simple LVM on LUKS worked the last time I tested it. I now uploaded the fixes into the unstable repo (version 0.9.3)

mhham commented 6 years ago

Hello again, I was away these last days, sorry I didn't answer.

So it seems that you made things work, great!

In order to keep contributing I would like to ask you a stupid question: how do you test the installer when you change a portion of the code. Do you create an ISO and boot it to a virtual machine every single time?

Chrysostomus commented 6 years ago

Nope, I don't use virtual machines or isos. I have manjaro-architect installed on my main system. I use a separate partition on the same ssd or a USB stick as the installation target. This way I almost never need to download anything when testing, because I automatically use the pacman cache of my main system. I just make some changes and restart the installer. If the changes work, I copy them to the git repo.

Chrysostomus commented 6 years ago

Virtual machines have some advantages too, but I'm too lazy for that. Always use pacman cache if available.

mhham commented 6 years ago

Ok, I justed managed to test an LVM on LUKS install with 0.9.3 version from the unstable repository.

What I did was the following:

  1. UEFI install with an unencrypted ESP mounted on /boot

  2. LVM on LUKS (volume cryptolvm) with swap, root and home volumes

A few remarks:

  1. GRUB_ENABLE_CRYPTODISK=y was added to /etc/default/grub, even if the /boot partition is unencrypted. This is useless, and even overkill, since the user has to enter the encryption password twice.

  2. The GRUB_CMDLINE_LINUX worked fine. I would suggest to add the following GRUB_CMDLINE_LINUX="... root=/dev/mapper/MyVol-root" as in archwiki.

  3. In case a swap partition is used in the LVM on LUKS setup, it could be nice to ask if the user wants to enable hibernate feature. If not, your current script works fine. If so, the following should be added to /etc/default/grub in GRUB_CMDLINE_LINUX="... resume=/dev/mapper/MyVol-swap", and the resume hook should be added to mkinitcpio.conf as in HOOKS="... encrypt lvm2 resume ... filesystems ..."

Chrysostomus commented 6 years ago

Okay. 1 should be fixed. I'll consider 2, even if current system works.

There is no hibernation support yet, but it has been planned. Currently there is the package hibernator to do this post installation. It uses the value from fstab, so it should do this already. We could just call hibernator in a chroot.

mhham commented 6 years ago

Yes, hibernator seems to do the job, though I noticed that it puts the resume hook after filesystems, whereas it is located before on the archwiki.

Not sure this is an issue ...

Chrysostomus commented 6 years ago

It should not matter. What matters is that it is after encrypt and lvm hooks.

Chrysostomus commented 6 years ago

Okay, it should now not trigger if /boot is not on encrypted partition.

0xbilko commented 6 years ago

Is It possible to fix it? Also have problem when trying install manjaro with full encrypted disk ( encrypted /boot ). Some instructions for arch: https://grez911.github.io/cryptoarch.html https://gist.github.com/mjnaderi/28264ce68f87f52f2cabb823a503e673

Chrysostomus commented 6 years ago

Yes. It is possible to fix and next on the to do list. If you are talking about unnecessarily adding the GRUB_ENABLE_CRYPTODISK=you. If you are talking about about giving the password only once with full disk encryption, then it is second on the to do list.

Unless you are talking about something else?

0xbilko commented 6 years ago

Yeap, "cryptsetup luksAddKey" + all from this issue

Chrysostomus commented 6 years ago

GRUB_ENABLE_CRYPTODISK issue should be resolved with the latest git update, but should be tested.

I have now implemented automated keyfile generation on local branch, but I'll test it a bit before merging.

0xbilko commented 6 years ago

Thanks, we w8 it...