Setting Up a PXE Boot Server on Fedora 19

One of the nice things about all current network cards is that virtually all of them are capable of booting to a network server. This tutorial will show you how to set up a server using the Preboot Execution Environment, or PXE (pronounced Pixie). It is very easy to set up and can be immensely useful. For the purposes of this tutorial, I will be using Fedora 19 x86_64 as the host system. All packages can be found in the official Fedora OS repositories. For the tutorial, I will use CentOS 5.5 x86_64 as the PXE boot OS as well. I will also have examples of some other systems you can set up to boot to, though I will not go into as much detail about them.

Install the Required Packages

First, we need to install some packages on our Fedora 19 system. Some or all of these may already be installed on your system for other purposes.

yum install tftp-server syslinux httpd dhcpd

If you already have a DHCP server on your network somewhere, make sure you leave dhcpd off of the install list. Having two DHCP servers on a network can cause serious problems if they are not properly configured to work together. If you have a home router that functions as your DHCP server, check to see if it supports custom dnsmasq configurations. If it does (most custom Linux firmwares do), you can see my note at the bottom of this tutorial for setting up dnsmasq with the proper DHCP options.

Create and Configure the Boot Environment
The next step is to create a directory somewhere to hold all PXE boot files, menus, and OS images. The default location in the TFTP configuration file is /tftpboot, which is what I’ll use in this tutorial. Note that you can place the directory anywhere you like, but it has to be an actual directory. In my experience, it doesn’t seem to work with symbolic links in the path. So if you place it at /var/tftpboot, you can’t just create a symlink at /tftpboot -> /var/tftpboot to make it work with the defaults.
After we create the directory, we can configure the TFTP system so that it’s enabled and knows where to find its files. To do that, edit /etc/xinetd.d/tftp and change the following two lines:

disable = yes
server_args = -s /tftpboot

The disable option will need to change to no, obviously. The server_args option should point to the absolute path of whatever directory you created in the previous step. After you’re done, it should look like this:

service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}

Once that is configured, restart xinetd to force the changes to take effect.

/bin/systemctl restart  xinetd.service

Copy Boot Files

The next step is to copy the required syslinux files into the /tftpboot directory. These files will make up the actual system that boots the remote machine into the initial menu.

cp /usr/share/syslinux/{pxelinux.0,menu.c32,memdisk,mboot.c32,chain.c32} /tftpboot

Create the directory to place your PXE menu files in next. Also, create a base directory for the OS image files to go.

mkdir /tftpboot/pxelinux.cfg
mkdir /tftpboot/images

Create a subdirectory for the CentOS image files.

mkdir -p /tftpboot/images/centos/x86_64/5.5

Then mount the CentOS 5.5 x86_64 DVD disc 1 somewhere on your system. We will need to copy some files off of it into the image directory we just created.

mount -o loop /path/to/CentOS-5.5-x86_64-bin-DVD-1of2.iso /mnt

Copy vmlinuz and initrd.img from the DVD to the images directory.

cp  /mnt/images/pxeboot/{vmlinuz,initrd.img} /tftpboot/images/centos/x86_64/5.5

Configure DHCP
Now we need to configure our DHCP server to tell clients using the BOOTP protocol where to find our PXE server. Replace the xxx.xxx.xxx.xxx in the following code with the IP address of your PXE boot server.

subnet 192.168.10.0 netmask 255.255.255.0 {
range dynamic-bootp 192.168.10.100 192.168.10.150;
option broadcast-address 192.168.10.255;
option routers 192.168.10.10;
allow booting;
allow bootp;
next-server 192.168.10.10;
filename “pxelinux.0”;
}

The filename option won’t have to change no matter where you put your tftpboot directory. The filename is absolute within that directory because the client doesn’t see any of the rest of your file system. It is confined to just that tftpboot directory, much like a jail would accomplish. Again, if you use a home router with a firmware that supports dnsmasq, see my notes below about setting it up to accomplish this same task for you.
Now restart your DHCP server.

service dhcpd restart
(or)
/bin/systemctl restart  dhcpd.service

Set Up the Menus
The only step left is to create the menu that the client will see. This is actually the trickiest part because each Linux system you want to include will contain its own kernel boot parameters. You will need to consult with the documentation for each system to determine how to set it up for PXE booting. I will demonstrate using CentOS 5.5 x86_64 with and without a kickstart file. I will also show you how to create multi-tiered menus for more organized and sophisticated systems.

Single Tier Menu
To create a single tier menu, you only need to create one file. In /tftpboot/pxelinux.cfg, create a file named default. That will serve as our entire menu for now. At the top of this file, add the following text:

default menu.c32
prompt 0
timeout 300
ONTIMEOUT local
MENU TITLE PXE Menu
LABEL local
MENU LABEL Boot local hard drive
lOCAL BOOT 0

You can change the values for timeout and MENU TITLE as you like. The local hard drive label is designed as a default in case the user does not select an option before the timeout period is reached.
After that, you will add an entry for each system you want to boot. The structure of each entry will be similar even though the values will be different. Basically, each will look like this:

LABEL xxxxx
MENU LABEL xxxxx
KERNEL path/to/kernel
APPEND option1=xxxx option2=xxxx

For instance, to boot CentOS without using a kickstart file, you would set up the menu this way:

LABEL CentOS 5.5 x86_64
MENU LABEL CentOS 5.5 x86_64
KERNEL images/centos/x86_64/5.5/vmlinuz
APPEND initrd=images/centos/x86_64/5.5/initrd.img ramdisk_size=100000 ip=dhcp url –url http://url.com/path/to/DVD/files/

The LABEL line is an internal label for that entry. The MENU LABEL parameter is what is displayed to the user. I usually keep them the same for clarity’s sake, but you can set them to whatever you like. The KERNEL parameter tells PXE where to find the kernel to boot. In this case, it’s in the images/centos/x86_64/5.5 directory inside our /tftpboot root directory. Always remember that any time you reference a file in that directory, you treat it as if you are sitting inside that directory. In the menu’s case, you do NOT use a leading / to indicate you are at the root tftpboot directory.
The APPEND option is what gets passed to the kernel when it loads. You can pass any valid kernel parameters you wish to tweak how the kernel will boot. In this case, I have specified the side of the RAMDisk to create and where the base CentOS images is at. I’ve also specified that the installation should use DHCP to obtain IP address information. The url kernel parameter is designed to tell it where to find the remainder of the installation files, but at the moment it appears to ignore that option. I’ll post back when I get a working parameter to force network booting of the OS files.

Here are some of the useful links

http://wiki.centos.org/HowTos/PXE/PXE_Setup

http://docs.fedoraproject.org/en-US/Fedora/7/html/Installation_Guide/ap-pxe-server.html