In this project, I will show you how to network boot an Arch Linux ISO image with DNSMASQ set up in proxy DHCP mode. The approach taken here should readily generalize to the ISO images of other distributions. If you understand what’s being done here, adapting to another distribution should not be too difficult.
I’m indebted to the Arch Linux wiki site, and the PXE page in particular, for many of the technical details I make use of in this article.
DNSMASQ is a very handy daemon that can handle not only DNS service, but also DHCP and TFTP as well. For this project, we won’t be using the DNS functions and will have them turned off. The big picture is that we’re going to use the DHCP function of DNSMASQ to respond to PXEboot requests from a DHCP client. (To initiate a PXE boot, there’s usually a “Boot from Network” option on either the BIOS setup page or boot options page when an Intel-based PC starts up)
This response will tell the client to download boot code from a TFTP server – also handled by DNSMASQ – which in turn will get us to a menu page being displayed on the client computer. The boot code on the Arch Linux ISO is PXElinux, a variant of the syslinux boot loader.
From the menu page (displayed by the boot code), the user will select a download method for Arch Linux itself (still from the ISO image). In this case , we’ll show how to use HTTP as the download method and darkhttpd as the web server (no reason we couldn’t use Apache, but darkhttpd is a single file, it’s easy to configure – no config files – and it doesn’t have to run as a daemon.)
Why Use Proxy Mode
This article differs from the referenced PXE article on the Arch Linux site primarily in that I show how to use “proxy mode”, in which the server responds only to requests for network boots. Specifically, it doesn’t allocate IP addresses in proxy mode. For most household situations, you already have a DHCP server set up – it’s in your residential gateway or wireless router. Proxy mode allows you to set up another DHCP server just to service network boot requests – and because it won’t allocate IP addresses we avoid the risk of conflicting with the existing DHCP server. (Note: if you understand how to work around this, the PXE article on the Archlinux Wiki uses DNSMASQ in an ordinary DHCP mode while also serving netboot requests.) In my case, I wanted to leave the network boot capability on all the time, and didn’t want to have to have two IP address pools on my home network.
Download and Mount the Arch Linux ISO Image
Download the latest ISO image from the Arch Linux download site. Now create a mount point and mount the ISO image:
# mkdir -p /mnt/archiso # mount -o loop,ro archlinux-2014.09.03-dual.iso /mnt/archiso
We mount it with the loop option, which allows us to see the file structure within the ISO file.
Set up the TFTP Download Directory
The PXElinux boot loader expects to find its boot file, lpxelinux.0, in the root of the arch directory. Since that’s not the way the ISO image is laid out, we need to create some symlinks to make PXElinux happy. First, create a directory from which eventually we’ll serve files via TFTP:
# mkdir /srv/tftp/archlinux-iso
Now create symlinks within this directory to several directories that are expected to be in the same directory as the lpxelinux.0:
# ln -s /mnt/archiso/arch/boot boot # ln -s /mnt/archiso/arch/i686 i686 # ln -s /mnt/archiso/arch/x86_64 x86_64
Now create a symlink to the initial boot file, lpxelinux.0 itself:
# ln -s boot/syslinux/lpxelinux.0 lpxelinux.0
PXElinux expects to find a directory named
pxelinux.cfg at the same directory level:
# mkdir /srv/tftp/pxelinux.cfg # cd /srv/tftp/pxelinux.cfg
The directory looks like this when you’re done:
lrwxrwxrwx 1 root root 22 Sep 13 21:26 boot -> /mnt/archiso/arch/boot lrwxrwxrwx 1 root root 22 Sep 13 21:27 i686 -> /mnt/archiso/arch/i686 lrwxrwxrwx 1 root root 25 Sep 13 21:28 lpxelinux.0 -> boot/syslinux/lpxelinux.0 drwxrwxr-x 2 root root 4096 Sep 13 14:37 pxelinux.cfg lrwxrwxrwx 1 root root 24 Sep 13 21:27 x86_64 -> /mnt/archiso/arch/x86_64
Finally, PXElinux looks for a file named
default within the pxelinux.cfg directory. Now create the
default file, which tells lpxelinux.0 where the next step in the boot chain is located.
LABEL loadconfig CONFIG boot/syslinux/archiso.cfg
Setting up DNSMASQ
With that preliminary work done, setting up DNSMASQ is fairly straightforward. I created a separate file named “
PXEboot” stored in the
/etc/dnsmasq.d directory to avoid editing the distributed version of
/etc/dnsmasq. There’s no reason you couldn’t just use the
/etc/dnsmasq file itself if you wanted. I’ll give you the whole configuration first, then we’ll go through it line by line.
# DNS Options port=0 # DHCP Options dhcp-range=192.168.1.136,proxy,255.255.255.0 dhcp-option=vendor:PXEClient,6,2b dhcp-no-override pxe-service=X86PC, "Boot from network", lpxelinux # TFTP Options enable-tftp tftp-root=/srv/tftp/archlinux-iso
Let’s take these one at a time.
This disables the DNS server:
This tells DNSMASQ not to provide address service, but to respond to PXEboot requests arriving from the 192.168.1.0/24 network.
This tells DNSMASQ to send disable multicast and broadcast discovery, and to download the boot file immediately.
dhcp-no-override is a safety measure, probably optional. From the man page:
Disable re-use of the DHCP servername and filename fields as extra option space. If it can, dnsmasq moves the boot server and filename information (from dhcp-boot) out of their dedicated fields into DHCP options. This make extra space available in the DHCP packet for options but can, rarely, confuse old or broken clients. This flag forces “simple and safe” behaviour to avoid problems in such a case.
The final DHCP option is
pxe-service=X86PC, "Boot from network", lpxelinux
DNSMASQ will ignore this option unless the
dhcp-range option is set to proxy. When it is, this option sends the filename for the client to download. Note that the “
.0” is missing from the end. Somewhere or another, it gets added back, and if it’s here, the filename will end with “
.0.0“, which is not what we want.
The two TFTP options are pretty self-explanatory. One enables the TFTP server, and the other tells DNSMASQ where to serve files from. This is, of course, the directory we spent so much time setting up earlier.
Caution to Ubuntu Users
If you have a Ubuntu-based server, you may run into problems attempting to use DNSMASQ as a daemon. In a [Rant]misguided[/Rant] attempt to make things simple for mobile users, on Ubuntu 12.04 and later NetworkManager uses DNSMASQ as a DNS resolver. Only the dnsmasq-base package is installed by default. I got lots of really odd behaviors involving DNS functions and resolvconf until I completely disabled NetworkManager from using DNSMASQ and forced name searches to be directed to the network DNS server instead of being rerouted internally. [Rant]I’m normally pretty happy using Ubuntu Server, but seriously – how many servers need mobile support because they’re moving in and out of networks? Answer – not enough to make the NetworkManager complexity worth it for Ubuntu Server. On my things-to-do list is a task to cleanly remove all vestiges of NetworkManager – but what I did works for now[/Rant]
At this point, if a client were to initiate a PXE boot, after a bit of back-and-forth the user will be presented with a nicely formatted menu of options, but selecting any of them will result in some error messages due to files not found. To address this, we’ll set up to enable the HTTP download option, using darkhttpd. This part is extremely straightforward:
# darkhttpd /mnt/archiso/ --no-keepalive
This command starts a very simple HTTP server. With the server running, when the client initiates a PXE boot, then selects the HTTP option from the displayed menu, the server provides the requested files.
It’s not too difficult to set a Linux server based on DNSMASQ and darkhttpd to enable network booting of the Arch Linux ISO. From here, you can either use the bare bones system provided, or follow the installation instructions to set up Arch Linux on your client machine. Good luck!