PXE-boot server – dhcp & tftp server setup – Part 3/5

Status:

Previously we created a VM with installed OpenMediaVault 2.1. It is accessible via SSH and via web-gui. Now we will create a DHCP & TFTP server from it. Let’s start it.

 

Add network adapter to existing VM & setup network:

In first post you saw on schematic diagram that our Media Server had 2 ethernet interface. Now we will create it in our virtual environment:

Create host-only network in VirutalBox:

Create second ethernet interface for our VM:

Setup second ethernet interface on OS:

 – Reboot (init 6) is necessary after adding lines to configuration-file.

# Interface for our DHCP server
auto eth1
allow-hotplug eth1
iface eth1 inet static
        address 192.168.56.101
        netmask 255.255.255.0
        network 192.168.56.0
        broadcast 192.168.56.255

For reference you can check my “interfaces” configuration file here:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
allow-hotplug eth0
iface eth0 inet dhcp

# Interface for our DHCP server
auto eth1
allow-hotplug eth1

iface eth1 inet static
        address 192.168.56.101
        netmask 255.255.255.0
        network 192.168.56.0
        broadcast 192.168.56.255

Create PXE-test VM:

To test our dhcp & tftp server we will need a VM which will try to connect our previously connected, host-only network. As in future we will test windows PE image also, system-resources will adjust to make this possible. Please follow pictures:

Create VM:

 – Memory: If you will load some kind of diagnostic ISO, you need at least 2 x iso-image size + ~30% of iso-image size installed memory (ISO=400MB –> ~920MB of installed memory). If loaded ISO load application / OS which runs from memory, it is possible that you will need more than calculated memory.

Adjust VM:

Now we can leave in powered off state this VM, we will use it soon.

Install DHCP-server application:

In short about DHCP: This technology provide automatically an ip-address for connected devices on network. In everyday we saw it when connect to our router. Just to clarify: in our router also a DHCP-server application runs (minimal, targeted dhcp-server)! 

Install “isc-dhcp-server”, our DHCP-server application:

 – Install it: sudo apt-get install isc-dhcp-server

 – Declare where (which Ethernet interface) it will be listening: sudo nano /etc/default/isc-dhcp-server

INTERFACES="eth1"

By default it will be listening on all interface. In our case it is not as good, as on ETH0 our real network’s router also offer ip-address. +1 that absolutely un-needed to listen interface where we will not use PXE-boot mechanism.

For reference you can check my /etc/default/isc-dhcp-server configuration file here:

# Defaults for isc-dhcp-server initscript
# sourced by /etc/init.d/isc-dhcp-server
# installed at /etc/default/isc-dhcp-server by the maintainer scripts

#
# This is a POSIX shell fragment
#

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
#DHCPD_CONF=/etc/dhcp/dhcpd.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPD_PID=/var/run/dhcpd.pid

# Additional options to start dhcpd with.
#       Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
#OPTIONS=""

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="eth1"

 – Edit main-configuration file of isc-dhcp-server: sudo nano /etc/dhcp/dhcpd.conf

#uncomment "#uthoritative;" line --> uthoritative;
subnet 192.168.1.0 netmask 255.255.255.0 {
    #Good if DHCP server know about the other interface's network. Just declare it.
}

subnet 192.168.56.0 netmask 255.255.255.0 {
    range 192.168.56.200 192.168.56.220;	#It depends on you what size of range will be use for PXE
    option routers 192.168.56.101;
    option domain-name-servers 192.168.56.101;
    option domain-name "pxeboot.server";
    default-lease-time 300;
    max-lease-time 600;
    next-server 192.168.56.101;
    filename "grldr";				#PXE-booted machine will search for this file-name (grub4dos)
}

For reference you can check my /etc/dhcp/dhcpd.conf configuration file here:

#
# Sample configuration file for ISC dhcpd for Debian
#
#

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# option definitions common to all supported networks...
option domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org;

default-lease-time 600;
max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

subnet 192.168.1.0 netmask 255.255.255.0 {
    #Good if DHCP server know about the other interface's network. Just declare it.
}

subnet 192.168.56.0 netmask 255.255.255.0 {
    range 192.168.56.200 192.168.56.220;        #It depends on you what size of range will be use for PXE
    option routers 192.168.56.101;
    option domain-name-servers 192.168.56.101;
    option domain-name "pxeboot.server";
    default-lease-time 300;
    max-lease-time 600;
    next-server 192.168.56.101;
    filename "grldr";                           #PXE-booted machine will search for this file-name (grub4dos)
}

 – Start our configured dhcp-server: sudo /etc/init.d/isc-dhcp-server start

Now we have a configured, working DHCP-server which will provide ip-addresses for our PXE-boot clients. In case of your isc-dhcp-server couldn’t be started:

 – Check /etc/default/isc-dhcp-server file for syntax-error / miss-configuration.

 – Check /etc/dhcp/dhcpd.conf  file for syntax-error / miss-configuration.

 – Check /var/log/syslog file for messages from isc-dhcp. You can use the following command to check what is the problem when try to start isc-dhcp: sudo /etc/init.d/isc-dhcp-server start; tail -f  /var/log/syslog

