FreeBSD: a PXE network boot server (similar to RIS)

Practice



So, today our task is to set up a PXE network boot server based on FreeBSD. What for:

  • So that diagnostic utilities can be run over the network (MemTest, MHDD, etc.)
  • So that a LiveCD can be booted over the network
  • So that an OS can be deployed over the network


Actually, this article only covers points 1 and 2. I'll write about installing Windows 7 and other OSes via PXE a bit later (since that's about the same amount of material again).

For the PXE server we'll use the syslinux package, together with a local DHCP as well.

A quick note is in order (in case someone doesn't know). A machine that wants to boot via PXE (i.e. over the network) gets its network parameters via DHCP. This means, at minimum, that the DHCP server must be on the same network as the booting computer - i.e. BEFORE the first router.

1) First: we need a DHCP server so that clients can get their network parameters. How to set up such a server on FreeBSD - here's a link.

Once we've set up the server - we need to add the following lines to its config (in the zone description):

next-server 192.168.0.1;
filename "gpxelinux.0";

where instead of 192.168.0.1 - specify the IP address of the PXE server.

Also change the form of the range declaration:

range dynamic-bootp 192.168.0.100 192.168.0.200;

i.e. add the "dynamic-bootp" option.

we get something like this (this is just an example):

subnet 192.168.0.0 netmask 255.255.255.0 {
option routers 192.168.0.1;
option broadcast-address 192.168.0.255;
range dynamic-bootp 192.168.0.100 192.168.0.200;
next-server 192.168.0.1;
filename "gpxelinux.0";
}


And finally, restart the DHCP server:

$ sudo /usr/local/etc/rc.d/isc-dhcpd restart


2) Installing the TFTP server.

TFTP is needed for the PXE server to work. It doesn't matter whether you'll later serve files over HTTP (which is many times faster), or also via TFTP (which is simpler) - either way we need it.

We'll use tftp-hpa, since in the future you may need to apply substitution rules, which the stock daemon can't do.

$ cd /usr/ports/ftp/tftp-hpa
$ sudo make install clean


Now let's create the directory for the PXE server.

$ cd /usr/local
$ sudo mkdir pxe
$ sudo mkdir pxe/images
$ sudo mkdir pxe/images/utils
$ sudo mkdir pxe/images/os
$ sudo mkdir pxe/images/livecd
$ sudo mkdir pxe/pxelinux.cfg


The last directory (yes, no mistake - it's not a file) is the folder for syslinux configuration files. The directories before the last one were created for convenience - to separate the utility files, LiveCD images, and installation images so they don't all end up piled together.


Next, open the file /etc/inetd.conf and bring the tftp line to the following form:

tftp dgram udp wait root /usr/local/libexec/in.tftpd in.tftpd -p -s /usr/local/pxe


And restart inetd:

$ sudo /etc/rc.d/inetd restart


You can view the server's logs in /etc/xferlog


3) Installing syslinux.

Don't rush off to the ports tree - yes, syslinux is in ports, but we don't need it from there! We'll download it separately from: link

$ cd ~
$ mkdir syslinux
$ cd syslinux
$ fetch http://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-4.05.tar.gz


Unpack it and copy the needed files:

$ tar -xf syslinux-4.05.tar.gz
$ cd syslinux
$ sudo cp gpxe/gpxelinux.0 /usr/local/pxe/
$ sudo cp com32/menu/menu.c32 /usr/local/pxe/
$ sudo cp com32/menu/vesamenu.c32 /usr/local/pxe/
$ sudo cp com32/modules/reboot.c32 /usr/local/pxe/
$ sudo cp com32/modules/chain.c32 /usr/local/pxe/
$ sudo cp memdisk/memdisk /usr/local/pxe/


4) This step isn't mandatory, but is highly recommended. The thing is, transferring large files over TFTP is a slow business. But syslinux can use the HTTP protocol for the same purpose - which is much faster.

So we'll set up the following scheme:

  • Loading pxelinux (syslinux) itself is done via TFTP
  • Loading small utilities like MemTest - also via TFTP
  • Loading large files - LiveCD ISOs, etc. - via HTTP


So let's set up an HTTP server (if you don't already have one running). I won't describe installing one here. An example of installing Apache 2.2 can be found here.

After installing Apache - add the following entry to its config file:


Order Deny,Allow
Deny from all
Allow from 192.168.0.0/16
Options Indexes

where instead of 192.168.0.0/16 - specify your own working subnet or set of subnets.

Now let's make a symlink to our PXE directory in Apache's working directory:

$ sudo ln -s /usr/local/pxe /usr/local/www/apache22/data/pxe


and restart Apache:

$ sudo /usr/local/etc/rc.d/apache22 restart


If you're not using Apache - then configure your server accordingly in a similar fashion.


5) Let's create a configuration file for syslinux. We'll create it using an example based on the MfsBSD LiveCD. This is about the simplest thing you can do.

5a) Download the MfsBSD ISO and put it in the right place.

$ cd /usr/local/pxe/images/livecd
$ fetch http://mfsbsd.vx.sk/files/iso/mfsbsd-9.0-RELEASE-i386.iso

