Raspberry Pi PXE Server Rebuild

Posted by Brahm Lower on Mon 12 February 2018

Table of Contents


Since learning about Linux back in high school, my love for "just having servers" has been ever-present. Even when it's easier to spin up new VMs on Digital Ocean or AWS, I prefer having the hardware locally. This mentality naturally leads one to the world of home-labs, which I've been slowly building, maintaining and expanding since about 2014. It's safe to say that over the years, I've installed various Linux distributions more times than I can count, which I has left a bit of a sour aftertaste for the process of preparing liveboot/install media.

Every time I've had to rebuild a physical server, the process always seems to be muddled from the start. Finding the latest ISOs, a spare flash drive and getting everything written to it to be bootable was a process that was too infrequent to become fluid and familiar, yet too common to be tolerable. At the time, ARSC had a PXE boot system set up, and I'd done some work on it- adding a few updated distributions and other odds and ends. Being relatively comfortable with the technology, I decided to set up a PXE server for my homelab. I opted to get everything set up on a Raspberry Pi- the idea being that I should be able to bootstrap my whole homelab with just the pi.

The process of setting up the PXE server wasn't as smooth as I expected, but I eventually got it working. With the Raspberry Pi rarely needing any attention, it sat largely unchanged for several years. That is, until I remembered it existed again and that it likely needed updates (few years of unpatched CVEs never killed anyone right?). Due to a few configuration blunders I made during its initial setup, the updates essentially caused it to start chewing up files on the filesystem, leaving large parts of the PXE service unusable, prompting this server rebuild project.

Baking the Pi

For starters, I needed to rebuild the Raspberry Pi. There's really no getting around dealing with physical media here, but this should be a one-time deal. This is just a typical raspberry pi setup, though I am enabling the SSH service by creating the file ssh on the boot partition (this seems new since I last did a pi setup).

  1. Download Raspbian
  2. Write image to SD card
  3. Enable SSH
$ https://downloads.raspberrypi.org/raspbian_lite_latest
$ unzip raspbian_lite_latest
$ dd if=2017-11-29-raspbian-stretch-lite.img of=/dev/rdisk1 bs=1
$ touch /Volume/boot/ssh

TFTP + Syslinux = PXE Server

My favorite part of this whole project is that a "pxe server" isn't really any one technical piece you can point at and say "that is the pxe server". It's simply several technologies glued together. This seemed very unusual to me back in the day, and ultimately made it much more difficult to wrap my head around how everything worked together. Existing guides seemed to vary in quality and methodology as well, which gave no clear indicator of how "to just set up a pxe server". It's for this reason I felt obligated to document my adventure here- especially since this second time around has been a very smooth process.

To make this super clear and simple, I'm going to approach this 3 parts: preparing the TFTP server, preparing the syslinux resources, and preparing the pxelinux.cfg boot menu.

TFTP Preparation

This is super straightforward. Unless you feel compelled to dig into the configurables, you can just install and forget about the TFTP service.

$ sudo apt-get update
$ sudo apt-get install tftpd-hpa
$ sudo systemctl is-active tftpd-hpa

Cool beans- that's all set to go. This will (or should) create the directory /srv/tftp/, which is where we'll be storing our PXE resources.

Syslinux and Pxelinux

Depending on your distribution, you might need to install some variant of syslinux, syslinux-common or pxelinux. For Raspbian Stretch, I ran the following:

sudo apt-get install syslinux-common pxelinux

"Great Brahm, that's what you had to install, but WHY did you need to install these particular packages?" - The ever critical inner monologue

I find myself asking this sort of question a lot while reading other how-to posts, especially when I was first learning to make a PXE server. Different distributions have different packages, with varying package contents, which means it's better to know what to look for than to see what worked for someone else. Thus the question "why these particular packages".

Lets look at the syslinux-common package first, or rather, the list of files it gives us. There's a fair amount there, but notably it's providing c32 files like menu, vesamenu and memdisk which are needed for building and running the pre-boot environment. In my case (using Debian Stretch), these files are located at /usr/lib/syslinux/

The pxelinux package gives us only a few resources in comparison. What we really care about here is the pxelinux.0 file. This is the first file to be requested and executed by the netbooting client. This will in turn bootstrap the rest of the preboot execution environment. In my case (using Debian Stretch), this file is located at /usr/lib/PXELINUX/pgelinux.0.

Our goal here is to make these files available via the TFTP server so we'll just copy them all over to the root of the FTFP directory. In my case, I'm really only netbooting machines that have support for BIOS, so I can safely ignore considerations for efi.

$ sudo cp /usr/lib/syslinux/modules/bios/* /srv/tftp/
$ sudo cp /usr/lib/syslinux/memdisk /srv/tftp/
$ sudo cp /usr/lib/PXELINUX/pxelinux.0 /srv/tftp/

The pxelinux.cfg Menu!

Now for the fun part! The pxeboot process will try to find a file to describe a menu to display. There are some pretty cool details here, but they're outside the scope of this post.

Create the file /srv/tftp/pxelinux.cfg/default (making the directory too). The syslinux wiki generally has good documentation about the syntax and keywords accepted by the menu. At the time of this writing the site appears to be down.

DHCP Options 66 and 67

Lastly, DHCP need to be configured to provide DHCP options 66 and 67, the combination of which essentially tell clients which server to go to for PXE resources. More specifically:

Options 66: The host serving PXE resources via TFTP Options 67: The file to request from the TFTP (typically "pxelinux.0")

Setting these options doesn't appear to be supported by most end-user wifi routers, so you may need to host your own DHCP server or used a more feature rich appliance.


This has been a brief rundown of how to build a PXE server. Some details are pretty light, but I plan on coming back to fill in some of the gaps another day (when it's not 12am and when the syslinux site is actually responding).