eblot / pybootd

A minimalist bootp/dhcp/pxe and tftp server

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

pybootd support for UEFI-based systems upon PXE boot

lgharda opened this issue · comments

pybootd presently assumes that any PXE request comes from a system with BIOS firmware.

We would like to be able to have pybootd distinguish BIOS PXE boot requests from UEFI PXE boot requests.

Red Hat posted how to determine if a PXE boot comes from a UEFI system. The code snippet below shows the character string to look for in the PXE boot request:

Red Hat published how to make changes to a generic DHCP server responding to PXE requests to distinguish between BIOS and UEFI-based devices.

class "pxeclients" {
match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
next-server 192.168.1.10;
if option architecture-type = 00:07 {
filename "shim.efi";

} else {
filename "pxelinux/pxelinux.0";

https://www.redhat.com/sysadmin/pxe-boot-uefi

If someone could implement this in pybootd, it would be most appreciated. Thanks!

Just checking, what you need is something like:

UEFI-PXE boot

PXEd[pxed] INFO: UUID is 2B88C321:4AAE:EDC2:1BA7:1C697A006F4C for MAC 1C:69:7A:00:6F:4C
PXEd[pxed] INFO: 1C:69:7A:00:6F:4C access is authorized, request will be satisfied
PXEd[pxed] INFO: Selecting bootfile 'shimx64.efi' for architecture 00007
PXEd[pxed] INFO: Client needs its address
PXEd[pxed] INFO: Reply to: 192.168.99.255:68
PXEd[pxed] INFO: Offering lease for MAC 1C:69:7A:00:6F:4C: IP 192.168.99.100
PXEd[pxed] INFO: Moving from state 0 to state 1
PXEd[pxed] INFO: UUID is 2B88C321:4AAE:EDC2:1BA7:1C697A006F4C for MAC 1C:69:7A:00:6F:4C
PXEd[pxed] INFO: 1C:69:7A:00:6F:4C access is authorized, request will be satisfied
PXEd[pxed] INFO: Selecting bootfile 'shimx64.efi' for architecture 00007
PXEd[pxed] INFO: Client needs its address
PXEd[pxed] INFO: Lease for MAC 1C:69:7A:00:6F:4C already defined as IP 192.168.99.100
PXEd[pxed] INFO: Reply to: 192.168.99.255:68
PXEd[pxed] INFO: New lease for MAC 1C:69:7A:00:6F:4C: IP 192.168.99.100
PXEd[tftpd] INFO: Client: 192.168.99.100:1430
PXEd[tftpd] INFO: Resource '/Users/eblot/Downloads/pybootd/shimx64.efi'
PXEd[tftpd] INFO: Sending file '/Users/eblot/Downloads/pybootd/shimx64.efi'
PXEd[tftpd] INFO: File /Users/eblot/Downloads/pybootd/shimx64.efi send in 0.6 s (2.00 MB/s)
PXEd[tftpd] INFO: Client: 192.168.99.100:1431
PXEd[tftpd] INFO: Resource '/Users/eblot/Downloads/pybootd/grubx64.efi'
PXEd[tftpd] INFO: Sending file '/Users/eblot/Downloads/pybootd/grubx64.efi'
PXEd[tftpd] INFO: File /Users/eblot/Downloads/pybootd/grubx64.efi send in 0.5 s (2.01 MB/s)

BIOS-PXE boot (legacy)

PXEd[pxed] INFO: UUID is 2B88C321:4AAE:EDC2:1BA7:1C697A006F4C for MAC 1C:69:7A:00:6F:4C
PXEd[pxed] INFO: 1C:69:7A:00:6F:4C access is authorized, request will be satisfied
PXEd[pxed] INFO: Selecting bootfile 'pxelinux.0' for architecture 00000
PXEd[pxed] INFO: Client needs its address
PXEd[pxed] INFO: Reply to: 192.168.99.255:68
PXEd[pxed] INFO: Offering lease for MAC 1C:69:7A:00:6F:4C: IP 192.168.99.100
PXEd[pxed] INFO: Moving from state 0 to state 1
PXEd[pxed] INFO: UUID is 2B88C321:4AAE:EDC2:1BA7:1C697A006F4C for MAC 1C:69:7A:00:6F:4C
PXEd[pxed] INFO: 1C:69:7A:00:6F:4C access is authorized, request will be satisfied
PXEd[pxed] INFO: Selecting bootfile 'pxelinux.0' for architecture 00000
PXEd[pxed] INFO: Client needs its address
PXEd[pxed] INFO: Lease for MAC 1C:69:7A:00:6F:4C already defined as IP 192.168.99.100
PXEd[pxed] INFO: Reply to: 192.168.99.255:68
PXEd[pxed] INFO: New lease for MAC 1C:69:7A:00:6F:4C: IP 192.168.99.100
PXEd[tftpd] INFO: Client: 192.168.99.100:2070
PXEd[tftpd] INFO: Resource '/Users/eblot/Downloads/pybootd/pxelinux.0'
PXEd[tftpd] INFO: Sending file '/Users/eblot/Downloads/pybootd/pxelinux.0'
PXEd[tftpd] INFO: File /Users/eblot/Downloads/pybootd/pxelinux.0 send in 0.0 s (2.07 MB/s)
PXEd[tftpd] INFO: Client: 192.168.99.100:49152
PXEd[tftpd] INFO: Resource '/Users/eblot/Downloads/pybootd/ldlinux.c32'

Or do you need more changes in addition to the initial boot file?

Emmanuel and Emmanuel, thank you for looking into this. Your assistance is much appreciated.

Yes this looks like what we need. The BIOS action shown is the same as our current PXE usage. I do not yet have a full understanding of all the UEFI requirements. The shimx64.efi and grubx64.efi do correspond with examples shown for secure and non-secure .efi files we need.

It would be helpful to have pybootd.ini parameter values for these.

Current LinMin pybootd.ini relevant setting is --

; BIOS-PXE boot (legacy) currently used
# LinMin uses lpxelinux.0 not pxelinux.0 
boot_file = lpxelinux.0

Suggested settings for both PXE boot options are --

; Both BIOS-PXE boot UEFI-PXE boot
boot_file_bios_pxelinux = lpxelinux.0
boot_file_uefi_secure = shimx64.efi
boot_file_uefi_nonsecure = grubx64.efi

Note we do not support 32bit architecture. The boot_files referenced are based on this excerpt info from -- http://www.rodsbooks.com/linux-uefi/
"If you're booting with Secure Boot enabled, you should set shim.efi, shimx64.efi, or PreLoader.efi (whichever is present) as the boot program, rather than grubx64.efi."

It is possible that we could make the .ini boot_file_{type} parameter changes given pointers to the code location where the current boot_file is used and where the UEFI shimx64.efi and grubx64.efi files are selected to be used.

Additional info regarding LinMin's pybootd revisions are directing the PXE and DHCP IP management to LinMin proprietary modules that use these .ini parameters.

[http]
; # LinMin requires "always_check", enabled by default
;always_check = disable
; # LinMin location is LinMin server IP
location = @LinMinServerIp@
; # LinMin pxe and dhcp IP management are directed LinMin proprietary processes
pxe = /home/LinMin/lib/LSM_BootPxe.php
dhcp = /home/LinMin/lib/LSM_Dhcp.php
; # LinMin returns PXE or DHCP IP to the requesting client for MAC colon all upper case passed in

I iterate our thanks for your help with this.

(eblot: edited for MarkDown syntax)

Do forgive the large print in the comment above it did not show in the pre-post text

I'm not sure how to distinguish secure UEFI from non-secure UEFI boots from the above example.

Meanwhile, please checkout the pxe_rework branch.
Beware the syntax for the .ini file has been modified a bit, see the README.rst file and pybootd.ini sample file.

I assumed the code that resulted in these log entries specified the secure UEFI shimx64.efi followed by the nonsecure UEFI grubx64.efi was showing a secure attempt followed by nosecure success.

PXEd[tftpd] INFO: Resource '/Users/eblot/Downloads/pybootd/shimx64.efi'
PXEd[tftpd] INFO: Sending file '/Users/eblot/Downloads/pybootd/shimx64.efi'
PXEd[tftpd] INFO: File /Users/eblot/Downloads/pybootd/shimx64.efi send in 0.6 s (2.00 MB/s)
PXEd[tftpd] INFO: Client: 192.168.99.100:1431
PXEd[tftpd] INFO: Resource '/Users/eblot/Downloads/pybootd/grubx64.efi'
PXEd[tftpd] INFO: Sending file '/Users/eblot/Downloads/pybootd/grubx64.efi'
PXEd[tftpd] INFO: File /Users/eblot/Downloads/pybootd/grubx64.efi send in 0.5 s (2.01 MB/s)

I will look into the [bootfile] section of the pre_rework branch to see more details on "This section contains one entry for each supported architecture. It defines the name of the initial boot file the client should request, indexed on the architecture it reports, if any."

Excellent! I confirm what is shown in the pre_rework .ini is what we need.

[bootfile]
; BIOS boot file
default = pxelinux.0
00000 = pxelinux.0
; EFI Intel x86_32
00002 = shim.efi
00006 = shim.efi
; EFI Intel x86_64
00007 = shimx64.efi
00008 = shimx64.efi
00009 = shimx64.efi 

Have you run pybootd from this branch and can you confirm that it works w/ your environment?

Note: please use markdown syntax - especially for verbatim blocks - to ease reading, thanks.
Code block: an empty line followed with 4 space indented lines. I've edited the existing comments.

No we have not yet run pybootd from this branch. I will use markdown syntax in my comments from now on. Due to resource constraints it will be some time before we are able to do this. Current research shows the secure vs non-secure servicing is handled in the UEFI menu file with required certificate designation for secure/trusted . Additional research confirms that the new .ini file entries include all common vendor-class-identifier codes that we will need with the flexibility to change modules as needed.

Ok thanks for the update.
Let me know when you get a chance to test it.