manski's blog

PXE Server on Existing Network (DHCP Proxy) with Ubuntu

There are a lot of articles out there that explain how to run a PXE server. However, I couldn’t find a single one that contained all the information to setup a PXE server:

  • on Ubuntu
  • without replacing the network’s existing DHCP server (e.g. provided by a hardware router)

So, with article I’m trying to fill this gap.

The Goal

At the end of this article you’ll have a working PXE server that lets you boot memtest86+ over a network.

The goal is to have a simple but working solution. This is why I’m using memtest. It consists of just one file and thus is easy to use in a PXE setup. More complex scenarios (i.e. loading real operating systems) can be built on top of this simple setup.

Everything described in the article can be done inside a virtual machine. The only requirement is that the VM is connected directly (i.e. no NAT) to the network where it’s supposed to serve PXE (usually the host’s network).

The Basics: PXE, DHCP, ProxyDHCP, TFTP, and dnsmasq

PXE is an abbreviation for “Preboot Execution Environment”. To put it simple: It’s a standardized way to boot an operating system over network (rather than from hard disk).

DHCP is usually used to assign IP addresses to computers/devices in a network. PXE is an extension to DHCP. To use PXE one needs a PXE-capable DHCP server.

When PXE was designed, the creators wanted to make it compatible with networks that already have an existing DHCP server. As a result, PXE and DHCP can be provided by separate servers without interfering with each other. In this scenario, the PXE server is called proxyDHCP server and only provides the PXE functionality (but doesn’t do IP assigning).

TFTP (Trivial File Transfer Protocol) is used by PXE clients to download the operating system (file) from the PXE server.

dnsmasq is a “simple” Linux tool that combines a DNS server, a DHCP server, a TFTP server, and a PXE server. This is the tool you’ll use in this article.


The steps in this article are based on Ubuntu 16.04.

You need the following packages:

$ apt-get install dnsmasq pxelinux syslinux-common

You also need the precompiled memtest binary:

$ wget
$ gzip -dk memtest86+-5.01.bin.gz

Furthermore, you need a working DHCP server (e.g. one provided by a hard router).

The last thing you need is to know the network you’re on. My network is 192.168.178.XXX – so I’ll use this in this article. This information is only needed once in a configuration file (see below).

Warning: During the course of this article your Ubuntu machine may temporarily lose the ability to do DNS lookups. This is caused by dnsmasq. If this happens to you and you need to download anything or access the web, just (temporarily) stop dnsmasq.

Step by Step: From Start to Finish

Lets do it then. This section describes all steps need to get a working PXE server.

First, lets stop dnsmasq for now.

$ service dnsmasq stop

Create the directory where all transferable operating system files will reside:

$ mkdir -p /var/lib/tftpboot

Inside of this directory, create a directory for the unzipped memtest binary file and copy it there:

$ mkdir -p /var/lib/tftpboot/memtest
$ cp ~/memtest86+-5.01.bin /var/lib/tftpboot/memtest/memtest86+-5.01

Important: Note that the copy command removed the .bin file extension. This is required.

Now create the directory for the PXE configuration file:

$ mkdir -p /var/lib/tftpboot/pxelinux.cfg

Important: This directory must always be called pxelinux.cfg.

Inside of this directory, create a file called default and put in the following content:

default memtest86
prompt 1
timeout 15

label memtest86
  menu label Memtest86+ 5.01
  kernel /memtest/memtest86+-5.01

Next, you need to put the files pxelinux.0 (Ubuntu package pxelinux) and ldlinux.c32 (Ubuntu package syslinux-common) in /var/lib/tftpboot. I’ll use symlinks for that:

$ ln -s /usr/lib/PXELINUX/pxelinux.0 /var/lib/tftpboot/
$ ln -s /usr/lib/syslinux/modules/bios/ldlinux.c32 /var/lib/tftpboot/

Now, clear all contents of /etc/dnsmasq.conf and replace them with this:

# Disable DNS Server
# Enable DHCP logging
# Respond to PXE requests for the specified network;
# run as DHCP proxy
# Provide network boot option called "Network Boot".
pxe-service=x86PC,"Network Boot",pxelinux

Important: In line 9 you need to put in your network, if you’re not on 192.168.178.XXX.

Edit /etc/default/dnsmasq and add the following line to the end:


This line is necessary because you disabled dnsmasq’s DNS functionality above (with port=0). Without it Ubuntu will still redirect all DNS queries to dnsmasq – which doesn’t answer them anymore and thus all DNS lookups would be broken. You can check /etc/resolv.conf and verify that it contains the correct IP address for your network’s DNS server.

Last step – start dnsmasq again:

$ service dnsmasq start

Now, when starting a PXE-enabled machine, it should boot memtest.



While I was trying to get a PXE server working, I stumbled across some pitfalls that I like to add here.

Starting dnsmasq fails because resource limit

When starting dnsmasq with:

$ service dnsmasq start

and you get the error:

Job for dnsmasq.service failed because a configured resource limit was exceeded.

