Secure Boot with rEFInd

[quote="physkets, post:56, topic:24526, full:true"]Atutomating the procedure to the extent of feeding the keys into the firmware is going to be nearly impossible, because every firmware is different, also It will depend upon if one is using rEFInd or grub or... [/quote]And -according to the screenshots I see on Rod's page- shim makes for an "unified" UI you can assume everybody to have.

[quote="physkets, post:72, topic:24526, full:true"]Okay, now I'm confused. Read this article: Supporting third-party keys in a Secure Boot world

It seems to suggest, that to have functional Secure Boot (with our own keys), it isn't just enough to sign the refind_x64.efi, but also the kernel image, as well as any kernel modules that may be loaded separately.[/quote]https://mjg59.dreamwidth.org/9844.html
http://lkml.org/lkml/2013/2/25/438

It should be controlled by module.sig_enforce kernel parameter and MODULE_SIG_FORCE config flag.

Hey, guys, I was successful, and am currently 'SecureBooted' onto my machine, with my own keys in place. I primarily followed Rod Smith's guide. The steps are as follows:

First, generate your keys and certificates. You can run the following script for that purpose:

#!/bin/bash
# Copyright (c) 2015 by Roderick W. Smith
# Licensed under the terms of the GPL v3

echo -n "Enter a Common Name to embed in the keys: "
read NAME

openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME PK/" -keyout PK.key \
        -out PK.crt -days 3650 -nodes -sha256
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME KEK/" -keyout KEK.key \
        -out KEK.crt -days 3650 -nodes -sha256
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME DB/" -keyout DB.key \
        -out DB.crt -days 3650 -nodes -sha256
openssl x509 -in PK.crt -out PK.cer -outform DER
openssl x509 -in KEK.crt -out KEK.cer -outform DER
openssl x509 -in DB.crt -out DB.cer -outform DER

GUID=`python -c 'import uuid; print(str(uuid.uuid1()))'`
echo $GUID > myGUID.txt

cert-to-efi-sig-list -g $GUID PK.crt PK.esl
cert-to-efi-sig-list -g $GUID KEK.crt KEK.esl
cert-to-efi-sig-list -g $GUID DB.crt DB.esl
rm -f noPK.esl
touch noPK.esl

sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
                  -k PK.key -c PK.crt PK PK.esl PK.auth
sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
                  -k PK.key -c PK.crt PK noPK.esl noPK.auth
sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
                  -k PK.key -c PK.crt KEK KEK.esl KEK.auth
sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
                  -k KEK.key -c KEK.crt db DB.esl DB.auth

chmod 0600 *.key

echo ""
echo ""
echo "For use with KeyTool, copy the *.auth and *.esl files to a FAT USB"
echo "flash drive or to your EFI System Partition (ESP)."
echo "For use with most UEFIs' built-in key managers, copy the *.cer files."
echo ""

Store the .key files in a safe place. The .cer or .auth files are what your UEFI will take (mine only accepted the auth ones, but different implementations might take different certs). Copy them onto your ESP (/boot).

You can pull the keys into your UEFI, and if you have installed the efitools pacakge you can check using the command: efi-readvar. One could've used the efi-updatevar command to push certs into the UEFI, but I didn't try that, and even if it works, I don't think Manjaro should automate that part, because it will be bad if we accidentally bork someone's UEFI.

Now, install the sbsigntools package and sign the following files:

  1. /boot/EFI/boot/bootx64.efi
  2. /boot/EFI/refind/refind_x64.efi
  3. The vmlinuz files

The vmlinuz files may be signed as follows, after you cd into their folder:

sudo sbsign --key DB.key --cert DB.crt --output vmlinuz_signed vmlinuz

But for the other two, the signed files should have the same name as the current ones. So first create their backups, and then sign them. I did so without specifying an output name and renamed the resulting files to the original names, but I'm guessing it should also be possible to specify the same fileneame in the --output argument.

Now, finally you can re-enable SecureBoot.

@Chrysostomus So do you think the key generation part of this can be added into Architect? If a standard place for the keys, say /etc/keys/ is used, one could also think of automating the signing after every update of rEFInd and the kernels. But how exactly can that be implemented?

2 Likes

https://wiki.archlinux.org/index.php/Secure_Boot#Signing_kernel_with_pacman_hook or sbupdate-git from AUR.

1 Like

But is that a purely systemd thing? Asking because it looks like a systemd unit file.

Pacman hooks are not systemd specific, not sure about that aur package.

Oh! Cool; I will add that, and report back if anyting goes wrong with the next update.

EDIT: Although, one issue is that I curently store the keys in an ecryptfs encrypted folder, so I guess I'll have to either unlock it each time a kernel update happens, or store it outside.

Okay, now say we were to use pacman hooks, we also have to account for the fact that out kernels have different names, and that they may keep changing. In Arch, they just need:

