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
- CD images of grml 1.1 ("Skunk"; works at least starting with 0.9) and Ubuntu 7.10 (desktop live cd) ("Gutsy Gibbon", Feisty works as well. Hardy Heron Alpha 5 works, too.)
- the Debian Etch netboot installer,
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).
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";
(PXE uses TFTP, FTP's little brother in UDP. Think of it as a super lightweight FTP.)
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.
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.
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!
What happen? Let's start where we stopped after the last checkpoint:
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!
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.
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.
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
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)
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.)
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)
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.
- grml Wiki: http://wiki.grml.org/doku.php?id=terminalserver
- Howto forge on PXE servers: http://www.howtoforge.com/ubuntu_pxe_install_server
- Bootsplash images: http://www.mail-archive.com/debian-custom@lists.debian.org/msg01357.html
- PXELINUX: http://syslinux.zytor.com/
- Z. Johnson on diskless ubuntu (with read-write NFS): http://www.math.ucdavis.edu/~zjohnson/howto/diskless_ubuntu.html
- Options for casper: http://wiki.debian.org/DebianLive/casper-manpage#head-3831660508c7a32ca9de412c73896015fdc914fe
- Options for the Debian installer (preseed file): http://www.debian.org/releases/etch/example-preseed.txt
The original URI for this document is http://christian.amsuess.com/tutorials/lanbootserver/. It is available as HTML or as reStructuredText.
- 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
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).
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:
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.