gPXE boot config

What we want?

More, more and more.

In fact we want a simple setup, maintainable, clever, and that can do all what we want (and if possible all what we will want). :p

For the lazy, the static config is enough, but for the other the http will be handy.

Static config

See the syslinux site for the manual (lol, not so easy).

There a some magic words, like include( i use it very much).

First, the defaults parameters.

default.include

# Default boot option to use
DEFAULT menu.c32
# Prompt user for selection
PROMPT 0
# Menu Configuration
MENU WIDTH 80
MENU MARGIN 10
MENU PASSWORDMARGIN 3
MENU ROWS 12
MENU TABMSGROW 18
MENU CMDLINEROW 18
MENU ENDROW 24
MENU PASSWORDROW 11
MENU TIMEOUTROW 20
# Return to Main Menu
LABEL Main
   MENU DEFAULT
   MENU LABEL ^Main Menu
   KERNEL menu.c32
   APPEND default

And after, the defaults menus.

default

MENU TITLE Main Menu
#
# Menus
#
# gPXE
LABEL Linux 
  MENU LABEL ^1 - Linux
  KERNEL menu.c32
  APPEND http://bootserver.my.zone.tld/pxelinux.cfg/linux.conf
#
LABEL Windows
  MENU LABEL ^2 - Windows
  KERNEL menu.c32
  APPEND http://bootserver.my.zone.tld/pxelinux.cfg/windows.conf
#
LABEL Net Booting
  MENU LABEL ^3 - Net Booting
  KERNEL menu.c32
  APPEND http://bootserver.my.zone.tld/pxelinux.cfg/netboot.conf
#
LABEL Support
  MENU LABEL ^0 - Support
  MENU PASSWD passwd
  KERNEL menu.c32
  APPEND http://bootserver.my.zone.tld/pxelinux.cfg/support.conf
#

And in every section Linux, Windows, net booting and Support we include the terminal setup. i give the support config, because this is a stand syslinux config setup, and i will explain the other in another part (see below).

support.conf

INCLUDE default.include
MENU TITLE Boot gPXE {again}
#
#
LABEL Hardware Dectection Tool
  MENU LABEL ^Hardware Dectection Tool
  KERNEL http://bootserver.my.zone.tld/pxelinux.cfg/bin/hdt.c32
  APPEND modules=bin/modules.pcimap pciids=bin/pci.ids
#
LABEL Memtest
  MENU LABEL Memory tester
  KERNEL http://bootserver.my.zone.tld/pxelinux.cfg/bin/memtest
#
LABEL Freedos
  MENU LABEL Freedos
  KERNEL http://bootserver.my.zone.tld/pxelinux.cfg/bin/memdisk
  APPEND harddisk=1 initrd=kernels/freedos.img.gz
#
LABEL Gpxe
  MENU LABEL gPXE
  KERNEL http://bootserver.my.zone.tld/pxelinux.cfg/bin/gpxelinux.0
#

Dynamic config

So in this part, i will describe how to create a setup for booting from the gPXE boot, the gPXE script load a boot file from the web server. This web page is dynamic and forge the syslinux boot file. this boot file can depend on the network addrress, the mac address, or a database.

split config

This is an exemple og a split config.

2 networks( 10.0.0.0/24 and 10.0.1.0/24), and we want a classic config on the first network and serial config on the other

boot.php

<?php
    header ( "Content-type: text/plain" );
    $Net0 = "10.0.0" ;
    $Net1 = "10.0.1" ;
   
    // which Subnet
    list($A,$B,$C,$D)    =    explode(".",$_SERVER["REMOTE_ADDR"]);
     $subnet = $A .".". $B .".". $C;
    if ( $subnet == $Net1 ) {
        include("default.serialinclude");
    } else {
        include("default.include");
    }
    include("default");
?>

And the default.include is the one above, and default.serialinclude is below.

default.serialinclude

SERIAL 0 19200
CONSOLE 1
INCLUDE default.include

So it s exactly the same config but if the internet device is on the 10.0.1.0/24 network, we boot on the serial console, very usefull if we haven t any display on this computer.

More capabilities

Just about web possibilites

What we want