Exec = /usr/bin/sbsign --key db.key --cert db.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux

How do we do this?

With a for loop,

I spent some time on the Arch IRC talking about SecureBoot, and realised that in the current implementation, we loose all the benefits of SecureBoot.

This is due to the initramfs not requiring a signature, and the fact that it is exposed in /boot. Can you guys think of any way around it?

One suggestion was to build the initramfs into the kernel, but that is not practical for us, as it will make the file too big. Any other ideas?

Hmm... One can always encrypt /boot, but that requires manual boot stanzas with refind. Really, only grub handles both automatic boot entry creation and encrypted /boot. It is feasible to script creation of manual boot stanzas for refind, but that doesn't handle kernel updates...

But yes, many solutions that make secure boot work with linux also make secure boot useless.

1 Like

One advantage I see to using manual boot stanzas is that we can then get the right Manjaro icon for the boot selection.

Can you give me a reference to using manual boot stanzas with an encrypted /boot ?

I can.

menuentry Manjaro {
    icon /EFI/BOOT/refind/icons/os_manjaro.png
    loader vmlinuz-linux
    initrd initramfs-linux.img
    options "rw cryptdevice=UUID=INSERT_UUID_HERE:cryptroot root=/dev/mapper    /cryptroot rootflags=subvol=@"
}

This would be with encryption and btrfs subvolumes, but the rootflags part can be used for other stuff too.

I think we should stop with this paranoia.
I mean, I'd bet you are thinking to the samsung ■■■■■ bug, that was just a sub-product of the early days of the new efivar filesystem (plus assumptions made over Windows behavior rather than spec itself, but that's another matter).

Aside of this, anyway, I'm not really sure that's really "important". Touching keys from live OS requires authenticating with the -already trusted/enrolled in the first place- private keys.
So, the only possible use-case in a linux distro I see.. Would be a user wanting to authorize 3rd parties binaries or change from (say) Manjaro root certificate to his own?

