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 CentOS 5.5 x86_64 as the host system. All packages can be found in the official CentOS 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 CentOS 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 /data/tftpboot
disable = yes
per_source = 11
cps = 100 2
flags = IPv4
}
Once that is configured, restart xinetd to force the changes to take effect.
/sbin/service xinetd restart
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/lib/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.
allow booting; allow bootp; option option-128 code 128 = string; option option-129 code 129 = text; next-server xxx.xxx.xxx.xxx; 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
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 LOCALBOOT 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.
If you wish to make an entry that uses a kickstart file, it would look like this:
LABEL CentOS 5.5 x86_64 KS MENU LABEL CentOS 5.5 x86_64 KS KERNEL images/centos/x86_64/5.5/vmlinuz APPEND ks=http://url.com/path/to/kickstart.cfg initrd=images/centos/x86_64/5.5/initrd.img ramdisk_size=100000 ksdevice=eth0 ip=dhcp url --url http://url.com/path/to/DVD/files/
The main difference here is that there are two additional kernel parameters. The ks parameter tells the kernel where to find the kickstart file. It must be located on an FTP, HTTP, or NFS server that is accessible from the client. You cannot specify a file within the /tftpboot directory because the CentOS installation itself is what will read the file. The client PXE system that has booted is completely unaware of the PXE environment it booted from. The other additional paremeter is the ksdevice parameter. This tells the client which ethernet device to use to attempt to find the kickstart file. On multi-NIC systems, each NIC could be attached to a separate network segment, and that could cause problems if you don’t tell it which NIC to search on.
Multi-Tier Menus
The second menu type is multi-tiered. There is a main menu and one or more submenus that allow you to categorize different systems to boot to. For this, we will still create a default menu file in additional to one or more other menu files. To start with, lets take a look at the default menu.
default menu.c32 prompt 0 timeout 300 ONTIMEOUT local MENU TITLE Main Menu LABEL local MENU LABEL Boot local hard drive LOCALBOOT 0
This part of the menu is identical. However, the rest looks very different.
LABEL x86_64 Servers MENU LABEL x86_64 Servers KERNEL menu.c32 APPEND pxelinux.cfg/x86_64_Servers
Basically, this tells PXE to use the same kernel that it’s currently using (menu.c32) and to load the menu file located at pxelinux.cfg/x86_64_Servers. What you would do next would be create a menu file called x86_64_Servers. It will look very similar to the main menu without much of the default options at the top.
MENU TITLE x86_64 Server Menu LABEL Main Menu MENU LABEL Main Menu KERNEL menu.c32 APPEND pxelinux.cfg/default 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/ LABEL CentOS 5.5 x86_64 KS MENU LABEL CentOS 5.5 x86_64 KS KERNEL images/centos/x86_64/5.5/vmlinuz APPEND ks=http://url.com/path/to/kickstart.cfg initrd=images/centos/x86_64/5.5/initrd.img ramdisk_size=100000 ksdevice=eth0 ip=dhcp url --url http://url.com/path/to/DVD/files/
As you can see, I also added a Main Menu option to return to the default menu. This is not necessary, but it provides some more convenient navigation capabilities to the end user. Once this is all saved, you should be able to connect your client to your network with any PXE compliant network card and boot to your remote system!
Dnsmasq and Linux Home Routers
As promised, I’m including a small section about using dnsmasq on your custom Linux home router. I use Tomato at home, and I have it set up to perform the same task as my DHCP configuration earlier in this tutorial. Go to your dnsmasq custom configuration page in your router’s online configuration site or the dnsmasq configuration file on the router’s file system. In Tomato 1.25, this is located at Advanced -> DHCP/DNS. Under the custom configuration section, type the following:
dhcp-boot=pxelinux.0,,xxx.xxx.xxx.xxx
Once again, we specify the pxelinux.0 file as if we were in the /tftpboot directory. The commas separate parameters for the dhcp-boot command. In between the two commas, you can place the hostname of the PXE server, but it is not necessary. The xxx.xxx.xxx.xxx is the IP address of the PXE boot server. Once you save the configuration and restart the built-in DHCP server (which happens automatically when you save in Tomato), your new clients will all receive the correct information for booting to a PXE server.
Additional Systems
I will post some additional systems here as I get more and more working. I will highlight custom paths that you will need to change. Some parts of paths will need to stay fixed as they are contained on the ISO of that Linux distribution.
Clonezilla 1.2.5-17
LABEL Clonezilla MENU LABEL Clonezilla KERNEL images/clonezilla/live/vmlinuz APPEND initrd=images/clonezilla/live/initrd.img boot=live union=aufs noswap noprompt vga=788 fetch=http://url.com/path/to/live/filesystem.squashfs
OpenSUSE 11.2
LABEL OpenSUSE 11.2 MENU LABEL OpenSUSE 11.2 KERNEL images/opensuse/linux APPEND initrd=images/opensuse/initrd splash=silent vga=0x314 showopts install=http://url.com/path/to/mounted/dvd/iso/
#1 by Jeroen on June 29, 2010 - 1:56 pm
Quote
Hi,
Shouldn’t line 9 of /etc/xinetd.d/tftp file read “disable = no”?
Regards,
Jeroen.
#2 by Andy on June 29, 2010 - 2:41 pm
Quote
It is worded a little weird, but the code block is showing what the line looks like prior to editing it to say ‘no’. You are correct that it will read ‘no’ after you have made your changes.
#3 by Jeroen on June 29, 2010 - 2:47 pm
Quote
Hi again,
Not trying to bug you or anything, but you clearly write, just before the block code that “After you’re done, it should look like this”. Which, in my humble opinion, means that what follows should be the contents of the changed file. But then again, I am not a native English speaker so maybe it’s just my lack of contextual comprehension then.
Regards,
Jeroen.
#4 by Mike on June 29, 2010 - 2:50 pm
Quote
That’s my mistake. Andy got the intention behind it, but I did word it poorly. I had it set up one way originally and then changed the code block later on. I apparently forgot the text in front of it when I made that change. I will fix it when I get a chance. Thanks for the heads up, Jeroen.
#5 by Ricardo on July 14, 2010 - 1:01 pm
Quote
I currently do my PXE/kickstart installs using NFS instead of http.
If I want to try http, what further configuration is needed for http/apache. The only thing mentioned in this document is installing the http rpm. help please.
Regards,
Ricardo
#6 by Mike on July 14, 2010 - 5:17 pm
Quote
There really isn’t much to configure with HTTP. About the only thing I changed was to turn on directory listing for the ISO virtual domain so that I could view the files and directories. You don’t need this, however, because the kernel will know what files it’s looking for already. You need to mount the ISO file via the loop device exactly like you would for NFS, but you just need to make sure you do it in a directory that is accessible via your web server. That’s really it.
Pingback: How to create a CentOS 5 VMware virtual machine using PXEBOOT and Kickstart | Blog by Dave Rose
#7 by rashid on October 4, 2010 - 7:22 am
Quote
I am getting below error:
Unable to read group information from repositories this is a problem with the generation of your installation tree.
Kindly help me to sort out this problem.
Regards,
Rashid
#8 by Mike on October 4, 2010 - 10:47 am
Quote
That looks like a yum problem, not a problem with a PXE server. If you have a customized or personal yum repository, you should try fixing the repository or disabling it temporarily while you install software for this process. If not, use the ‘clean all’ and ‘makecache’ options in yum to clean out the metadata. It’s possible that something is broken there.
(Hint: if you set up your own repomd repository with the createrepo command, try using the -g switch.)
#9 by Steve on February 23, 2011 - 2:21 pm
Quote
Thank you for an excellently documented process! One note to add, in case the firewall is enabled. Add the following two lines to your firewall iptables rules (from the command line or via the System -> Administration -> Security Levels and Firewall -> Firewall Options -> Other ports interface):
ACCEPT udp anywhere anywhere state NEW udp dpt:tftp
ACCEPT tcp anywhere anywhere state NEW tcp dpt:tftp
(this opens port 69 to both udp and tcp traffic, so the tftp transfer of PXE boot files can happen).
#10 by Mike on February 23, 2011 - 2:29 pm
Quote
Excellent point. I hadn’t been working on a firewalled server, so I never had to worry about that. Thanks!
#11 by Otto on March 2, 2011 - 5:26 am
Quote
Hi,
Very nice tutorial.
I was trying to install CentOS 5.5 this way. But I’m getting the following error message “Unknown boot installation ‘http://xxxxx’ ignoring command”.
It’s like PXE is considering the URL as a command.
Here is the APPEND command: APPEND initrd=images/centos5/x86_64/5.5/initrd.img ramdisk_size=100000 ip=dhcp lang=en_US keymap=fr url –url http://mirror.facebook.net/centos/5/os/x86_64
Any idea ?
#12 by Mike on March 18, 2011 - 5:22 pm
Quote
Try adding an addition – to the url switch. See if it works like this:
APPEND initrd=images/centos5/x86_64/5.5/initrd.img ramdisk_size=100000 ip=dhcp lang=en_US keymap=fr url –-url http://mirror.facebook.net/centos/5/os/x86_64
#13 by Harry on July 25, 2011 - 5:16 am
Quote
i did all this but my DHCP server doesn’t start.
Any ideas why?
#14 by Mike on August 4, 2011 - 9:19 am
Quote
Do you have any errors in the logs? There are a ton of reasons why it could be failing to start, so it’s hard to narrow it down. If you could post the relevant part of the DHCP logs, I might be able to help.
Pingback: Setting PXE Boot Server di CentOS 5.5 | Renjong
Pingback: » Setting up a PXE Netboot Server for Network Installations of GNU/Linux ASPENSMONSTER
#15 by sujith on December 7, 2011 - 10:08 pm
Quote
Nice tutorial. I have setup pxe remote install setup using this tutorial. But I didn’t used the URL option in menu. My APPEND line is
append vga=normal initrd=images/centos/i386/5.4/initrd.img ramdisk_size=32768
It works for me. I don’t know how the remote machine got installation files without this option.
#16 by nick on December 17, 2011 - 11:57 pm
Quote
For specifying the URL for the rest of the installation files for cent0s try: method=http://path_to_CD_contents/
if method does not work try repo=http://path_to_CD_contents/
#17 by Marcelo Ariatti on March 16, 2012 - 3:07 pm
Quote
Thank’s man! Great job!
It worked flawlessly here!
Trackback: svensk pølseret