PXE secure network booting

Ubuntu Support Template

Ubuntu Version: 26.04
Desktop Environment (if applicable): N/A

Problem Description: Setting up a PXE secure server. I am using isc-DHCP server, tftpd-hpa server, Apache2 and currently using Grub2.

I have managed to get the system working to the point that it provides an ISO for the client to load, but I get the dreaded warning that the files are not signed. I installed the shim-signed package and followed advice to copy the signed EFI files across to the locations of the original EFI files. Now when I try to boot the client, I am getting the message that the NBP file has downloaded, then the client jumps back to the boot selection screen. Looking at a TCPdump, the client successfully downloads grubnetx64.efi (this is the signed version, but renamed), then it ceases any further downloads and reverts to the boot selection screen as previously mentioned.

It appears that the bootloader is either damaged, incorrect, or the client doesn’t work with it.

Further information, the server has a static IP on its ethernet interface and the client is using DHCP to get its address from the server. The Client is a Lenovo X1 Extreme 20TJS1UG00 laptop. I cannot determine which UEFI version it is using, as Lenovo seem to use their own internal versioning numbers, but the FW is N2VET45W (1.30) with controller version N2VHT22W (1.11).

Sorry, forgot to add that turning off secure boot is not an option unfortunately.

I have a Lenovo. It’s not as bad as you — firmware updates require me to turn off Secure Boot temporarily, but I can turn it on after the firmware updates have completed.

It might be an idea to go into the BIOS and reset the certificates back to default. Then, run the firmware updates if any. After that, register your new MOKs if you have any.

I don’t know if that will help, but it’s worth trying.

(emphasis added)

I think that’s your problem. Since you’ve renamed the file it cannot be found to verify/run it.

So I have modified my dhcp.conf to point directly to shimx64.efi.signed and the first stage booloader now works, so thanks to Peter for that. Where it gets weird is that it then tries to download revocations.efi and grubx64.efi and does this repeatedly until the RAMdisk is full!

From reading the github for shim, it appears that the revocations.efi is a known annoyance but shouldn’t cause any problems except for a warning message. I copied the distribution grubx64.efi to the root of the tftp directory and the client then booted as far as the grub console, without loading any more files.

I had to video the clients screen to catch a very fleeting set of messages:

Unable to fetch TFTP image:TFTP Error

Fetching Netboot Image amd64/grubx64.efi

error: disk ‘tftp,192.168.10.10’ not found.

error: no such device /.disk/info.

error: no such device /.disk/mini-info.

amd64/ is the directory holding all of the 64 bit boot files; 192.168.10.10 is my server’s IP.

Does the 1st error message imply that net and/ or tftp aren’t loaded with grubx64.efi?

So it seems this is a known issue:

Secure boot issue with Grub2

Whilst solving it for a local or USB boot is mentioned, solving it for netboot is not so easy; note also that the article references Debian, so the paths mentioned will be incorrect. Does this imply that the grubx64.efi is unique to each distribution?

Calling it a “known issue” is somewhat misleading, because it’s caused by a misconfiguration.

Maybe have a look here:

Given that the linked page is the one I was using to configure my system, I cannot see what you were trying to highlight; please could you identify what part of that wiki article addresses te issue I am encountering. My aplogies if I am overlooking something obvious.

Sorry, I wasn’t aware. But, since you did manage to rename a file that shouldn’t have been, you might want to double check where else you could have strayed from that path.

This part of the Wiki indicates what the problem may be:

“Once the system continues booting to GRUB; the GRUB process loads any required configuration (usually loading configuration from the ESP (EFI System Partition), pointing to another configuration file on the root or boot partition), which will point it to the kernel image to load.”

Given that the EFI partition isn’t available to the client, I believe this is where things are going wrong. That also reflects what the article I linked to says. The Wiki doesn’t cover netboot and that is where my problem lies.

The 1st stage bootloader never requests the grub.cfg from the server, but it clearly has some kind of config file as it is attempting to load local files. Again, this is what the article says.

Well I located this article,

PXE withe UEFI

and it seems extremely experienced people are having just as much difficulty with this! Thankfully he created a repo with an image of a fully working setup. Off to download it now.

1 Like

And I just happened upon this:

Maybe it’s a little more up-to-date.

Thanks Peter, I shall give that a try.

That link is for netbooting without a secure boot option; I have no problems building a server that netboots clients via PXE for BIOS and UEFI targets. What I cannot get working is secure boot.

CtrlF → “secure boot” :wink:

Oh it is mentioned, but it isn’t 100% correct; secure boot requires a different boot process, so whilst the images may be signed, it’s the process of getting them to the client that causes the issues. The secure bootloader is hardcoded to read a local image, as the article I referred to earlier states.

Whilst I appreciate the help, if you haven’t successfully built a server that serves a secure PXE bootloader and then an OS image that the client accepts, you probably are not going to be able to help.

Maybe that’s because it’s what’s actually required? You are talking about that ramdisk image, aren’t you? The way I understand it – not having done this in a long time – is that you download the bootstrap initrd into RAM, and then chroot into it, so to speak, hence the ./whatever/path.

Have you actually followed that guide and it still doesn’t work? Or, you simply failed to set some envrionment variable, because that script, I seem to remember, checked for some var and only in some circumstances would it try to use said path.

if [ -z "$prefix" -o ! -e "$prefix" ]; then
        if ! search --file --set=root /.disk/info; then
                search --file --set=root /.disk/mini-info
        set prefix=($root)/boot/grub

It also appears to me that those errors might just be failures of search --file – maybe there is no --quiet or it’s missing by oversight – but that’s GRUB shell, so I don’t know. The way I see it, you should end up with prefix='/boot/grub', because nothing actually sets $root, which may be the intended outcome.

So the linked procedure does have 1 significant error, but skipping over that part wasn’t a big problem. It actually got my client booted, although it couldn’t download an image from the web, so I need to fix that. One thing that the procedure does do is rename the 2 files that I renamed when trying an earlier procedure as part of the process of extracting them from the .deb installer files. Thanks for the pointer, that article seems to be one of the few that atually works!

Mind sharing what that error is? You can also help improve the documentation by contributing changes; see the little pencil icon at the top.

Well, what can I say, I did get it working on a UEFI/SecureBoot VM, but that HowTo is really not quite how I did it; seems to be missing some steps.

Apart from the boilerplate setup of the DHCP and TFTP server, you can skip all the other steps and just unpack the ./amd64 directory inside resolute-netboot-amd64.tar.gz directly to /srv/tftp. There’s a grub.cfg already in there, which may need adjusting:

menuentry "Install Ubuntu Server" {
        set gfxpayload=keep
        linux   linux ramdisk_size=4G iso-url=http://Myhost.localdomain/resolute-live-server-amd64.iso ip=dhcp cloud-config-url=/dev/null ---
        initrd  initrd
}

That is the only content; I only adjusted the iso-url to not download from upstream every time, and cloud-config-url=/dev/null.

Update

In my first attempt I totally missed that SB might be disabled, so I double-checked and it was indeed disabled. But now I have the server installer running and mokutil --sb says enabled. Interestingly I now needed to set ramdisk_size=4G to not run into no space left. I don’t know why it worked the first time around, without even specifying that parameter.

1 Like