EDIT: ok, I just realized that if you are booting the system in Setup Mode (because, say, you just cleared the key db) this requires no special certificate in the first place to add PK and all.
This could make for some 'easily manageable' system, but I think that if you are not a power user recommending to ditch microsoft key is bad (since many Option ROMs are signed with that, and you'd have to extract them from bios image, then enroll their hashes individually to have a perfectly secure and working pc)

The assumption we should target imo, should be the user never having touched it in the first place.
Hell, not even have entered the bios.
(then, better if we do one step at time I guess :p)

Well, 'convenience' in this case seems mutually exclusive with 'hardened' security.

The best solution I could think for you, would be the signing script having default folder customizable (with default value /etc/keys/ ofc).

For the records, ubuntu seems to be using /etc/secureboot. What's canon?

vmlinuz-${_basekernel}-${CARCH}" (that's what every PKGBUILD uses to copy kernel in /boot)
Don't know where the difficulty would be.

Sign it too?
Ok that's looks impossible for the moment.

Your embed-the-initrd idea (together with grub detached signatures) seems doable then.
But that requires keys to "secure initramfs hash" someway.
And thus it would only be possible by a good-willed enough power user.

Matthew didn't go ■■■■■■■ on this though.. so I guess for as much important it shouldn't be really a catastrophe then?

At least we'd still have gained noob-proof installing of manjaro.

?
I'm not sure why a file x+y big, would create any problem compared to files x and y separated.
Unless... we are talking about shipping an "universal" initramfs for either of the two aforementioned solutions?
...
God, that might do it perhaps.

But I guess we'd have to evaluate if the benefits of the (honestly) slim actual security benefit are bigger than (I dunno, just supposing) the downsides of having to boot ~20MB more stuff.


By the way, I'll remember again Secure Boot isn't about impeding to touch /boot (which nevertheless, even in your encrypted scenario, would still be accessible from a hypthetical rouge root application from live system then)

In my experience booting extra 20Mb is not problematic at boot time. More annoying is the extra time used building the initramfs.

Of course, some systems have really small esp (windows seems to like that), and 20Mb might actually make a difference on a multiboot system with small esp.

Anyway, it seems that this might be a lot of trouble for little benefit, especially since the solution would not be even beginner friendly anyway.

Afaik arch is already building everytime fallback initramfs with everything, so if any building only it should reduce compilation time.

Then W7 made me a 100MB partition, and that should be enough for more or less 3 kernels, along with windows.

Last.. I'm not sure what's not friendly there?
If any.. that should be well agreed with phil and everybody else in manjaro team (I guess for the moment we can skip it?)

No support for install media booting with secure boot on.

?
Is the install disk using a different bootloader or kernel than the installed system?

I don't package the kernels, so can't be doing that part. Also, for support on live iso would probably need co-operation of @artoo, which is not likely. At the very least it would require that someone would send a very complete pull request, and would maintain that part of buildiso. I don't know the code well enough and don't have enough time to maintain it.

So, I can do solutions that involve the installer, but for kernel stuff you need @philm and for live iso stuff @artoo.

This probably the reason @artoo kept telling people that he won't do it, even when nobody was asking him. He realized that the reasonable solutions would involve the tools that he maintains.

He doesn't want to spend his own time implementing stuff.
Which is a thing.

And the whole thread was exactly about implementing this stuff, where if any his (and/or others) "most effort" would have been pressing the 'push' button (or say I don't like this or that I mean)

First you get up some kind of satisfactory off-tree patches, only then you think to incorporating them.
It's still kind of early to ping everybody.

Hi guys, I want to share some useful pacman hooks to keep kernels and rEFInd signed after installation and updates. New-generated initramfs images are copied to "manjaro" dir on ESP. These things have really eased the maintenance on my particular installation and I finally got rid of GRUB.
The samples below assumes that your own keys and certificates (db.key, db.crt) location is /etc/efikeys, your ESP partition is mounted to /boot/efi and its size is at least 300 Mb.

  1. This hook copies intel-ucode image to manjaro dir on ESP each time intel-ucode package is updated (necessary when root partition is encrypted and kernel can't see initramfs images)
    intel-ucode.hook:
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = intel-ucode

[Action]
Description = Copying intel-ucode to manjaro dir
When = PostTransaction
Exec = /usr/bin/cp /boot/intel-ucode.img /boot/efi/EFI/manjaro/
  1. Similar to the above, just the same but for the main initrd image
    96-refind-secureboot-linux414-initrd.hook:
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = linux414

[Action]
Description = Copying linux414 initramfs to manjaro dir
When = PostTransaction
Exec = /usr/bin/cp /boot/initramfs-4.14-x86_64.img /boot/efi/EFI/manjaro/initramfs-4.14-x86_64.img
  1. Signes kernel, places it to manjaro dir on ESP (due to encryption, adjust to your needs)
    96-refind-secureboot-linux414.hook:
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = linux414

[Action]
Description = Signing linux414 kernel for SecureBoot
When = PostTransaction
Exec = /usr/bin/sbsign --key /etc/efikeys/db.key --cert /etc/efikeys/db.crt --output /boot/efi/EFI/manjaro/vmlinuz-4.14-x86_64 /boot/vmlinuz-4.14-x86_64
Depends = sbsigntools
  1. This hook simply re-installs refind binaries and configs after the update of refind-efi package
    refind-install.hook:
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = refind-efi

[Action]
Description = Updating rEFInd on ESP
When = PostTransaction
Exec = /usr/bin/refind-install --yes
  1. This hook signs refind ext4 efi driver with your key after installation or update of refind-efi package (for those who don't use encryption of root partition)
    refind-sign-ext4.hook:
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = refind-efi

[Action]
Description = Updating rEFInd on ESP
When = PostTransaction
Exec = /usr/bin/sbsign --key /etc/efikeys/db.key --cert /etc/efikeys/db.crt --output /boot/efi/EFI/refind/drivers_x64/ext4_x64.efi /boot/efi/EFI/refind/drivers_x64/ext4_x64.efi
Depends = sbsigntools
  1. This hook signs refind binary with your key after installation or update of refind-efi package
    refind-sign.hook:
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = refind-efi

[Action]
Description = Updating rEFInd on ESP
When = PostTransaction
Exec = /usr/bin/sbsign --key /etc/efikeys/db.key --cert /etc/efikeys/db.crt --output /boot/efi/EFI/refind/refind_x64.efi /boot/efi/EFI/refind/refind_x64.efi
Depends = sbsigntools

Of course these must be slightly edited to suit one's need, for instance, one would not need to have kernels and initramfs on ESP partition if he-or-she does not use LUKS for boot partition and so on.

And finally an exaple of kernel parameters in refind-linux.conf:

"Boot with optimized options" "ro quiet cryptdevice=UUID=350a09b6-89b9:luks-350a09b6-89b9:allow-discards root=/dev/mapper/luks-350a09b6-89b9 rootfstype=ext4 resume=/dev/mapper/luks-350a09b6-89b9 resume_offset=32958464.. add_efi_memmap initrd=/EFI/manjaro/intel-ucode.img initrd=/EFI/manjaro/initramfs-%v.img"

WARNING: do not use /crypto_keyfile.bin with direct efistub booting from ESP, delete it from FILES section in mkinicpio.conf and reinstall your kernel(s) with necessary pacman hooks described above. Otherwise anyone will be able extract keyfile from initramfs in order to use it for access to your data.

Also sorry for necroposting, but this thread needed some examples without using AUR's sbupdate, etc.

EDIT: Digging into this finally let me move my Manjaro installation to LVM on LUKS (v2) without making unencrypted boot partition, so now I have only sda1 for /boot/efi and sda2 for LVM inside LUKS.

2 Likes

Forum kindly sponsored by