Encrypted Root and Grub keymap

Hello new to Garuda Linux and first just want to say thanks for making the distro. I have been enjoying my time on it quite a bit.

I really like the encrypted install script for Garuda as well that it uses full encryption thereby hiding your initramfs and kernel. I have installed my /boot/efi partiiton to a usb disk and my nvme drive is just two partitions (swap and root) which are of course both encrypted. This is good to prevent the 'evil maid attack', so if I leave my laptop somewhere I can just remove the usb drive from it and turn it off and there is no grub for them to attack.

It doesn't have the dual mfa that my Sakaki Gentoo install had with an encrypted key as it seems from /etc/cryptab that Garuda root contains the key. If this were encrypted and moved to /boot/efi then you would have your MFA and even with a keylogger you couldn't break in without having both the password and the key, but then again the whole thing is going a bit overboard anyway.

As a side not I noticed that LUKS1 is used which used to be required but I believe Grub now supports LUKS2 or at least I read so on:
https://www.phoronix.com/scan.php?page=news_item&px=GRUB-Boots-LUKS2-Disk-Encrypt

My problem currently is with grub , I have special characters in my encryption key which results me in entering my encryption key incorrectly sometimes when I forget its on US keymap, so since grub handles the first EFI boot loading before the initramfs kicks as that is in the encrypted root partition, I need to sort out GRUB's keymap not initramfs if that makes sense...

I have tried to do the following to change the keymap to UK keymap:

Change grub file on /etc/default/grub from console to:
GRUB_TERMINAL_INPUT="at_keyboard"

Create a grub keyboard layout:
sudo grub-kbdcomp -o /boot/grub/layouts/gb.gkb gb

Add this to grub file /etc/grub.d/40_custom :

insmod keylayouts
keymap $prefix/layouts/gb.gkb

Then update grub based on a forum post I found this command:

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

Then I verified the config generated.

This shows that the at_keyboard is in the grub.cfg so thats good:

λ sudo grep terminal_input /boot/grub/grub.cfg
terminal_input at_keyboard

I can see the keymap is reference as well:

λ sudo grep gkb /boot/grub/grub.cfg
keymap $prefix/layouts/gb.gkb

I can see the keymap exists as well:

λ ls -l /boot/grub/layouts/gb.gkb
.rw-r--r-- 2.6k root 30 Mar 23:35  /boot/grub/layouts/gb.gkb
λ sudo grep layouts /boot/grub/grub.cfg
insmod keylayouts
keymap $prefix/layouts/gb.gkb

Yet my keymap seems to remain US, which isn't a problem really but I like to fix things. Anyone know what I'm doing wrong?

Again amazing work on the distro,looks great and I am using it as my daily driver and the KDE dragonized version as well, which is a change from i3.

Just to be on the same page, which guide have you followed?
Have you used this?

2 Likes

Hi petsam,

Apologies I think I did this the gentoo way, instead of arch way...

Bah stupid mistake apologies I'll try again using the arch wiki, will need to do this later today though busy at work and can't reboot into rescue etc if I mess up !

1 Like

So I made a first attempt here not entirely sure what is going wrong but I followed the arch guide, but grub will leave me in un-branded (no Garuda theme) window and when I select the boot it flashes up text on the screen and disappears.

I can confirm that I am using the UK keymap within the grub shell it just won't boot, so not much help there =)

From holding down the 'space' key to make the error flash continually I can see that it has no 'linux' command, which I assume means these modules weren't built into the efi loader. Not sure what else it could mean.

Here are the steps I have taken:

My early-grub.cfg is as follows:

set root=(memdisk)
set prefix=($root)/

terminal_input at_keyboard
keymap /gb.gkb

cryptomount -u MyDRIVEUUID
set root='cryptouuid/MyDRIVEUUID'
set prefix=/@/boot/grub

configfile grub.cfg
~