Test our new Software DHCP-server:

 – Make sure, our “Media&PXE” VM is running. If yes, start to inspect dhcp log entrys: tail -f /var/log/syslog

 – Start “PXE-test” VM which try to boot from network. You need to get the following:

Jan 20 04:59:05 mediapxe dhcpd: DHCPDISCOVER from 08:00:27:eb:8b:50 via eth1
Jan 20 04:59:06 mediapxe dhcpd: DHCPOFFER on 192.168.56.200 to 08:00:27:eb:8b:50 via eth1
Jan 20 04:59:08 mediapxe dhcpd: DHCPREQUEST for 192.168.56.200 (192.168.56.101) from 08:00:27:eb:8b:50 via eth1
Jan 20 04:59:08 mediapxe dhcpd: DHCPACK on 192.168.56.200 to 08:00:27:eb:8b:50 via eth1

Now our dhcp-servers is working, it is redirect “PXE-test” VM to boot “grldr” file from FTP-server just until now we don’t have grldr file. So this response is expected.

Install TFTP-server application:

As we used OMV21 as source of our media & pxe-boot server, tftp software was installed by default. But if you need to install it, use the following command:

sudo apt-get install tftpd-hpa tftp-hpa

Please don’t left to add tftp-server as auto start application in case of server-reboot, with the following command:

update-rc.d tftpd-hpa enable

Configure TFTP-server: Configuration file is “/etc/default/tftpd-hpa”. Here is my configuration with short explanation.

# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"                    #User who can read & write.
TFTP_DIRECTORY="/srv/tftp"              #Folder where user can read & write. Files will read from here
TFTP_ADDRESS="192.168.56.101:69"        #Where tftp-sercer will listen for requests.
TFTP_OPTIONS="--secure -vv"             #Log-level adjust.

 – I adjusted the “TFTP_ADDRESS” & “TFTP_OPTIONS” to our needs. Address was adjusted to our ETH1 (this is used for PXE-network) address. For options I added logging-option to make tftp-server visible on “/var/log/syslog”. After you adjust your configuration file like my config-file, please restart tftp server: /etc/init.d/tftp-hpa restart

If you restart / start your PXE-test VM, you will get log-entry on your “media&pxe” VM:

Jan 20 10:32:40 mediapxe in.tftpd[4436]: RRQ from 192.168.56.200 filename grldr
Jan 20 10:32:40 mediapxe in.tftpd[4436]: sending NAK (1, File not found) to 192.168.56.200

You can see that requested file was not found (on /srv/tftp folder). So fix this problem, download missing (grub4dos) file with the following commands:

cd /srv/tftp/	#Stand to directory (declared on tftp-hpa's config-file)
mkdir source	#Create dircetory where we download source grub4dos.
cd source/	#Stand to it
wget http://dl.grub4dos.chenall.net/grub4dos-0.4.6a-2016-12-24.7z	#Download source, compressed file.
sudo apt-get install p7zip	#Install application to extract compressed-file.
7zr e grub4dos-0.4.6a-2016-12-24.7z		#Extract downloaded file.
cp grldr /srv/tftp/		#Copy file (need for boot). This file requested by pxe-client.

After these commands, your tftp-server’s folder must to be look like:

cd ..; ls -trha
root@mediapxe:/srv/tftp# ls -ltrha
total 324K
drwxr-xr-x 4 root root    4.0K Jan 13 13:48 ..
drwxr-xr-x 5 root root    4.0K Jan 20 11:40 source
-rw-r--r-- 1 root root    311K Jan 20 11:40 grldr
drwxr-xr-x 3 root nogroup 4.0K Jan 20 11:40 .

 

Test TFTP-server: Now we have DHCP server, TFTP-server, and file which can be booted by pxe-client. Let’s test it:

Start / restart PXE-test VM.

On VM-side you must to get the following:

On server-side (Media&PXE vm) /var/log/syslog entry while pxe-client VM boot:

Jan 20 12:11:10 mediapxe dhcpd: DHCPDISCOVER from 08:00:27:eb:8b:50 via eth1
Jan 20 12:11:11 mediapxe dhcpd: DHCPOFFER on 192.168.56.200 to 08:00:27:eb:8b:50 via eth1
Jan 20 12:11:13 mediapxe dhcpd: Wrote 1 leases to leases file.
Jan 20 12:11:13 mediapxe dhcpd: DHCPREQUEST for 192.168.56.200 (192.168.56.101) from 08:00:27:eb:8b:50 via eth1
Jan 20 12:11:13 mediapxe dhcpd: DHCPACK on 192.168.56.200 to 08:00:27:eb:8b:50 via eth1
Jan 20 12:11:13 mediapxe in.tftpd[5582]: RRQ from 192.168.56.200 filename grldr
Jan 20 12:11:14 mediapxe in.tftpd[5583]: RRQ from 192.168.56.200 filename grldr
Jan 20 12:11:14 mediapxe in.tftpd[5583]: tftp: client does not accept options
Jan 20 12:11:14 mediapxe in.tftpd[5584]: RRQ from 192.168.56.200 filename grldr
Jan 20 12:11:14 mediapxe in.tftpd[5585]: RRQ from 192.168.56.200 filename menu.lst
Jan 20 12:11:14 mediapxe in.tftpd[5585]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5586]: RRQ from 192.168.56.200 filename menu.lst/01-08-00-27-EB-8B-50
Jan 20 12:11:14 mediapxe in.tftpd[5586]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5587]: RRQ from 192.168.56.200 filename menu.lst/C0A838C8
Jan 20 12:11:14 mediapxe in.tftpd[5587]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5588]: RRQ from 192.168.56.200 filename menu.lst/C0A838C
Jan 20 12:11:14 mediapxe in.tftpd[5588]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5589]: RRQ from 192.168.56.200 filename menu.lst/C0A838
Jan 20 12:11:14 mediapxe in.tftpd[5589]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5590]: RRQ from 192.168.56.200 filename menu.lst/C0A83
Jan 20 12:11:14 mediapxe in.tftpd[5590]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5591]: RRQ from 192.168.56.200 filename menu.lst/C0A8
Jan 20 12:11:14 mediapxe in.tftpd[5591]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5592]: RRQ from 192.168.56.200 filename menu.lst/C0A
Jan 20 12:11:14 mediapxe in.tftpd[5592]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5593]: RRQ from 192.168.56.200 filename menu.lst/C0
Jan 20 12:11:14 mediapxe in.tftpd[5593]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5594]: RRQ from 192.168.56.200 filename menu.lst/C
Jan 20 12:11:14 mediapxe in.tftpd[5594]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5595]: RRQ from 192.168.56.200 filename menu.lst/default
Jan 20 12:11:14 mediapxe in.tftpd[5595]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5596]: RRQ from 192.168.56.200 filename boot/grub/menu.lst
Jan 20 12:11:14 mediapxe in.tftpd[5596]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5597]: RRQ from 192.168.56.200 filename grub/menu.lst
Jan 20 12:11:14 mediapxe in.tftpd[5597]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5598]: RRQ from 192.168.56.200 filename menu.lst
Jan 20 12:11:14 mediapxe in.tftpd[5598]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5599]: RRQ from 192.168.56.200 filename boot/grub/menu.lst
Jan 20 12:11:14 mediapxe in.tftpd[5599]: sending NAK (1, File not found) to 192.168.56.200
Jan 20 12:11:14 mediapxe in.tftpd[5600]: RRQ from 192.168.56.200 filename grub/menu.lst
Jan 20 12:11:14 mediapxe in.tftpd[5600]: sending NAK (1, File not found) to 192.168.56.200

Finalize settings, create missing files for complete boot: Now our PXE-client get IP-address from our dhcp-server and boot file served by our tftp-server, but just a minimal-BASH available at the moment. Now we will create a missing “menu.lst” file what will be interpreted by grub4dos (grldr) and give choosable options fror user on pxe-client. We will also test it with  bootable tool (memtest).

  – Download memtest image file & prepare it.

mkdir -p /srv/tftp/memtest #Create memtest foldder
cd /srv/tftp/memtest/ # Stand to created folder.
wget http://www.memtest.org/download/5.01/memtest86+-5.01.iso.zip #Download memtest iso image.
sudo apt-get install unzip #Install application which can extracted archived memtest iso image.
unzip memtest86+-5.01.iso.zip #Extratct memtest iso.zip.

 – Create & adjust “menu.lst”. Please create menu.lst (touch /srv/tftp/menu.lst) & fill up with the following content:

# display this heading
write (md)0x220+1 !BAT\necho -n -P:0000 $[0133]                    --- CH-E-MISTRY PXE-BOOT Created by Humikacp ---                                    \0
initscript (md)0x220+1

##################################################################################
title MemTest86+ \nMemory test tool
pxe keep
root (pd)/memtest/memtest86+-5.01.iso
map --mem (pd)/memtest/memtest86+-5.01.iso (0xff)
map --hook
root (0xff)
chainloader (0xff)
##################################################################################

 

Now our tftp (& dhcp) server is working fine, we can boot image(s) with grub4dos. If everything is working fine, with “PXE-test” VM you will get similar like this:

 

 

For this post, I used grub4dos as my boot manager, but not this is the only available tool for multi / pxe boot, you can use also syslinux. You just replace “grldr” file with yours (in dhcp-server configuration & physically).

On next post, we will create a winPE environment and append it to the our actual grub4dos menu.

If you faced with problem or you found a bug on post please let me know, leave a comment.

One thought on “PXE-boot server – dhcp & tftp server setup – Part 3/5

  1. Hi,
    I like this HowTo. It’s the best I have found so far.
    Iwanted to print this as pdf (for documentation purposes), but the whith of your pages is fixed. Also the whith of the source windows is fixed. Therefore the long lines are cut off and not readable as pdf-document.
    Greetinx

Leave a Reply