Never Ending Security

It starts all here

The Perfect Lab – PXE Server on Linux


The Preboot Execution Environment (PXE) is an industry standard client/server interface that allows networked computers that are not yet loaded with an operating system to be configured and booted remotely by an administrator. The PXE code is typically delivered with a new computer on a read-only memory chip or boot disk that allows the computer (a client) to communicate with the network server so that the client machine can be remotely configured and its operating system can be remotely booted. PXE provides three things:

  1. The Dynamic Host Configuration Protocol (DHCP), which allows the client to receive an IP address to gain access to the network servers.
  2. A set of application program interfaces (API) that are used by the client’s Basic Input/Output Operating System (BIOS) or a downloaded Network Bootstrap Program (NBP) that automates the booting of the operating system and other configuration steps.
  3. A standard method of initializing the PXE code in the PXE ROM chip or boot disk.

The PXE process consists of the client notifying the server that it uses PXE. If the server uses PXE, it sends the client a list of boot servers that contain the operating systems available. The client finds the boot server it needs and receives the name of the file to download. The client then downloads the file using Trivial File Transfer Protocol (Trivia File Transfer Protocol) and executes it, which loads the operating system. If a client is equipped with PXE and the server is not, the server ignores the PXE code preventing disruption in the DHCP and Bootstrap Protocol (BP) operations.


Why would you want to boot a PC from the network?

Having PXE Server opens the door to booting diskless workstations, eg: Internet Cafe PC’s, or if you regularly install tens or hundreds of PC’s, you can start the installer on all those machines at once without needing to have individual boot/install media for each machine. You can even use Linux PXE for starting Microsoft Windows network installers and tools.

Install DHCP & TFTP packages

sudo apt-get install dhcp3-server inetutils-inetd tftpd-hpa

DHCP Setup

Edit /etc/default/dhcp3-server, Ethernet interface for DHCP service


Edit /etc/dhcp3/dhcpd.conf‬ DHCP service configuration PXE specific configurations: filename & next-server