Now i want to talk about dynamic syslinux bootfile generator. Actualy i use php, but you can also use perl, ruby, python or more. It s juste a web service for serving a syslinux bootfile.

We can generate a syslinux with menu, or an autoboot syslinux with only 1 boot choice.

What we have

gPXE can send some information when we use it for booting.

  • ${net0/mac} -> mac address of first interface
  • ${hostname} -> hostname given by dhcp server
  • ${uuid} -> the uuid of the system (uniq id)

with the mac address or the uuid we have a uniq id of the system, and we can use it for setting the boot file. i choose the mac address because we already have it for the dhcp server parameters, but it s not too difficulte top create a database with uuid as a primary key.

Store config

We can store the data in sql database like ldap, postgres, mysql or just a txt file. How we store the config is not very important.

I will show how we can use it with very few informations, we now hostaname (given by dhcp server), mac address (send by gPXE) and uuid (not very usefull here). you must have in mind the files of the previous configuration(default.include, default, support.conf, linux.conf, windows.conf, netboot.conf).

This an exemple of a tree with bootfiles.

boot file tree

.
|-- bin
|   |-- gpxelinux.0
|   |-- hdt.c32
|   |-- memdisk
|   `-- memtest
|-- boot.php
|-- knownhosts
|   |-- 00:02:e3:14:48:ef
|   |-- 00:1c:23:2d:91:88
|   |-- 52:54:00:34:d8:0c
|   `-- 52:54:00:54:73:e4
`-- pxelinux.cfg
    |-- default
    |-- default.include
    |-- linux.conf
    |-- netboot.conf
    |-- support.conf
    `-- windows.conf

The dhcp server server boot.php as boot filename (remember the dhcp.conf config file)

filename "http://bootserver.my.zone.tld/pxelinux.cfg/boot.php";

The boot.php file is a not like the other files, it s a chain loading boot file sequence.

boot.php

<?php
header ( "Content-type: text/plain" );
echo "#!gpxe\n";
echo "imgfree\n";
echo "chain ".
"http://".$_SERVER["SERVER_NAME"].
dirname( $_SERVER["REQUEST_URI"] ).
"/gpxe.php?mac=\${net0/mac}\n";
?>

And now with the gpxe.php we can choose the right config file.

We store specific config file with the mac address as filename, so if we have one of this mac address, we boot with this file. It s very simple and clever.

gpxe.php

<?php
header ( "Content-type: text/plain" );
$macaddress = $_REQUEST["mac"];
if ( is_file("knownhosts/".$macaddress)) {
    include("knownhosts/".$macaddress);
} else {
    include("pxelinux.cfg/default.include");
    include("pxelinux.cfg/default");
}
?>

In the macaddress filen we have the complete syslinux boot config file, we send a "static" boot config.

clone or migrate config

As we can see above, we can use symlinks in the knowhost sub tree.

Advanced boot tree

.
|-- bin
|   |-- gpxelinux.0
|   |-- hdt.c32
|   |-- memdisk
|   `-- memtest
|-- boot.php
|-- knownhost
|   |-- 00:02:e3:14:48:ef
|   |-- 00:12:b3:41:18:ef -> Boot_From_Disk
|   |-- 00:1c:23:2d:91:88 -> Install_Windows_Server_2008R2_From_Scratch
|   |-- 52:54:00:34:d8:0c -> Install_Linux_From_Scratch
|   |-- 52:54:00:54:73:e4 -> Install_Windows7_From_Scratch
|   |-- Boot_From_Disk
|   |-- Install_Linux_From_Scratch
|   |-- Install_Windows7_From_Scratch
|   `-- Install_Windows_Server_2008R2_From_Scratch
`-- pxelinux.cfg
    |-- default
    |-- default.include
    |-- linux.conf
    |-- netboot.conf
    |-- support.conf
    `-- windows.conf

The symlinks can share config for many mac addresses, and for cloning a boot config, we create a new symlinks. After booting the computer and setting up, we can send a request to the server for removing this symlink and targeting to boot from hard drive(it s a security if we boot from pxe).

journalisation

I have 2 words:

  • subversion
  • git

We must use a versioning system. If we use database or ldap, we must have backup.