Note - the link may be different by the time you read this - the MfsBSD project doesn't stand still. It's better to visit their site (link) and download the latest image for the architecture you need (I recommend x86, as it's universal).


5b) Now let's create the syslinux configuration file.

/usr/local/pxe/pxelinux.cfg/default:

ui menu.c32
menu title PXE Boot Menu

label boothdd
menu label Boot from Hard Drive
localboot 0

label mfsbsd
menu label MfsBSD LiveCD
kernel memdisk
initrd http://192.168.0.1/pxe/images/livecd/mfsbsd-9.0-RELEASE-i386.iso
append iso raw


Here we set:

  • The first item will be "Boot from local HDD"
  • The second: boot the MfsBSD LiveCD (by the way, the root password is: mfsroot).


Save the file.

PS. If you decided not to use an HTTP server after all - then the file will look like this:

ui menu.c32
menu title PXE Boot Menu

label boothdd
menu label Boot from Hard Drive
localboot 0

label mfsbsd
menu label MfsBSD LiveCD
kernel memdisk
initrd images/livecd/mfsbsd-9.0-RELEASE-i386.iso
append iso raw


6) Now try booting the machine via PXE. If you did everything correctly - it will boot.


7) Next, the PXE menu can be expanded. Below I'll give an example of my own draft config.

Since syslinux allows creating submenus - my example config consists of several files.

  • default: the main menu itself.
  • utils.menu: the Utilities menu
  • livecd.menu: the LiveCD menu
  • os.menu: the network OS installation menu


default:

ui menu.c32
menu title PXE NetBoot

label menu_utils
menu label Utilities
kernel menu.c32
append pxelinux.cfg/utils.menu

label menu_livecd
menu label LiveCD
kernel menu.c32
append pxelinux.cfg/livecd.menu

label menu_os
menu label Setup OS
kernel menu.c32
append pxelinux.cfg/os.menu

label boothdd
menu label Boot from Hard Disk
localboot 0


utils.menu:

menu title Utilities - NetBoot

label menu_os
menu label ^Back
kernel menu.c32
append pxelinux.cfg/default

label memtest
menu label MemTest86
kernel images/utils/memtestp

label wmemtest
menu label Windows Memory Diagnostic
kernel memdisk
initrd images/utils/wmemtest.gz

label mhdd
menu label MHDD
kernel memdisk
APPEND initrd=images/utils/mhdd.img floppy

label hdt
menu label Hardware Detection Tool
kernel images/utils/hdt.c32

label winpwdchange
menu label Windows Password Reset
kernel images/utils/chntpw vga=1
initrd images/utils/chntpw.gz

label acronis
menu label Acronis
kernel http://10.0.1.1/pxe/memdisk
initrd http://10.0.1.1/pxe/images/utils/acronis.iso
append iso raw


livecd.menu:

menu title LiveCD - NetBoot

label menu_livecd
menu label ^Back
kernel menu.c32
append pxelinux.cfg/default

label xplive
menu label Windows XP LiveCD
kernel http://10.0.1.1/pxe/memdisk
initrd http://10.0.1.1/pxe/images/livecd/Windows_XP_Live_CD_Mini.iso
append iso raw

label xplivebig
menu label Windows XP LiveCD (BIG)
kernel http://10.0.1.1/pxe/memdisk
initrd http://10.0.1.1/pxe/images/livecd/LiveXP_RAM.iso
append iso raw

label livelinux
menu label Linux LiveCD (Debian)
kernel http://10.0.1.1/pxe/memdisk
initrd http://10.0.1.1/pxe/images/livecd/debian-livecd.iso
append iso raw

label mfsbsd
menu label MfsBSD
kernel http://10.0.1.1/pxe/memdisk
initrd http://10.0.1.1/pxe/images/livecd/mfsbsd-9.0-RELEASE-i386.iso
append iso raw


os.menu:

menu title Install OS - NetBoot

label menu_os
menu label ^Back
kernel menu.c32
append pxelinux.cfg/default

label iwin7
menu label Install Windows 7 Professional SP1 x86 GGWA (KMS)
kernel http://10.0.1.1/pxe/memdisk
initrd http://10.0.1.1/pxe/images/os/win7/winpe_x86.iso
append iso raw


As you can see - the configuration files contain the most varied ways of launching utilities. For example, if we just want to load some ISO into the machine's memory and have it treated as if it were a CD inserted into the drive - we use the memdisk kernel (by the way, don't try feeding it an ISO that's a couple of gigs in size - that's not going to work, believe me).

I won't be posting the actual files themselves (at least not for now) - I recommend digging through discs like Hiren's, Infra, etc. - they contain a number of utilities that suit our purposes (the same MemTest and MHDD, for instance). Opening these discs you can also roughly find out how it's all supposed to be launched.

For the Windows LiveCD images I used ready-made ISOs - and it works. The same goes for the FreeBSD LiveCD. For Linux LiveCDs you need to pick and choose to get one working - not all of them boot.



PS. In the next articles I'll describe how to deploy Windows 7 and Linux over the network. In reality it's not as obvious or simple as it sounds - I had to piece together the Windows 7 install via PXE syslinux, quite literally, from THREE different articles in different languages from different sources.

Applies to: FreeBSD 8.x+

Comments

To leave a comment

If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Lectures and tutorial on "Computer networks"

Terms: Computer networks