Install PXE server on Raspberry Pi 4

And boot Linux systems over the network without installing

Install PXE server on Raspberry Pi 4

Photo by Timo Volz on Unsplash

About the plan

In this short tutorial, I will show how to boot live-cd-type systems over the network. We are going to use a Raspberry PI board as a server. For the operating system, I chose Raspberry Pi OS (early known as Raspbian) which is technically Debian 10 (Buster).

To set up a PXE Server we will need the following dependencies:

  • TFTP

  • dnsmasq

  • NFS

Network boot is possible due to TFTP.

Usually, the TFTP server has the same IP address as the DHCP server, but we will use dnsmasq to configure some kind of relay for our goal. It is called proxy DHCP to be more precise. This way our setup will work in any local network even with grandma's router.

We will set up an NFS (Network File System) server, which will allow computers to access files on the PXE server over the network.

Note: This tutorial assumes you are the root user, if not, please add sudo for all the commands.

Install and configure

The following command will install the required packages on Raspberry OS:

apt install -y dnsmasq pxelinux syslinux-common nfs-kernel-server

Once downloading is complete, stop the dnsmasq service

systemctl stop dnsmasq

PXELINUX

Create a directory where all transferable files will reside

mkdir /srv/tftpboot

Take important boot modules (pxelinux.0, ldlinux.c32, libutil.c32, menu.c32 and vesamenu.c32) and place them into /srv/tftpboot

cp /usr/lib/PXELINUX/pxelinux.0 \
    /usr/lib/syslinux/modules/bios/{ldlinux.c32,libcom32.c32,libutil.c32,menu.c32,poweroff.c32,reboot.c32,vesamenu.c32} \
    /srv/tftpboot/

Create the directory for the PXE configuration file.

Important: this directory must be called pxelinux.cfg

mkdir -p /srv/tftpboot/pxelinux.cfg

Prepare boot menu design

nano /srv/tftpboot/pxelinux.cfg/default

with this content

MENU TITLE Network Boot Menu
UI vesamenu.c32
MENU INCLUDE pxelinux.cfg/pxe.conf

LABEL next
    MENU LABEL Load local bootloader
    MENU DEFAULT
    localboot

# Separator
MENU SEPARATOR

LABEL reboot
    MENU LABEL Reboot
    COM32 pxelinux.cfg/arch/reboot.c32

LABEL poweroff
    MENU LABEL Power Off
    COM32 pxelinux.cfg/arch/poweroff.c32

And styles separately

nano /srv/tftpboot/pxelinux.cfg/pxe.conf
MENU BACKGROUND pxelinux.cfg/logo.png
MENU RESOLUTION 1024 768
NOESCAPE 1
ALLOWOPTIONS 0
PROMPT 0
menu width 32
menu rows 5
MENU MARGIN 0
MENU VSHIFT 10
MENU HSHIFT 46
menu color title                1;37;40    #ffffffff #00000000 std
menu color border               36;40      #c00090f0 #00000000 std
menu color sel                  30;47      #00000000 #ffffffff all
menu color unsel                37;40      #ffffffff #00000000 std

And the background /srv/tftpboot/pxelinux.cfg/logo.png

logo.png

We will add real entries in the Test section.

UEFI version

The setup of PXE boot for UEFI computers is slightly different from the setup supporting the BIOS computers. I will not cover it here, because the topic is very big for one article. In some rare cases, you will only need to find grubx64.efi file and replace pxelinux.0 with grubx64.efi. Take it from the system that matches your client computers, for example, take it from the official Ubuntu 20.04 (Focal) distribution. Then put grubx64.efi into /srv/tftpboot/. But usually, it's not that simple.

dnsmasq

Update the content of /etc/dnsmasq.conf. By default this file full of comments above each option. You can read through and tweak settings to your liking, but I already know what I put into:

mv /etc/dnsmasq.conf /etc/dnsmasq.conf.example
nano /etc/dnsmasq.conf
#Disable DNS Server
port=0

#Enable DHCP logging
log-dhcp

#Respond to PXE request for the specified network;
#Run as DHCP proxy
dhcp-range=192.168.1.0,proxy,255.255.255.0

dhcp-boot=pxelinux.0

#Flag forces "simple and safe" behavior
dhcp-no-override

#Provide network boot option called "Network Boot"
pxe-service=x86PC,"Network Boot", pxelinux

#Turn tftp ON
enable-tftp

#Set tftp root
tftp-root=/srv/tftpboot

Add the following line to the /etc/default/dnsmasq file

DNSMASQ_EXCEPT=lo

NFS

In order to give access to specific files to NFS clients add the following line to the /etc/exports file

/srv/tftpboot 192.168.1.0/24(rw,sync,no_root_squash,no_subtree_check)

And make this change live:

exportfs -a

Test

For tests, we are going to run Kali Linux and custom Buildroot build (long story short, we'll assume that you already have output/images/rootfs.tar.gz)

Kali

Download an ISO image from the official website and transfer it to Raspberry Pi (when I was writing this tutorial the last version was 2021.2 and the ISO name correspondingly kali-linux-2021.2-live-amd64.iso)

scp kali-linux-2021.2-live-amd64.iso pi@192.168.1.11:~

Then extract it to /srv/tftpboot/kali

mkdir -p /srv/tftpboot/kali
mount ~/kali-linux-2021.2-live-amd64.iso /mnt
cp -r /mnt/* /srv/tftpboot/kali

Add an entry to the boot menu

nano /srv/tftpboot/pxelinux.cfg/default
LABEL kali
    MENU vesamenu.c32
    MENU LABEL Kali Linux Live
    KERNEL /kali/live/vmlinuz
    APPEND root=/dev/nfs nfsroot=192.168.1.11:/srv/tftpboot/kali,tcp,v3 ip=dhcp vers=3 rootfstype=ext4 rw --

Buildroot

Do not forget to enable in the kernel configuration

  • CONFIG_IP_PNP_DHCP=y

  • NFS filesystem support (CONFIG_NFS_FS).

  • The root file system on NFS (CONFIG_ROOT_NFS).

Transfer rootfs archive to Raspberry Pi

scp rootfs.tar.gz pi@192.168.1.11:~

Then extract it to /srv/tftpboot/buildroot

mkdir -p /srv/tftpboot/buildroot
tar xvpf ~/rootfs.tar.gz -C /srv/tftpboot/buildroot

Add to the boot menu an entry

nano /srv/tftpboot/pxelinux.cfg/default
LABEL buildroot
    MENU vesamenu.c32
    MENU LABEL Custom Buildroot build
    KERNEL /buildroot/boot/bzImage
    APPEND root=/dev/nfs nfsroot=192.168.1.11:/srv/tftpboot/buildroot,tcp,v3 ip=dhcp vers=3 rootfstype=ext4 rw --

Credits and comparison

There are some great (?) tutorials out there describing the same topic, and of course, this one was compiled with their help.

Why this tutorial is better than

  • TecMint - very descriptive, but here we use Debian's package manager

  • Debian's wiki - focuses more on DHCP configuration, but we also add an NFS server and make a very nice boot menu

  • Red Hat - probably works great on Red Hat Linux, but I like free and open source solutions. So in this tutorial, we configure completely different packages

Conclusion

Network boot is a long story. I've started writing a gitbook about it, so for more information on the topic you can give it a read.

Tags: #UEFI, #PXE, #network boot, #Raspberry Pi