How To Set Up A Lan Boot Server

Introduction

So you have your LAN set up and everything works fine. DHCP and DNS make allow you to use every PC in your network without any effort. Still -- something is missing. Unsure of what you are missing, you look around and spot that stack of bootable CDs on your desk. grml, Ubuntu live CD, Debian, each in different releases. Really necessary? Well, actually, not at all...

This text will provide a step-by-step guide to installing a boot server on a LAN, providing different linux distributions (I am not familiar with boot mechanisms of other operating systems; parts of this might apply as well) and is, in large parts, a compilation of information already available on the web. I will assume the following setup, occasionally discussing alternatives:

  • a Debian server to accommodate most services (every Linux (or other unixoid) will do as long as it can run a TFTP and NFS server),
  • an OpenWRT router running DHCP using dnsmasq (most DHCP servers should do on any OS; can also be the server itself) and
  • clients supporting PXE boot. (Most modern PCs have this capability. For testing, I recommend using a virtual machine.)

You'll also need at least one of

and optionally
  • a computer with an image manipulation program (e.g. GIMP) and ppmtolss16 installed (latter comes with SYSLINUX; required if you want to design your own boot screen).

It is assumed that you can autonomously operate standard GNU/Linux tools like tar or wget, your distribution's package manager (e.g. apt-get) and understand the linux boot process well enough to have heard of initrd. You should have already booted from linux CDs, which gives you basic familiarity with ISOLINUX/PXELINUX (you don't have to know what it is).

Configuring The DHCP Server

Discovery of the boot parameters is handled by DHCP/BOOTP. Detailed knowledge of the process is not necessary for installing a boot server. For the dnsmasq DHCP server, adding this line to dnsmasq.conf is sufficient:

dhcp-boot=/srv/tftp/pxelinux.0,<SERVERNAME>,<SERVERIP>

It seems that <SERVERNAME> is more or less irrelevant, since everything worked fine although i had not yet registered the new host name at that time. pxelinux.0 is the file name to load and run from there. Restart dnsmasq by killall dnsmasq; dnsmasq for the changes to take effect.

If you use dhcpd, add the following lines to the section describing the clients you want to provide images for:

next-server <SERVERNAME>;
filename "/srv/tftp/pxelinux.0";
CHECKPOINT
If you boot your test client now (after setting the boot sequence to "network first"), it gets an IP address, but times out when trying to access the TFTP server.