… then you (accidentally) deleted /etc/dnsmasq.d/README.

The dnsmasq init script checks the existence of this file and this leads to this obscure error message (filed as #819856).

PXE Boot with VMWare Fusion

VMWare Fusion’s GUI is more designed for regular users than developers. If you want to use PXE boot in a VMWare Fusion VM, make sure you select “Bridged Networking” rather than “Share with my Mac” (which is NAT).


PXE Boot with Hyper-V

To be able to PXE boot a Hyper-V VM, you need to add a Legacy Network Adapter to the VM. By default, only a non-legacy network adapter is added to VMs and it doesn’t support PXE boot (for whatever reason).


This is especially confusing since the “BIOS” section always lists “Legacy Network adapter” – even if none has been added to the VM.


  1. Marc Hoaglin said:

    Great Article.
    Can you show how this can be done for legacy BIOS and UEFI simultaneously?

    • Sebastian Krysmanski (post author) replied:

      Unfortunately, not at the moment. I haven’t figured that out (yet) – the legacy BIOS thingy was hard enough

  2. Tagz said:

    I want to boot laptops by using PXE but I cannot controll which IPs are used in network. Is it possible that PXE client and PXE server use IPs and when operating system starts it will get IP from actual DHCP server which might be like or something else?

    • Sebastian Krysmanski (post author) replied:

      Sorry, but I can’t help you here. PXE was complicated enough to figure out and I didn’t dig any deeper (yet).

  3. Matt van de Werken said:

    Excellent blog Manski – I’ve used it as inspiration for my own solution to the same problem. I have managed to implement a multiboot menu though using your excellent blog as a starting point. You can find my solution at:
    * Part 1 – basic setup covering memtest86+
    * Part 2 – setting up for Ubuntu i386, and
    * Part 3 – System Rescue CD and Clonezilla.

    Thanks for providing an excellent starting point!

    • Sebastian Krysmanski (post author) replied:

      Thanks for sharing these great tutorials. I’ve just brushed over them quickly but I’ll definitely have a deeper look at them when I revisit PXE booting in the future.

  4. MKay said:

    Great work! Thank you very much for share.

  5. Sherman said:

    You are the man! I’ve been trying to get this done for days. Every search I did ended with a “Nope. You just can’t do it. You JUST MUST have a DHCP server that supports PXE.”

    That seemed so silly. I have a nicely-working DHCP server (in my router). I don’t want to scrap that. What a headache. Finally I found your tutorial. It worked perfectly on the first try.

    I’m running dnsmasq inside a FreeNAS jail. FreeNAS is FreeBSD-based, but I’m wanting to boot ubuntu on the clients so there was minimal modification from what you have here.

    Thanks again. Super-awesome.

  6. Harvs said:

    Why did you disable the DNS capability of DNSMasq? I want to set this up on a PiHole raspberry pi, which requires the DNSMasq DNS.

    • Sebastian Krysmanski (post author) replied:

      It was not necessary and would be kind of useless for a DHCP Proxy.

  7. Paul said:

    Thank you for sharing this. Very helpful.

  8. adrien said:

    I finished your tutorials in 10 minutes… and it did work ! (knowing that I had already prepared 2 virtual machines with Debian preinstalled). After 4 hours of search in internet, I was still around the beginning of the setup.
    Your tutorial was like a cheat code lol. Thank you !

  9. SBPAABCK said:

    At last a guide that works – I have been trying to get DNSMASQ to work as a proxydhcp server for ages now… youre right all the other guides are pants (my words not yours)


  10. PiXiE said:

    Very helpful!

    One change I had to make was to copy the files pxelinux.0 and ldlinux.c32 into the tftpboot directory instead of linking them because with linked files, the tftp client failed to download them, reporting that there was no such file or directory.

  11. peter said:

    this does not work as you do not discuss what to do with the existing dhcp server on the lan maybe you could specify its dhcp settings of the dhcp server which is not the same as the pxe server
    i find it very unsatisfied when i google and on every search i reach this tutorial which does not work for this situation.

    • Anonymous replied:

      You don’t do anything with the existing server, that’s the point. This works alongside the existing server, only serving network boot requests. The existing server still assigns addresses and handles everything, unless the device wants to network boot, then this one steps in and takes care of it.

  12. Noire said:

    Great tutorial, too bad it didnt work

  13. Nader said:

    Thank you for your excellent guide!

    I’ve been jumping between various guides and piecing bits together, yours contained everything I was missing.

    I’m configuring this on AlmaLinux and all my c32 files and `pxelinux.0` are located in this folder. This could perhaps be the same for Ubuntu? If so then you don’t need the `pxelinux` package, I only needed to install the `syslinux` package.

    With regards to symlinking the syslinux files, would it be safe to do it like this:
    ln -s /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
    ln -s /usr/share/syslinux/*.c32 /var/lib/tftpboot/

    Thank you again for writing up this detailed and easy to understand guide!

  14. jprosoft said:

    Amazing Article. Thank you for sharing.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.