And the command I used to make the efi file:
sudo grub-mkimage -c early-grub.cfg -o grubx64.efi -O x86_64-efi -m /boot/grub/layouts/memdisk.tar gzio part_gpt cryptodisk luks gcry_rijndael gcry_rijndael gcry_sha256 btrfs memdisk tar at_keyboard keylayouts configfile

Initially I had set prefix set to:
set prefix=($root)/grub

However this didn't work I would boot enter my key and it would drop me to shell. So I read further and the archwiki links to the debian guide so I read that as well and it refers to specifying the boot directory if you have boot on the root partition which I do.

I have:
root -> nvme0p1 /
swap -> nvme0p2
usb drive -> /boot/efi

So I attempted to use the grub shell and cryptomount my disk which works, and lets me then ls through / which due to btrfs subvolumes results in path:

/@/boot/grub

In the grub shell I manually typed:
configfile /@/boot/grub/grub.cfg

At which point I was put into the grub boot menu unthemed, and when I attempt to select Garuda to boot I just get the flash of errors and back to the menu. This is where I saw the no linux command. I edited the menu item to verify the contents it all looks ok, at least to me.

I fell back down to the shell and if I try to use linux and select the kernel or initrd I get no command errors. However the guide doesn't state to build these (if they can?).

The UUID is correct, to revert I copied my backed up efi file back to /boot/efi/EFI/Garuda/

Then I reboot back in with the US keymap.

The drive UUID is the same one I see when I boot correctly back in with the US keymap except one is refering to HD1,GPT and the other to HD2,GPT, not familiar with how grub reads block devices so not sure if this matters.

OK. You are more than capable for this, so I will only offer just another pair of eyes :wink: , since my cryptic experience is only theoretical and RTFMing.

Have you confirmed the required modules for early-grub image? I notice diskfilter is referred in the guides, but not in your grub-mkimage command.
Check a normal auto generated grub.cfg for modules as

For instance, under your menuentry you should see lines similar to:

insmod diskfilter cryptodisk luks gcry_rijndael gcry_rijndael gcry_sha256 insmod ext2

Another possible (but not sure it matters) is prefix of

to

set prefix=($root)/@/boot/grub

For the theme, if ($root) is properly decrypted, it should read and load the target/normal grub.cfg, which should load required gfxmenu etc.
Confirm /etc/default/grub has not disabled gfxmenu

# Uncomment to disable graphical terminal
#GRUB_TERMINAL_OUTPUT=console

and grub.cfg loads these

set gfxmode=1024x768x32,auto  # whatever
  load_video
  insmod gfxterm
...
terminal_output gfxterm
...
insmod gfxmenu

An incompatible resolution could break gfxmenu.


Do you mean you have successfully booted from grub command-line, using grub commands?

2 Likes

So I have it working now, somewhat frustrating having to reboot so many times but I have a working UK keymap in grub. Though I'll be honest I don't entirely understand the solution, grub is rather esoteric...

I ended up reading the grub.cfg from the default installation and noticed this line:

search --fs-uuid --no-floppy --set=root --hint='cryptouuid/<MY LUKS-UUID>'  <MY ROOT UUID>

So instead of following the arch wiki I decided to be lazy and see if I could just copy my own grub.cfg file since I know it works anyway, and funny enough it works.

Here is what I have done in case anyone else wants to try, just note that I have a seperate efi boot disk as /dev/sdXy, but other than that I followed the standard Garuda install:

Verified my locales with:

locale --all-locales | grep -i gb

Created the keymap for grub:

cd /boot/grub/layouts
sudo grub-kbdcomp -o /boot/grub/layouts/gb.gkb gb

Then I created the memdisk tarball that grub will use later:

sudo tar cf memdisk.tar gb.gkb

I then inspected vanilla grub.cfg generated by Garuda at /boot/grub/grub.cfg during installation this led me to note the following modules that were being used prior to mounting my encrypted luks1 partition by searching for the first instance of cryptomount which looked like the following:

if [ x$feature_default_font_path = xy ] ; then
font=unicode
else
insmod part_gpt
insmod cryptodisk
insmod luks
insmod gcry_rijndael
insmod gcry_rijndael
insmod gcry_sha256
insmod btrfs
cryptomount -u <LUKS1 UUID>
set root='cryptouuid/<LUKS1 UUID>'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint='cryptouuid/<LUKS1 UUID>'  <ROOT BTRFS UUID>
else

Which tells me I need the following modules:

part_gpt,cryptodisk,luks,gcry_rijndael,gcry_rijndael,gcry_sha256,btrfs

If you look at the arch wiki guide here. Then you will see different modules like diskfilter (which is for RAID) etc, so if you have diverged from standard install then you may need additional modules and they might be built into your existing efi boot file, there is a module list here.

Then I created the file /boot/grub/early-grub.cfg

set root=(memdisk)
set prefix=($root)/

terminal_input at_keyboard
keymap /gb.gkb

cryptomount -u <LUKS1 parition with root fs>
search --fs-uuid --no-floppy --set=root --hint='cryptouuid/<LUKS1 parition with root fs>'  <UUID that points to the btrfs parition that contains root>
set prefix=/@/boot/grub

configfile grub.cfg

If you compare this and the grub.cfg file generated by grub you will see that I copied the search command from it, this was because trying to get the root and prefix set with the subvolumes and btrfs proved rather difficult, it does mean I need to add search to my grub efi, but I can live with that.

My understanding is that this early configuration file will do the following:

  • Set the root and prefix to memdisk tarball
  • Unzip and load the keyboard map
  • Then you get 1 attempt to enter your encryption key correctly
  • If that is correct the early config file calls the grub generated file which will progress with the boot process as root is now unencrypted and the themed grub will now load and allow you to select a boot menu item

More information on grub variables can be found here.

Before we run the following command we need to backup up our existing grubx64.efi file. This is located at /boot/efi/EFI/Garuda/ with filename grubx64.efi.

I backup this via the following:

cp -v grubx64.efi{,.bak}

Then I backup my entire efi directory with tar to a seperate location:

sudo tar czvf efi-backup.tar.gz /boot/efi/EFI/

If the following efi we generate fails then all you need to do is copy the grubx64.efi.bak back to grubx64.efi to revert to your previous boot settings.

We now need to generate the efi file that will use this configuration via the following command:

grub-mkimage -c /boot/grub/early-grub.cfg -o grubx64.efi -O x86_64-efi -m /boot/grub/layouts/memdisk.tar gzio part_gpt cryptodisk luks gcry_rijndael gcry_rijndael gcry_sha256 btrfs memdisk tar at_keyboard keylayouts configfile search echo

Now I added a few extra modules here those being search and echo, as I use the search command in early-grub.cfg as seen earlier. echo is not needed but I failed to get this to work quite a bit and it can be very helpful to perform commands such as:

echo $root
echo $prefix

To see what grub had for values for those variables at the point of failure.

Now if you are using the default garuda install then you should already have this efi file in your efi boot parameters you can verify this with:

efibootmgr -v

I get the following result (snipped long stuff down with ... for readability):

BootCurrent: 0001
Timeout: 0 seconds
BootOrder: 0001,2001,2002,2003
Boot0000* EFI USB Device (SanDisk)      ...
Boot0001* garuda        HD(1,MBR,...)/File(\EFI\garuda\grubx64.efi)
Boot2001* EFI USB Device        RC
Boot2002* EFI DVD/CDROM RC
Boot2003* EFI Network   RC

You can see the specific reference the file and its location so all is good.

I probably need to make a pacman hook to automatically regenerate my grubx64.efi with the grub-mkimage command, but that is a task for another day.

5 Likes

Blockquote
OK. You are more than capable for this, so I will only offer just another pair of eyes :wink:

Thanks, very nice to hear. I have been a linux lurker for years, and I haven’t ever really come on to a forum or written anything, so was very nice to hear! Thanks

1 Like

There is not much to say, if any. You've said it all! :laughing:

We are happy to have you here!

3 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.