default-lease-time 600;
max-lease-time 7200;
subnet netmask {
    option subnet-mask;
    option routers;
    option broadcast-address;
    filename "pxelinux.0";

Setup a static IP for eth0 -

Start service

sudo /etc/init.d/dhcp3-server restart

Check status

netstat -lu


Proto Recv-Q Send-Q Local Address           Foreign Address         State      
udp        0      0 *:bootpc                *:*                                

TFTP Setup

Edit ‪/etc/inetd.conf, remove #<off># from the beginning of tftp line.

tftp    dgram   udp wait    root    /usr/sbin/in.tftpd  /usr/sbin/in.tftpd -s /var/lib/tftpboot

Enable boot service for inetd

sudo update-inetd --enable BOOT

Open UDP port 69 to allow clients in the network to connect to the TFTP server.

sudo ufw allow proto udp from to any port 69

Start service

sudo /etc/init.d/tftpd-hpa restart

Check status

netstat -lu


Proto Recv-Q Send-Q Local Address           Foreign Address         State 
udp        0      0 *:tftp                  *:*                          

PXE boot files setup

Your tftpboot should look like this:

 |-- pxelinux.0
 |-- pxelinux.cfg/
 |   `-- default
 `-- Ubuntu/
     |-- initrd.gz
     `-- vmlinuz

SYSLINUX is a boot loader for the Linux operating system. We can use it to display a menu during system boot. To proceed, install SYSLINUX.

sudo apt-get -y install syslinux

When the client boots, DHCP will provide it with the TFTP server and filename (pxelinux.0). In order to boot from the file, copy it to the TFTP boot folder.

sudo cp /usr/lib/syslinux/pxelinux.0 /var/lib/tftpboot  

The “vesamenu.c32” is used to display a graphical menu, so lets copy it from the syslinux folder to the TFTP boot folder

sudo cp /usr/lib/syslinux/vesamenu.c32 /var/lib/tftpboot/

SYSLINUX will read its configuration from the “pxelinux.cfg” directory.

sudo mkdir -p  /var/lib/tftpboot/pxelinux.cfg/

Create the PXE configuration file

sudo nano /var/lib/tftpboot/pxelinux.cfg/pxe.conf   

Add the following content

MENU COLOR border               30;44      #ffffffff #00000000 std

Its possible to customise the menu based on the MAC address and IP address of the client. In this case, we’ll create a default menu for all TFTP clients.

sudo nano /var/lib/tftpboot/pxelinux.cfg/default

Add the following content. It creates an Ubuntu menu, allowing us to add more Linux distributions to TFTP.

DEFAULT vesamenu.c32 
MENU INCLUDE pxelinux.cfg/pxe.conf
LABEL BootLocal
        localboot 0
        TEXT HELP
        Boot to local hard disk
        LABEL Previous
        MENU LABEL Previous Menu
        TEXT HELP
        Return to previous menu
        MENU EXIT
        MENU INCLUDE Ubuntu/

Create the folder where we’ll store Ubuntu menus.

sudo mkdir /var/lib/tftpboot/Ubuntu/

Create the Ubuntu Menu. The file is being referenced by “/var/lib/tftpboot/pxelinux.cfg/default”.

sudo nano /var/lib/tftpboot/Ubuntu/

Add the following content. Notice the TFTP server IP Addresses as well as the paths the kernel and preseed.cfg is loaded from. Change it to suit your environment.

        MENU LABEL Ubuntu 14.04 (64-bit)
        kernel tftp://
        append auto=true priority=critical vga=788 initrd=tftp:// locale=en_US.UTF-8 kbd-chooser/method=us netcfg/choose_interface=auto url=tftp://
        TEXT HELP
        Boot the Ubuntu 14.04 64-bit DVD

Create directories to store the media. If you recall, we exported an NFS share /srv/install.

sudo mkdir -p /var/lib/tftpboot/Ubuntu/14.04/amd64

Download Ubuntu Server 14.04 ISO


Mount the ISO and copy all the files to the TFTP folder.

sudo mkdir /mnt/loop
sudo mount -o loop -t iso9660 ~/ubuntu-14.04-server-amd64.iso /mnt/loop
sudo cp -R /mnt/loop/* /var/lib/tftpboot/Ubuntu/14.04/amd64
sudo cp -R /mnt/loop/.disk /var/lib/tftpboot/Ubuntu/14.04/amd64
sudo umount /mnt/loop

Create a preseed.cfg to automate the Ubuntu 14.04 installation. The following file was copied from the Ubuntu Site.

wget -O /var/lib/tftpboot/preseed.cfg

It is also possible to make separate directories within tftp root folder.

You can use Netboot as template, where pxelinux.cfg/default includes display_ubuntu/menu.cfg which by itself includes display_ubuntu/text.cfg which contains the main menu of Ubuntu boot:

$ tree -L 2
├── bios_flash.img
├── clonezilla
│   ├── filesystem.squashfs
│   ├── initrd.img
│   ├── parameters.txt
│   └── vmlinuz
├── display_ubuntu
│   ├── adtext.cfg
│   ├── f10.txt
│   ├── f1.txt
│   ├── f2.txt
│   ├── f3.txt
│   ├── f4.txt
│   ├── f5.txt
│   ├── f6.txt
│   ├── f7.txt
│   ├── f8.txt
│   ├── f9.txt
│   ├── menu.cfg
│   ├── po4a.cfg
│   ├── prompt.cfg
│   ├── splash0.png
│   ├── splash1.png
│   ├── splash.png
│   ├── splash.xcf
│   ├── stdmenu.cfg
│   ├── text.cfg
│   └── vesamenu.c32
├── etc
│   └── boot.conf
├── FDSTD.144
├── hello.boot
├── memdisk
├── Notes.txt
├── openbsd
│   ├── bsd
│   ├──
│   ├── bsd.rd
│   └── pxeboot.0
├── pxelinux.0
├── pxelinux.cfg
│   ├── default
│   └── default.backup
├── ubuntu_14.04
│   ├── initrd.gz
│   └── vmlinuz
├── ubuntu_mini.iso

Example: of pxelinux.cfg/default

include display_ubuntu/menu.cfg
default display_ubuntu/vesamenu.c32
prompt 0
timeout 0

Example: display_ubuntu/menu.cfg

menu hshift 7
menu width 65
menu margin 5

menu title GNU/Linux Rescue Collection

include display_ubuntu/stdmenu.cfg
include display_ubuntu/text.cfg

menu begin advanced
    menu title Advanced options
    label mainmenu
        menu label ^Back..
        menu exit
    include display_ubuntu/stdmenu.cfg
    include display_ubuntu/adtext.cfg
menu end

label help
    menu label ^Help
    config display_ubuntu/prompt.cfg

Example: display_ubuntu/text.cfg

DEFAULT ubuntu_14.04_install

LABEL test_kernel
    MENU LABEL ^Test Kernel
    KERNEL hello.boot

LABEL clonezilla
    MENU LABEL ^CloneZilla
    KERNEL clonezilla/vmlinuz
    APPEND initrd=clonezilla/initrd.img boot=live union=aufs noswap noprompt vga=788 ocs_live_keymap=NONE ocs_lang=en_US.UTF-8 fetch=tftp://

LABEL mini_ubuntu
    MENU LABEL Mini-Ubuntu
    KERNEL memdisk
    APPEND initrd=ubuntu_mini.iso

LABEL freedos
Testing boot from Floppy IMG.
    KERNEL memdisk
    APPEND initrd=FDSTD.144

LABEL bios_flash
    MENU LABEL Bios Flash
    KERNEL memdisk
    APPEND initrd=bios_flash.img

LABEL openbsd
    KERNEL openbsd/pxeboot.0

LABEL ubuntu_14.04_install
        menu label ^Ubuntu 14.04 net install
        kernel ubuntu_14.04/vmlinuz
        append vga=normal initrd=ubuntu_14.04/initrd.gz -- quiet

LABEL ubuntu_14.04_cli
        menu label Ubuntu 14.04 ^command-line net install
        kernel ubuntu_14.04/vmlinuz
        append tasks=standard pkgsel/language-pack-patterns= pkgsel/install-language-support=false vga=normal initrd=ubuntu_14.04/initrd.gz -- quiet

LABEL pxeserver2
        menu label Switch to 2nd PXE server...

Over http ?

For that we need a webserver: Install apache package

apt-get install apache2

Copying… Ubuntu files

Create an ubuntu directory under your freshly installed apache’s document root and copy all of the contents of the Ubuntu Alternate CD to that directory

mkdir /var/www/ubuntu
cp -r /media/cdrom/* /var/www/ubuntu/

Customising the install

There is a package called system-config-kickstart which is a GUI frontend to creating kickstart files. The kickstart file tells the installer where to get its packages from, what to install and a number of other useful settings.

This package does not have to be installed on your install server, it can be on a convenient Ubuntu desktop somewhere.

Create a custom ks.cfg with system-config-kickstart, be sure to specify HTTP under “Installation Method”. Provide the IP of you install server and make the HTTP Directory /ubuntu/ Save the file and copy it to your install server under /var/www/html/

A very minimalist ks.cfg file which only uses the installation files on the install server and asks for all other questions might look like this

url --url

Use your ks.cfg

In order for your network Ubuntu install to use your kickstart file, you have to tell it where to find it.

Edit /var/lib/tftpboot/pxelinux.cfg/default and add ks=http://<installserver>/ks.cfg to the append line. It should then look something like this (note that the append line is one line)

label linux
       kernel ubuntu-installer/i386/linux
       append ks= vga=normal initrd=ubuntu-installer/i386/initrd.gz ramdisk_size=16432 root=/dev/rd/0 rw  --

In Jaunty the default file has been broken up into includes. The append line can be found in /ubuntu-installer/i386/boot-screens/text.cfg

label install
        menu label ^Install (from my http server)
        menu default
        kernel ubuntu-installer/i386/linux
        append ks= vga=normal initrd=ubuntu-installer/i386/initrd.gz -- quiet

 Make Your PXE Server really useful with Clonezilla

Besides Clonezilla Live CD and Live USB, Clonezilla Live can be put on a PXE server so that a client can be booted via network to use Clonezilla live. This is how:

  1. Prepare a PXE server. We assume the pxelinux config file is /tftpboot/nbi_img/pxelinux.cfg/default, and the image files are in /tftpboot/nbi_img/.
  2. Download Clonezilla live zip file (You have to use Clonezilla live 1.2.0-25 or later), and unzip the required files (vmlinuz, initrd.img, and filesystem.squashfs in dir live) to /tftpboot/nbi_img/. You can make it by something like: “unzip -j clonezilla-live-*.zip live/vmlinuz live/initrd.img live/filesystem.squashfs -d /tftpboot/nbi_img/” (Replace clonezilla-live-*.zip with the file name you just downloaded).
  3. Edit your PXElinux config file /tftpboot/nbi_img/pxelinux.cfg/default, and append the following:
    label Clonezilla-live
    MENU LABEL Clonezilla Live (Ramdisk)
    KERNEL vmlinuz
    APPEND initrd=initrd.img boot=live config noswap nolocales edd=on nomodeset ocs_live_run="ocs-live-general" ocs_live_extra_param="" keyboard-layouts="" ocs_live_batch="no" locales="" vga=788 nosplash noprompt fetch=tftp://$serverIP/filesystem.squashfs


    1. Replace $serverIP with your IP address of tftp (DRBL) server.
    2. Remember to check kernel, initrd file names and boot parameters in syslinux/syslinux.cfg from the zip file, copy them to here. It might be different from here, say vmlinuz path maybe different.
      For more info about pxelinux, you can refere to here.
    3. Here we do not put “ip=frommedia” in the boot parameters because the /etc/resolv.conf get in live-initramfs won’t exist in the system after initramfs is done.
    4. “fetch” also supports http or ftp, if you want to use http or ftp instead of tftp, you have to put the file filesystem.squashfs in your http or ftp server and the corresponding path.
    5. If you want to do unattended clone, you can assign clonezilla live parameters (ocs_live_run, ocs_live_extra_param, ocs_live_keymap, ocs_live_batch and ocs_lang) in kernel parameters. For example, you can use:
      append initrd=initrd.img boot=live union=aufs noswap noprompt vga=788 keyboard-layouts=NONE locales=en_US.UTF-8 fetch=tftp://$serverIP/filesystem.squashfs

      in the above example to assign your PXE client to use default keymap (US) and English environment. For more info about those parameters, you can refer to CloneZilla live documentation

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s