Quick setup of a proxyDHCP with dnsmasq and PXE boot


How to netboot a device in a few simple steps.


Since we will be relying on PXE, we need to ensure that our booting device has a network card that runs a PXE ROM, i.e it runs a firmware that implements some necessary internet protocols: UDP/IP, DHCP and TFTP.

We then need a DHCP server that is capable of replying to our device with both:

  1. IP address, IP mask, etc
  2. a bootstrap program (the PXE part of things)

Not every router or DHCP server allows configuring (2.) for different reasons. If that is the case we need to setup a proxyDHCP, and for that we will be using dnsmasq.


The dnsmasq service should be running on a machine sharing the network with the booting devices. It may be running in the host itself, in a virtual machine or even from a docker container, as long as it shares the same network as the devices. Two examples are addressed:

  • Ubuntu 18.04 netboot
  • XenServer from iso

In the following examples the dnsmasq service will be running from inside a container and configuration passed by a volume mount. So, in short we need the following Dockerfile:

FROM alpine:latest
RUN apk --no-cache add dnsmasq
WORKDIR /tftpboot
CMD ["dnsmasq", "-d"]

which can be built with:

docker build -f Dockerfile -t proxydhcp .

and run with:

docker run \
  --rm -it \
  --net=host \
  --cap-add=NET_ADMIN \
  -v ${PWD}/dnsmasq.conf:/etc/dnsmasq.conf \
  -v ${PWD}/tftpboot:/tftpboot \

NOTE: don’t run yet, we need to configure tftpboot/ directory, keep reading…

a dnsmasq.conf file with the following content:

pxe-service=x86PC,'Network Boot',pxelinux

NOTE: dhcp-range should be set with the correct network address.

and a directory named tftpboot:

mkdir -p tftpboot/

Ubuntu 18.04 netboot example config

Download Ubuntu 18.04 netboot from here netboot_url, and decompress it into tftpboot/:

cd tftpboot/
wget http://archive.ubuntu.com/ubuntu/dists/bionic-updates/main/installer-amd64/current/images/netboot/netboot.tar.gz
tar xf netboot.tar.gz && rm netboot.tar.gz
cd -

tftpboot/ should look like this:

├── ubuntu-installer/
├── ldlinux.c32 -> ubuntu-installer/amd64/boot-screens/ldlinux.c32
├── pxelinux.0 -> ubuntu-installer/amd64/pxelinux.0
├── pxelinux.cfg -> ubuntu-installer/amd64/pxelinux.cfg
└── version.info

And we should now be able to run our docker container as mentioned above and boot the PXE ROM machine.

XenServer ISO example config

Download XenServer Free from xenserver.org

and then mount bind the iso file:

sudo mkdir -p /mnt/xeniso/
sudo mount -o loop XenServer-7.6.0-install-cd.iso /mnt/xeniso/

Copy mboot.c32, menu.c32 and pxelinux.0 from inside /mnt/xeniso/boot/pxelinux/ to tftpboot/:

cp /mnt/xeniso/boot/pxelinux/* tftpboot/

Create the directories tftpboot/pxelinux.cfg/ and tftpboot/xenserver/

mkdir -p tftpboot/pxelinux.cfg/
mkdir -p tftpboot/xenserver/

and copy all the contents from /mnt/xeniso/boot to tftpboot/xenserver/:

cp /mnt/xeniso/boot/* tftpboot/xenserver/
cp /mnt/xeniso/install.img tftpboot/xenserver/

and create the file tftpboot/pxelinux.cfg/default with content:

default xenserver
label xenserver
kernel mboot.c32
    append /tftpboot/xenserver/xen.gz dom0_max_vcpus=2 dom0_mem=1024M,max:1024M com1=115200,8n1 console=com1,vga ---  /tftpboot/xenserver/vmlinuz xencons=hvc console=hvc0 console=tty0 ---  /tftpboot/xenserver/install.img

Finally expose /mnt/xeniso through http for instance by running:

cd /mnt/xeniso
sudo python3 -m http.server 80

Run the container and boot the PXE device. Follow the installation and instructions and configure installation from http, pointing to the python http server setup above.