How do I get grub-efi-amd64-signed to not automatically overwrite NVRAM on update

I am using refind as my main boot loader. Since it can load kernel images directly, I probably don't even need GRUB much, but keeping it around just in case feels safer just in case. What's annoying me however is that certain upgrades (haven't worked out whether it's to grub, to the kernel, or both) will trigger a change to my UEFI NVRAM, making GRUB the default boot loader.

I've read in various posts that there is an option --no-nvram to the grub installer, which is probably what I want. So my main question here is how do I get that flag passed to the grub installer on upgrades?

Several existing Stack Exchange answers [1, 2, 3] all point to sudo dpkg-reconfigure grub-efi-amd64 as the solution, because it should show me a dialog where I can disable that behavior. Doesn't work for me on focal, though:

$ sudo dpkg-reconfigure grub-efi-amd64
dpkg-query: package 'grub-efi-amd64' is not installed and no information is available
Use dpkg --info (= dpkg-deb --info) to examine archive files.
/usr/sbin/dpkg-reconfigure: grub-efi-amd64 is not installed

$ dpkg -l *grub*
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                  Version                Architecture Description
+++-=====================-======================-============-===============================================================
un  grub                  <none>                 <none>       (no description available)
un  grub-cloud-amd64      <none>                 <none>       (no description available)
ii  grub-common           2.04-1ubuntu26         amd64        GRand Unified Bootloader (common files)
un  grub-coreboot         <none>                 <none>       (no description available)
un  grub-doc              <none>                 <none>       (no description available)
un  grub-efi              <none>                 <none>       (no description available)
un  grub-efi-amd64        <none>                 <none>       (no description available)
ii  grub-efi-amd64-bin    2.04-1ubuntu26         amd64        GRand Unified Bootloader, version 2 (EFI-AMD64 modules)
ii  grub-efi-amd64-signed 1.142.1+2.04-1ubuntu26 amd64        GRand Unified Bootloader, version 2 (EFI-AMD64 version, signed)
un  grub-efi-arm          <none>                 <none>       (no description available)
un  grub-efi-arm64        <none>                 <none>       (no description available)
un  grub-efi-arm64-signed <none>                 <none>       (no description available)
un  grub-efi-ia32         <none>                 <none>       (no description available)
un  grub-efi-ia64         <none>                 <none>       (no description available)
un  grub-emu              <none>                 <none>       (no description available)
ii  grub-gfxpayload-lists 0.7                    amd64        GRUB gfxpayload blacklist
un  grub-ieee1275         <none>                 <none>       (no description available)
un  grub-legacy           <none>                 <none>       (no description available)
un  grub-legacy-doc       <none>                 <none>       (no description available)
un  grub-linuxbios        <none>                 <none>       (no description available)
ii  grub-pc               2.04-1ubuntu26         amd64        GRand Unified Bootloader, version 2 (PC/BIOS version)
ii  grub-pc-bin           2.04-1ubuntu26         amd64        GRand Unified Bootloader, version 2 (PC/BIOS modules)
un  grub-uboot            <none>                 <none>       (no description available)
un  grub-xen              <none>                 <none>       (no description available)
un  grub-yeeloong         <none>                 <none>       (no description available)
un  grub2                 <none>                 <none>       (no description available)
ii  grub2-common          2.04-1ubuntu26         amd64        GRand Unified Bootloader (common files for version 2)

$ sudo dpkg-reconfigure grub-efi-amd64-signed
Installing grub to /boot/efi.
Installing for x86_64-efi platform.
Installation finished. No error reported.

So my package is named differently, and the most likely candidate just does the thing I don't want it to do, without asking any questions.

Looking at /var/lib/dpkg/info/grub-efi-amd64-signed.postinst I find it calls /usr/lib/grub/grub-multi-install --target=$target which in turn contains an invocation _UBUNTU_ALTERNATIVE_ESPS="$RET" grub-install --efi-directory=$mntpoint "$@". So the latter could handle additional flags, but the former doesn't seem to have a hook to provide any.

Is there any reliable way (i.e. likely to work in the next few upgrades as well) to pass --no-nvram there, can I achieve that goal by some other means, or do I have to remove GRUB or accept that it will mess my boot menu every now and then?


I've never used refind so I don't know the possible side effects to my suggestion, caveat emptor, don't blame me if this bricks your system, etc.

Looking at the packages on my Ubuntu 20.04 server, I believe you should be able to delete /boot/grub/x86_64-efi/core.efi. The postinst scripts for grub-efi-amd64, grub-efi-amd64-signed, and shim-signed all share the same logic. If the core.efi file exists, then run /usr/lib/grub/grub-multi-install. Otherwise, the step is skipped.

The comments in the grub-efi-amd64.postinst script do suggest that the core.efi file missing is supposed to tell the script to skip the install step

https://git.launchpad.net/~ubuntu-core-dev/grub/+git/ubuntu/tree/debian/postinst.in?h=focal#n742

# Check /boot/grub to see if we previously installed to an ESP. We don't
# want to trigger the install code just by installing the package,

Only the grub-efi-amd64 package has configuration for the --no-nvram option. grub-efi-amd64-signed and shim-signed do not. I don't know why, but they have different source packages which may explain the different options. The grub-efi-amd64 package stores this option in debconf and uses it to generate the command line when it calls grub-multi-install. As you noted, the script for grub-multi-install appears to pass its parameters directly to grub-install. You might be able to patch the postinst scripts or grub-multi-install to add the --no-nvram argument, but this would probably lead to problems during future updates

These are other debconf settings that are used grub-multi-install. However, I could not get them to skip installation. They might work if they are set before installing the grub packages

echo grub-efi-amd64  grub-efi/install_devices_empty  boolean true | debconf-set-selections
echo grub-efi-amd64  grub-efi/install_devices        multiselect | debconf-set-selections

References

https://unix.stackexchange.com/questions/565615/efi-boot-bootx64-efi-vs-efi-ubuntu-grubx64-efi-vs-boot-grub-x86-64-efi-grub-efi

When grub-install is used, it will first use the grub-mkimage utility to create a GRUB core image: on a UEFI system, this file will be saved at /boot/grub/x86_64-efi/grub.efi and/or .../core.efi before it will be copied to the EFI System Partition and added to the UEFI NVRAM boot settings by grub-install. The copy in /boot/grub/x86_64-efi/*.efi will not be used at all in the boot process

This may be different now, as the output of the command /usr/lib/grub/grub-multi-install -vvv suggests to me these files are generated but are not copied to the ESP. The file used to boot comes from /usr/lib/shim/shimx64.efi.signed

Non-interactive install of grub2 when installing from scratch

I would like to install the grub2 software on an image - but not configure it or install it on the boot sector at all

This may also be different now, as the grub packages have been reworked and the logic may have changed