(PXE uses TFTP, FTP's little brother in UDP. Think of it as a super lightweight FTP.)

About PXELINUX

PXELINUX is the bootloader we are going to use; it is the network equivalent to GRUB or LILO (booting from harddisk) or ISOLINUX (booting from cd).

PXELINUX is developed together with ISOLINUX and SYSLINUX. They differ mainly in the backend, the frontends are virtually identical, to the distributor as well as to the end user. You probably know all those bootable CDs where you switch screens with F1, F2, ... -- that's ISOLINUX; PXELINUX looks and feels the same.

Setting Up A TFTP Server

Although dnsmasq can provide a TFTP server, I decided to run one on the Debian server, because that's where I have all the other data of the boot images; I use tftpd-hpa (there is a Debian package with that name).

By default, the directory /srv/tftp/ is exported via TFTP, so no further configuration is required; just install it and make sure you can be reached.

First Data: grml

grml is a "linux live-cd for sysadmins / texttools-users / geeks", one of whose features is to provide a boot server on a machine running grml by issuing a single command. This makes grml the logical choice for a first test system, as the image will certainly boot off the network.

As described in the grml wiki, you need the grml_netboot_package for the current grml version. In order to get a first netboot distribution up and running, extract the archive's tftpboot folder's contents directly into the server's /srv/tftp/.

Before we move to detailed inspection of the package, let's just see what works right now!

CHECKPOINT
The test client will offer the usual grml boot screen as known from the CD. You can start grml by hitting <Return>, but after some time it will fail with a bunch of suggestions what can have gone wrong, dropping you to the busybox shell. (busybox is a collection of programs for basic unix operation, used in an initrd environment). This error is ok, we haven't finished the setup yet, but up to here, it works.

What happen? Let's start where we stopped after the last checkpoint:

The BIOS ...
  • successfully connected to the TFTP server,
  • fetched the pxelinux.0 file as instructed by DHCP, and
  • executed pxelinux.0.
pxelinux.0 ...
  • checked for the existence of a pxelinux.cfg/default file where it was loaded from,
  • loaded that configuration file and acted on it, showing the boot screen,
  • proceeded by executing the default action when you pressed <Return>,
  • loaded a kernel and gzipped initrd, still using TFTP,
  • decompressed those and executed the kernel, passing some parameters
grml ...
  • ran through a bunch of initialization and hardware detection procedures,
  • tried to mount a remote directory containing the CD contents and finnally
  • failed.

It's time to examine the PXELINUX configuration to find out more (this is the grml pxelinux.conf/default from grml_netboot_package, indented and shortened):

DEFAULT linux26
        APPEND root=/dev/nfs rw nfsroot=192.168.0.1:/live/image boot=live lang=us nomce quiet apm=power-off nodhcp noprompt noeject initrd=minirt26.gz vga=791
TIMEOUT 100
PROMPT 1
DISPLAY boot.msg
F1 boot.msg
LABEL grml
        KERNEL linux26
        APPEND root=/dev/nfs rw nfsroot=192.168.0.1:/live/image boot=live lang=us nomce quiet apm=power-off nodhcp noprompt noeject initrd=minirt26.gz vga=791
LABEL ...
        ...

For this config file, sequence matters, indent does not (the latter is used here to show the semantics of the former), case matters not.

You'll have noticed that the DEFAULT section and the LABEL grml sections are identical, with the DEFAULT keyword replacing KERNEL. This is PXELINUX's way of defining what happens on timeout or when the user presses <Return>. (You could just as well refer to the other settings with DEFAULT grml and no APPEND after that.) linux26 is the file name of the kernel to load from TFTP, the options after APPEND are passed to the kernel as command line.

The init ram disk, specified as initrd=minirt26.gz, is loaded by from TFTP as well -- I welcome any feedback on how this exactly works, i just noticed that this works with other files too (preseed, mentioned later).

TIMEOUT tells PXELINUX to run DEFAULT after 100 seconds, PROMPT 1 makes a prompt appear at all. DISPLAY specifies the message to show from the beginning, F1 to F10 are used to show other messages when the user presses any of those keys. Message files are plain text files with controll characters to do fancy things like loading images. LABEL grml describes which KERNEL be loaded when the user requests grml on the boot prompt.

Inspection of the APPEND-ed options shows the reason for the failure of the first test: grml looked for a nfs share not yet available. So let's set up that next!

NFS setup

I have no idea of how NFS works, so I'll keep this section short.

Install an NFS server, nfs-kernel-server. (I used to recommend nfs-user-server here. See Previous problems with NFS for the reasons and what you have to do when you have to use nfs-user-server.)

Create a directory /var/lib/nfsboot and add the following line to /etc/exports:

/var/lib/nfsboot/grml_1.1/ *(ro,insecure,all_squash)

(/var/lib/nfsboot was chosen arbitrarily to resemble /var/lib/tftpboot, the historic default of tftpd. Note that using nfs-kernel-server, you can't mount sub-directoies of exported directories, so you have to export every single CD image!)

Restart nfs-kernel-server -- NFS should now work.

Before you can adjust pxelinux.conf/default, you first have to provide the required data on the NFS, this can be easily done by mounting the grml image to /var/lib/nfsboot/grml_1.1 (don't forget that this is a loopback mount; use -o loop!). Later, you might want to unextract the data permanently.

Now modify pxelinux.conf/default and set nfsdir=<SERVERIP>:/var/lib/nfsboot/grml_1.1.

CHECKPOINT
The Client is able to boot grml from LAN.

More Than One Distribution

Until now, you can only boot grml. If you want to serve several distributions or OSes, you have to create an own pxelinux.cfg/default config. First, move everything from /srv/tftp/ to a subdirectory called grml_1.1/. The final directory structure will look roughly like this, just to get an overview:

/srv/tftpd
|
+-+ debian-etch                         \
| +--+debian-installer/i386/... *       |
| +--+gtk/...                           |
| +-- mini.iso                          |
| +-- netboot.tar.gz                    |
| +-- pxelinux.0                        |
| +-+ pxelinux.cfg                      |
|   +-- default                         |
|                                       \  three distribution images
+-+ grml_1.1                            /
| +-- boot.msg *                        |
| +-- linux26 *                         |
| +-- logo.16 *                         |
| +-- memtest                           |
| +-- menu.lst                          |
| +-- minirt26.gz                       |
| +-- pxelinux.0                        |
| +-+ pxelinux.cfg                      |
|   +-- default                         |
|                                       |
+-+ ubuntu-gutsy-desktop                |
| +-- initrd.gz *                       |
| +-- ubuntu.seed *                     |
| +-- vmlinuz *                         /
|
+-+ lan **                              \
| +-- boot.txt *                        |  files referred to in the pxelinux configuration
| +-- f3.txt .. f5.txt *                |
| +-- splash.rle *                      /
|
+-- pxelinux.0 *                        \
+-+ pxelinux.cfg                        |  files essential to pxelinux
  +-- default *                         /

You may have already noticed that only the files marked with * are really used at all. All the others are relics of the independent boot CDs, which I left in place to look up certain things or quickly switch the boot server to, say, Debian only by just a couple of mv-s.

The lan directory (marked **) holds auxiliary files for the PXELINUX configuration; the names of directory and files are chosen arbitrarily.

Install PXELINUX

Copy pxelinux.0 over from the grml directory. (This is maybe a good time to mention that symlinks won't work in TFTP.) Create a pxelinux.cfg directory and a pxelinux.cfg/default config as follows:

DEFAULT grml

DISPLAY lan/boot.txt
F1 lan/boot.txt
F3 lan/f3.txt
F4 lan/f4.txt
F5 lan/f5.txt

PROMPT 1
TIMEOUT 0

LABEL grml
        KERNEL grml_1.1/linux26
        APPEND root=/dev/nfs rw nfsdir=<SERVERIP>:/var/lib/nfsboot/grml_1.1 boot=live lang=us nomce quiet apm=power-off nodhcp noprompt noeject initrd=grml_1.1/minirt26.gz vga=791

The LABEL grml section is taken from our latest version of grml_1.1/pxelinux.cfg/default, with paths for KERNEL and initrd adapted to the new directory structure. For a complete description, read the manual.

Now create lan/boot.txt:

^Xlan/splash.rle

Hello and welcome on the LAN! This is <SERVERNAME> <ETC...>

Available systems: grml (F3), ubuntu-live (F4), debian (F5)

(The first character is Control-X, character 030. You can influence the display by various other options.)

The other f?.txt files can hold information about which parameters the individual distributions take; for the time being, it will just show a distribution logo (lan/f3.txt):

^Xgrml/logo.16
CHECKPOINT
Client displays our welcome message (without image). grml splash screen is shown after pressing F3, welcome message restored after pressing F1. grml still boots normally.

Create An Own Bootsplash Image

Just because it looks cool, you can create a custom bootsplash screen for PXELINUX (same can be used for other *LINUX bootloaders as well). If you prefer to skip this step, just remove the ^Xlan/splash.rle line from boot.txt and go ahead.

Splash images are stored in a special runlength encoding format with 16 colours, sizes up to 640x400 are known to work; if you want to display text as well, make sure there is enough space (Ubuntu uses 639x320, for example).

Design your bootsplash image, reduce its colour depth to 16, and save it as a "Netpbm PPM" image splash.ppm. Then do:

ppmtolss16 "#000000=0" "#ffffff=7" < splash.ppm > splash.rle

and put splash.rle into /srv/tftpd/lan/.

If warnings occur, make sure there are only 16 colours in the image. (GIMP: Image / Mode / Indexed... / Generate optimum palette, 16 colours)

CHECKPOINT
Same as before, but with your custom bootsplash image.

Add Debian Installer

Adding the Debian installer to the netboot server is easier than was adding grml, but not as useful, for you can only install Debian with it. (In fact, you can already do so with grml using debootstrap, but you might find the Debian installer more comfortable. It already provides interesting ways of setting defaults. The Debian netboot installer does not need NFS because all it needs is contained in the initramfs image or fetched from a mirror.)

Download the beforementioned Debian Etch netboot installer directory as /srv/tftpd/debian-etch. Copy the LABEL expert or LABEL install section from from debian-etch/pxelinux.cfg/default over to your own default and rename it to debian. You can use one or more of those sections; you can modify your settings at any time on the PXELINUX command line by appending options, so which defaults to provide is basically a matter of taste.

Adapt all sections by prefixing kernel and initrd options with debian-etch/.

Questions the Debian installer asks can be prefilled here. Take this as an example:

LABEL debian
        kernel debian-etch/debian-installer/i386/linux
        append priority=low vga=normal initrd=debian-etch/debian-installer/i386/initrd.gz netcfg/disable_dhcp=false mirror/protocol=http mirror/country="enter information manually" mirror/http/hostname=<LOCALAPTSERVER> mirror/http/directory=/debian/ mirror/http/proxy= --

priority=low shows that I prefer expert mode, netcfg/disable_dhcp=false is tells the installer to use DHCP (which is, as we know, available on the LAN), the mirror/ options tell it not to ask for a mirror, but instead use the one available locally without a proxy. (If you don't know the URL of your closest APT mirror, just leave those options out.)

CHECKPOINT
Enter debian at the PXELINUX prompt and press <Return>. The Debian installer starts and offers to install.

Add Ubuntu Live CD

The live CD was not explicitly built to support that feature, but due the flexibility of the initramfs creation mechanism, mkinitramfs, and casper, the system used for live CDs, it is possible anyway.

Mount the live CD image to /var/lib/nfsboot/ubuntu-gutsy-desktop/ (Feisty and Hardy work too), as you did with grml. Copy vmlinuz, ubuntu.seed and initrd.gz from the CD's casper/ directory to the newly created /srv/tftpd/ubuntu-gutsy-desktop/, as well as splash.rle and isolinux.cfg (the latter is just for convenience).

As before, copy LABEL sections from ubuntu-gutsy-desktop/isolinux.cfg at your discretion. (I suggest naming it ubuntu-live.) You can drop the menu label lines -- they are only relevant if you use an alternative graphical representation of PXELINUX. Adopt them again by prepending ubuntu-gutsy-desktop/ to kernel and initrd=, leave file= unchanged (this path is interpreted relative to the image provided via NFS). Now append the magical options netboot=nfs nfsroot=<YOURSERVERIP>:/var/lib/nfsboot/ubuntu-gutsy-desktop to the append section, and drop the quiet splash -- you'll probably want to see what's up.

Append the following line to /etc/exports:

/var/lib/nfsboot/ubuntu-gutsy-desktop/ *(ro,insecure,all_squash)
CHECKPOINT
Boot the client into ubuntu-live. The client boots a live Ubuntu system.

Further Steps

In theory, this should work for most bootable linux CDs. I have not tried non-debian-based distributions.

Dependent of what options you plan to use, what you know by heart, and which options the distributions offer, you can assemble individual cheat sheets for the Fn keys (remember, you can always add options on the PXELINUX command line). Especially for the debian installer, there is a huge number of options you can set as defaults for automated installs. You can package those into a preseed file as used by ubuntu if the append line gets unmanagably long or you hit any limit.

Sources

About this How To

  1. chrysn <chrysn@fsfe.org> 2007-2008, published under CC-BY-SA.

The original URI for this document is http://christian.amsuess.com/tutorials/lanbootserver/. It is available as HTML or as reStructuredText.

Changes

  • 2007-12-07: Added Ubuntu 7.10, grml 1.0
  • 2008-02-06: Added Ubuntu 8.04
  • 2008-02-29: Added grml 1.1, fixed the NFS problem
  • 2010-02-15: Changed tftp paths to reflect new defaults

Plans

There is a number of changes on my TODO list for this tutorial. Adding grub2 might move this from a LAN bootserver tutorial to "How To Boot Anything From Anywhere", but I'm not quite there yet (up to now, it's just a sketch).

Previous problems with NFS

In earlier versions of this tutorial, I recommended using nfs-user-server over nfs-kernel-server. It turned out that the Ubuntu live CD images' initrd.gz files need to be patched in order to work with nfs-user-server. In case you have good reasons to use nfs-user-server, the following will happen when you first try to start Ubuntu:

CHECKPOINT
Boot the client into ubuntu-live. It drops you into a busybox shell. Type cat /casper.log; it should end in rpc failed: 2 repeated several times, followed by Done. and Unable to find a live file system on the network.

Modify your initrd.gz images as follows:

  • In a temporary directory, zcat /srv/tftpd/ubuntu-gutsy-desktop/initrd.gz | cpio -i to extract the initial ramdisk.
  • Edit scripts/casper and change nfsmount to mount in line 215 (175 for Feisty, 220 for Hardy Alpha 5). To ease debugging, do the same in the log message line in line 212 (172 for Feisty, 217 for Hardy Alpha 5).
  • In the beforementioned temporary directory, find |cpio -o -H newc |gzip -9 > /srv/tftpd/ubuntu-gutsy-desktop/initrd-mod.gz (create the archive again in the same way as ubuntu's mkinitramfs does)
  • Change pxelinux.cfg/default to use initrd-mod.gz instead of initrd.gz.

There is a bug report pending, but it seems that the kernel server is the way to go these days anyway.

CHECKPOINT
Client boots into ubuntu-live without problems.