The iPXE project is a very popular network boot firmware, the official website is ipxe.org. This post will show you how to build iPXE with buildah. This build is focusing on enabling HTTPS boot protocol for iPXE. Some prebuilt binaries are available from github.

The build_ipxe.sh script

set -e
export container=$(buildah from docker.io/amd64/alpine:3.18)

pcbios_targets=("ipxe.pxe" "ipxe.kpxe" "ipxe.kkpxe" "ipxe.lkrn")

# Initialize the buildtargets string with ipxe.efi
build_targets="bin-x86_64-efi/ipxe.efi "

# Iterate through the pcbios_targets and construct the buildtargets string
for pcbios_target in "${pcbios_targets[@]}"; do
  build_targets+="bin-x86_64-pcbios/$pcbios_target "
done
export build_targets

buildah run $container wget -c https://ipxe.org/_media/certs/ca.crt -O /tmp/ipxe.org.crt

if [ -z $1 ]; then
  embedded_ca=""
  embedded_trust="TRUST=/tmp/ipxe.org.crt"
else
  embedded_ca="CERT=/tmp/$1"
  embedded_trust="TRUST=/tmp/$1,/tmp/ipxe.org.crt"
  buildah copy $container $1 /tmp/$1
fi

buildah config --label maintainer=""github.com/deamen"" $container

buildah config --env build_targets="$build_targets" $container
buildah run $container apk add git gcc make libc-dev perl openssl openssl-dev xz-dev syslinux xorriso coreutils

# DO not use shallow clone, the makefile requires full clone
buildah run $container git clone https://github.com/ipxe/ipxe.git

buildah config --workingdir "/ipxe/src" $container
# Set up build options
buildah copy $container set_up_build_options.sh .
buildah run $container sh set_up_build_options.sh

# build .efi, .pxe, .kpxe, .kkpxe, .lkrn only
# check https://ipxe.org/appnote/buildtargets for details
buildah run $container make -j$(nproc --ignore 1) ${embedded_ca} ${embedded_trust} ${build_targets}

copy_script="copy_artifacts.sh"
cat << 'EOF' >> $copy_script
#!/bin/sh
mnt=$(buildah mount $container)
cp $mnt/$1 ./out/$2
buildah umount $container
EOF
chmod a+x $copy_script
for source_file in ${build_targets}; do
  dest_file=$(echo $source_file | sed 's/.*\///')
  echo "Copying $source_file to out/$dest_file"
  buildah unshare ./$copy_script ipxe/src/$source_file $dest_file
done

rm ./$copy_script
buildah rm $container

This script will build the following binaries and copy them into the out directory:

  • bin-x86_64-efi/ipxe.efi
  • bin-x86_64-pcbios/ipxe.pxe
  • bin-x86_64-pcbios/ipxe.kpxe
  • bin-x86_64-pcbios/ipxe.kkpxe
  • bin-x86_64-pcbios/ipxe.lkrn

Please check the official document for details.

The script accept one argument, which is the path to the certificate file. If no argument is provided, the script will use the certificate from ipxe.org. The certificate is used to verify the HTTPS server certificate when iPXE is booting from HTTPS server. The certificate file can be downloaded from ipxe.org. Build with the following command:

./build_ipxe.sh

If you want to use your own certificate, you can provide the path to the certificate file as the argument to the script. The certificate file will be copied into the container and used to build the iPXE binaries, the certfifcate needs to be in PEM format. Build with the following command:

./build_ipxe.sh my_certificate.pem

Please check the official document for details.

The set_up_build_options.sh script

# Enable NFS support
sed -i 's/#undef\tDOWNLOAD_PROTO_NFS/#define\tDOWNLOAD_PROTO_NFS/' config/general.h

# Enable HTTPS support
sed -i 's/#undef\tDOWNLOAD_PROTO_HTTPS/#define\tDOWNLOAD_PROTO_HTTPS/' config/general.h
##
# Enable Ping support
##
sed -i 's/\/\/#define\ PING_CMD/#define\ PING_CMD/' config/general.h
sed -i 's/\/\/#define\ IPSTAT_CMD/#define\ IPSTAT_CMD/' config/general.h

# Enalbe Reboot command
sed -i 's/\/\/#define\ REBOOT_CMD/#define\ REBOOT_CMD/' config/general.h
# Enable Poweroff command
sed -i 's/\/\/#define\ POWEROFF_CMD/#define\ POWEROFF_CMD/' config/general.h
# Enable Certificate management commands
sed -i 's/\/\/#define\ CERT_CMD/#define\ CERT_CMD/' config/general.h

##
# Disable unwanted command
##
# Infiniband
sed -i 's/#define\ IBMGMT_CMD/#undef\ IBMGMT_CMD/' config/general.h
# Fibre Channel
sed -i 's/#define\ FCMGMT_CMD/#undef\ FCMGMT_CMD/' config/general.h

##
# Disable insecure 802.11 protocols
##
# Disable WEP
sed -i 's/#define\ CRYPTO_80211_WEP/#undef\ CRYPTO_80211_WEP/' config/general.h
# Disable WPA
sed -i 's/#define\ CRYPTO_80211_WPA/#undef\ CRYPTO_80211_WPA/' config/general.h

##
# Disable unwanted SAN boot protocols
##
# Disable AOE
sed -i 's/\/\/#undef\ SANBOOT_PROTO_AOE/#undef\ SANBOOT_PROTO_AOE/' config/general.h
# Disable IB_SRP Infiniband SCSI RDMA protocol
sed -i 's/\/\/#undef\ SANBOOT_PROTO_IB_SRP/#undef\ SANBOOT_PROTO_IB_SRP/' config/general.h
# Disable FCP Fibre Channel protocol
sed -i 's/\/\/#undef\ SANBOOT_PROTO_FCP/#undef\ SANBOOT_PROTO_FCP/' config/general.h

This script is used to enable and remove some features in iPXE. Please check the official document for details.