Configure kickstart server | PXE boot server | RHEL/CentOS 8

In this article we will setup a PXE boot server using RHEL/CentOS 8 ISO Image. To perform network based installation we will also configure kickstart server. Below are the brief list of steps involved to setup PXE boot server

  • Setup installation repo using Red Hat 8.1 ISO
  • Setup PXE boot server environment
  • Configure kickstart server to automate the installation
  • Configure DHCP Server to assign IP Address
  • Configure TFTP server to transfer PXE files
  • Configure NFS server to share installation repo and kickstart file


Lab Environment

I have created two Virtual Machines using Oracle VirtualBox installed on my Linux server. We will perform VirtualBox PXE boot installation where first VM will be used to setup pxe boot kickstart server while we perform network based installation on the second VM.


Below are the server specifications:

Hostname centos-8 centos8-4
IP Address NIC1: eth0 - DHCP
NIC2: eth1 - DHCP
Purpose PXE Boot Server VirtualBox PXE Boot Client


Step 1: Setup Installation Repo

We will setup PXE boot server to install RHEL 8 using network based installation. Create a new directory where we will place all the RHEL image files

[root@centos-8 pxelinux]# mkdir /images

I have virtually mounted RHEL 8 ISO to my virtual machine, to access this ISO I will mount the image to /mnt

[root@centos-8 ~]# mount /dev/sr0 /mnt
mount: /mnt: WARNING: device write-protected, mounted read-only.

Copy all the files from the RHEL 8 ISO Image to /images directory

[root@centos-8 ~]# cp -apr /mnt/* /images/

Note that here copying of hidden file will be ignored and .treeinfo file which is required for a valid installation source so manually copy these hidden files.

[root@centos-8 ~]# cp -apr /mnt/.discinfo /mnt/.treeinfo /images/

Verify the repository content

[root@centos-8 ~]# ls -al /images/
total 92
drwxr-xr-x   7 root root  4096 Apr 19 20:33 .
dr-xr-xr-x. 33 root root  4096 Apr 19 19:57 ..
dr-xr-xr-x   4 root root  4096 Oct 15  2019 AppStream
dr-xr-xr-x   4 root root  4096 Oct 15  2019 BaseOS
-r--r--r--   1 root root    60 Apr 19 20:33 .discinfo
dr-xr-xr-x   3 root root  4096 Oct 15  2019 EFI
-r--r--r--   1 root root  8266 Oct 15  2019 EULA
-r--r--r--   1 root root  1455 Oct 15  2019 extra_files.json
-r--r--r--   1 root root 18092 Oct 15  2019 GPL
dr-xr-xr-x   3 root root  4096 Oct 15  2019 images
dr-xr-xr-x   2 root root  4096 Oct 15  2019 isolinux
-r--r--r--   1 root root   103 Oct 15  2019 media.repo
-r--r--r--   1 root root  1669 Oct 15  2019 RPM-GPG-KEY-redhat-beta
-r--r--r--   1 root root  5134 Oct 15  2019 RPM-GPG-KEY-redhat-release
-r--r--r--   1 root root  1796 Oct 15  2019 TRANS.TBL
-r--r--r--   1 root root  1566 Apr 19 20:33 .treeinfo


Step 2: Install and Configure TFTP Server

Next we will configure TFTP server to transfer PXE image files to the client for network based installation.

Install tftp-server and xinetd using dnf


On RHEL system you must have an active subscription to RHN or you can configure a local offline repository using which "yum" package manager can install the provided rpm and it's dependencies.
[root@centos-8 ~]# dnf install tftp-server xinetd -y

Earlier with RHEL/CentOS 7, tftp service was managed by xinetd. Although even with RHEL/CentOS 7 we had an option to disable xinetd and fork TFTP process using systemd.


You can fork TFTP process either by xinetd or by systemd but not both. For more details check: TFTP service is getting inactive automatically in RHEL7

In this example we will fork TFTP process using systemd.
The tftp-server rpm installation will create /usr/lib/systemd/system/tftp.service unit file

Below is the content of this service unit file

[root@centos-8 pxelinux.cfg]# cat /usr/lib/systemd/system/tftp.service
Description=Tftp Server

ExecStart=/usr/sbin/in.tftpd -s /var/lib/tftpboot

  • From ExecStart we can see that the default location for TFTP server is /var/lib/tftpboot.
  • So we must place all the PXE boot server files under this location
  • You can also use any other directory but then you will have to modify this service unit file to use the custom path for tftp service

Next start the tftp service and enable it to start automatically post reboot

[root@centos-8 pxelinux.cfg]# systemctl enable tftp.service --now
Created symlink /etc/systemd/system/ → /usr/lib/systemd/system/tftp.socket.
  • TFTP service uses to tftp.socket to serve TFTP requests
  • So it is possible that if there are no incoming TFTP requests then the tftp service will become inactive on it's own
  • But as soon as a TFTP request goes to tftp.socket, the socket will start tftp.service and serve the request

Check the status of tftp.socket

[root@centos-8 ~]# systemctl status tftp.socket
● tftp.socket - Tftp Server Activation Socket
   Loaded: loaded (/usr/lib/systemd/system/tftp.socket; enabled; vendor preset: disabled)
   Active: active (listening) since Sun 2020-04-19 19:32:40 IST; 7h ago
   Listen: [::]:69 (Datagram)
   CGroup: /system.slice/tftp.socket

Apr 19 19:32:40 systemd[1]: Listening on Tftp Server Activation Socket.


Step 3: Setup PXE boot server

  • Next to perform PXE network based installation, we must configure PXE boot server.
  • We will need Linux boot images to boot the RHEL 8 OS with minimal configuration
  • This is performed using initrd and vmlinuz. I hope you are familiar with the Linux boot process which covers this part
  • Before the actual kernel loads, initrd and vmlinuz will load the necessary drivers from the memory to boot up the server

We will create another directory "pxelinux" under /var/lib/tftpboot to store PXE images

[root@centos-8 ~]# mkdir -p /var/lib/tftpboot/pxelinux



Step 3.1: Extract syslinux-tftpboot

With RHEL/CentOS 8, the pxelinux file is part of syslinux-tftpboot rpm so we will copy this file from our RHEL 8 ISO to a temporary location

[root@centos-8 ~]# cp /mnt/BaseOS/Packages/syslinux-tftpboot-6.04-4.el8.noarch.rpm /tmp/

Next extract the syslinux-tftpboot rpm. We will not use all the contents of this rpm and only required files

[root@centos-8 ~]# cd /tmp/
[root@centos-8 tmp]# rpm2cpio syslinux-tftpboot-6.04-4.el8.noarch.rpm | cpio -idm

The above command will extract syslinux-tftpboot under /tmp.

Next we will copy pxelinux.0 and ldlinux.c32 to /var/lib/tftpboot/pxelinux/ required to setup PXE boot server

[root@centos-8 tmp]# cp /tmp/tftpboot/ldlinux.c32 /var/lib/tftpboot/pxelinux/
[root@centos-8 tmp]# cp /tmp/tftpboot/pxelinux.0 /var/lib/tftpboot/pxelinux/


Step 3.2: Copy initrd and vmlinuz

We also need other PXE boot images which will be under isolinux folder of the RHEL/CentOS 8 Image.
Since we had copied the ISO content to /images, we will copy required PXE boot images from /images/isolinux to /var/lib/tftpboot/pxelinux/

[root@centos-8 tmp]# cp /images/isolinux/initrd.img /var/lib/tftpboot/pxelinux/
[root@centos-8 tmp]# cp /images/isolinux/vmlinuz /var/lib/tftpboot/pxelinux/


List all the PXE boot image files:

[root@centos-8 tmp]# ls -l /var/lib/tftpboot/pxelinux/
total 58880
-r--r--r-- 1 root root 62248424 Apr 19 19:14 initrd.img
-rw-r--r-- 1 root root   116096 Apr 19 19:47 ldlinux.c32
-rw-r--r-- 1 root root    42821 Apr 19 19:01 pxelinux.0
-r-xr-xr-x 1 root root  8106848 Apr 19 19:14 vmlinuz

Next navigate to pxelinux folder

[root@centos-8 tmp]# cd /var/lib/tftpboot/pxelinux


Step 3.3: Create Boot Menu

  • We will create PXE boot server which can be used to install multiple images so we will create a boot menu.
  • This boot menu will be displayed to initiate the installation for user input.
  • Create a new file boot.msg under /var/lib/tftpboot/pxelinux
  • You can use any name for this file as per your requirement.

Since I intent to configure Kickstart server only for single Image, I have only created two menu entries.

[root@centos-8 pxelinux]# cat boot.msg
Welcome to the installation of "My Linux Server" !
Red Hat Enterprise linux 8.1 (x86_64)
Version: 1.0
Architecture: x86_64

To start the installation enter :
    '1', '2' and press .

Available boot options:

  1 - Install Red Hat Enterprise Linux 8.1
  2 - Boot from Harddisk (this is default)

Have a lot of fun...


Step 3.4: Create PXE configuration file

Once the client retrieves and executes pxelinux.0, it is hard-coded to look for a file from the pxelinux.cfg/ sub directory relative to where pxelinux.0 was found. In large deployments we create individual PXE configuration file per node.

After attempting the file as specified in the DHCP or hardcoded options, PXELINUX will probe the following paths, prefixed with "pxelinux.cfg/", under the initial Working Directory. The naming syntax of these PXE configuration file is very important. 

  • First, it will look for file based on the client UUID, if provided by the PXE stack.
    Note that some BIOSes do not have a valid UUID, and it might end up reporting something like all 1's.
    This value is represented in the standard UUID format using lowercase hexadecimal digits, e.g. "b8945908-d6a6-41a9-611d-74a6ab80b83d".
  • Next it will look for a file named after the MAC address (using its ARP "htype" code), in the form 01-xx-xx-xx-xx-xx-xx all in lowercase hexadecimal with dash separators.
    For example, in this example my client's NIC MAC Address is 08:00:27:83:1e:2a so my PXE configuration file will be 01-08-00-27-83-1e-2a
  • Next, it will look for a file named by the IP address as provided by the DHCP server in UPPERCASE letters.
    The IP address is looked up in hexadecimal format.
    You can use printf to get the hexadecimal format of an IP Address, for example to get the hexadecimal value of
# printf "%02x%02x%02x%02xn" 10 10 10 12

You can read more at PXELINUX - Syslinux Wiki

  • Since I am not assigning any static IP Address, I cannot use the hexadecimal format file. Although I can use MAC address based file.
  • If both MAC Address and hexadecimal format file are not found under pxelinux.cfg then the installer will look for "default" file
  • In this example I will use default file but I have also verified the PXE network installation using MAC based file 01-08-00-27-83-1e-2a

We will create a new directory pxelinux.cfg

[root@centos-8 ~]# mkdir /var/lib/tftpboot/pxelinux/pxelinux.cfg

Create the PXE configuration file /var/lib/tftpboot/pxelinux/pxelinux.cfg/default

[root@centos-8 ~]# cat /var/lib/tftpboot/pxelinux/pxelinux.cfg/default
timeout 600
display boot.msg
default 1
prompt  1

label 1
  menu label ^Install Red Hat Enterprise Linux 8
  kernel vmlinuz
  append initrd=initrd.img showopts ks=nfs: ip=dhcp net.ifnames=0 biosdevname=0

label 2
  menu label Boot from ^local drive
  localboot 0x80

menu end
  • I have created two labels based on our Boot Menu
    • label 1: This will be used to install Red Hat Linux 8
    • label 2: To continue booting from hard disk
  • I have provided label 2 as the default option.
  • So if a user input is not provided until the timeout value i.e. 600, the installer will choose label 2 and continue to boot from hard disk
  • I will use NFS server to configure kickstart server to perform network based installation.
  • My kickstart file will be available under /ks directory which we will create in next steps
  • ip=dhcp is optional, as the client will anyhow get the IP address from the DHCP server.
  • net.ifnames and biosdevname are also optional, as I do not wish to use consistent network device naming scheme for my client node.

Make sure the PXE configuration files have read permission for "other" users

[root@centos-8 ~]# ls -l /var/lib/tftpboot/pxelinux/
total 68880
-rw-r--r-- 1 root root      325 Apr 19 19:10 boot.msg
-r--r--r-- 1 root root 62248424 Apr 19 19:14 initrd.img
-rw-r--r-- 1 root root   116096 Apr 19 19:47 ldlinux.c32
-rw-r--r-- 1 root root    42821 Apr 19 19:01 pxelinux.0
drwxr-xr-x 2 root root     4096 Apr 20 01:47 pxelinux.cfg
-r-xr-xr-x 1 root root  8106848 Apr 19 19:14 vmlinuz

[root@centos-8 ~]# ls -l /var/lib/tftpboot/pxelinux/pxelinux.cfg/default
-rw-r--r-- 1 root root 307 Apr 20 01:47 /var/lib/tftpboot/pxelinux/pxelinux.cfg/default


Step 4: Install and Configure DHCP server

You can also use DNSMASQ server to assign IP address but we will use DHCP server in this example to perform network based installation in Linux.

[root@centos-8 pxelinux.cfg]# dnf install dhcp-server -y

Below is a very basic example of DHCP server configuration

  • The PXE file name is defined with filename. Since the tftp is configured to use /var/lib/tftp as default location we have provided pxelinux/pxelinux.0
  • next-server defines the IP address of the TFTP server
  • range is used to assign IP address for DHCP requests
[root@centos-8 pxelinux.cfg]# cat /etc/dhcp/dhcpd.conf

allow bootp;
allow booting;
max-lease-time 1200;
default-lease-time 900;
log-facility local7;

option ip-forwarding    false;
option mask-supplier    false;

   subnet netmask {

       option  routers;
       option  domain-name-servers;
       filename "pxelinux/pxelinux.0";

Enable and start the dhcpd service

[root@centos-8 pxelinux.cfg]# systemctl enable dhcpd --now
Created symlink /etc/systemd/system/ → /usr/lib/systemd/system/dhcpd.service.

Make sure the dhcpd service status is active and running

[root@centos-8 ~]# systemctl status dhcpd
● dhcpd.service - DHCPv4 Server Daemon
   Loaded: loaded (/usr/lib/systemd/system/dhcpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2020-04-19 19:45:45 IST; 6h ago
     Docs: man:dhcpd(8)
 Main PID: 30897 (dhcpd)
   Status: "Dispatching packets..."
    Tasks: 1 (limit: 26213)
   Memory: 5.1M
   CGroup: /system.slice/dhcpd.service
           └─30897 /usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid


Step 5: Configure kickstart server

  • To configure kickstart server we would need a kickstart file to automate the installation.
  • With every Red Hat and CentOS installation, a default kickstart file is created under home folder of root user i.e. /root/anaconda-ks.cfg
  • This anaconda kickstart file contains the values used to install your server
  • We can use this anaconda file to create our kickstart configuration file and configure kickstart server
  • You can also use online kickstart generator tool provided by Red Hat. Although I am not very fond of this tool has very limited options while a kickstart supports many more features
  • In this example I will use the default anaconda.cfg template to configure kickstart server

Create /ks directory where we will store our kickstart file

[root@centos-8 pxelinux.cfg]# mkdir /ks

Copy the content of anaconda-ks.cfg and rename to /ks/kickstart.conf

[root@centos-8 pxelinux.cfg]# cp /root/anaconda-ks.cfg /ks/kickstart.conf

Make sure the kickstart file is readable by other users while ks directory has read and execute permission for others.

[root@centos-8 ~]# ls -l /ks/kickstart.conf
-rw-r--r-- 1 root root 1688 Apr 19 20:55 /ks/kickstart.conf


Step 5.1: Sample kickstart configuration file

Below is my sample kickstart configuration file. I prefer to perform text based network installation (Since the day I started using Linux, I sort of have got addicted to CLI rather than graphics)

I won't be able to explain the entire content of kickstart file in this article as it would be too long, I will plan to write another article with detailed description of all the values from kickstart file.

[root@centos-8 pxelinux]# cat /ks/kickstart.conf

ignoredisk --only-use=sda

# Partition clearing information
clearpart --all

# Use text install

# Create APPStream Repo
repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream

# Use NFS Repo
nfs --server= --dir=/images/

# Keyboard layouts
keyboard --vckeymap=us --xlayouts='us'

# System language
lang en_US.UTF-8

# Network information
network  --bootproto=dhcp --device=eth0 --ipv6=ignore --activate
network  --bootproto=dhcp --device=eth1 --onboot=off --ipv6=ignore --activate

# Root password
rootpw --iscrypted $6$w7El/FYx9mbTG6x9$Te.Yg6dq0TsQwGpdSjeDGSw4J9ZBAkLXzT9ODMV7I7lHvX3n5.9PCS4jIkS2GbVLZOpVRLvrua3wwbwA.cfWX.

# Run the Setup Agent on first boot
firstboot --enable

# Do not configure the X Window System

# System services
services --enabled="chronyd"

# System timezone
timezone Asia/Kolkata --isUtc

# Reboot after installation completes

# Disk partitioning information
autopart --type=plain --fstype=ext4

# Packages to be installed


%addon com_redhat_kdump --enable --reserve-mb='auto'

pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty


Step 6: Install and Configure NFS

I have already written a separate article with detailed description and steps to install and configure both NFSv4 and NFSv3 server. Hence I will be very brief here:

Install nfs-utils rpm required to configure NFS

[root@centos-8 ~]# dnf -y install nfs-utils

Below are the directories I plan to share for my Linux kickstart server.
Here /ks contains the kickstart configuration file
and /images contains the RHEL 8 ISO content for installation

[root@centos-8 ~]# cat /etc/exports
/ks     *(ro,sync,no_root_squash)
/images *(ro,sync,no_root_squash)

Re-export the shares

[root@centos-8 ~]# exportfs -r

Print the available shares

[root@centos-8 ~]# exportfs -v
/ks             (sync,wdelay,hide,no_subtree_check,sec=sys,ro,secure,no_root_squash,no_all_squash)
/images         (sync,wdelay,hide,no_subtree_check,sec=sys,ro,secure,no_root_squash,no_all_squash)

Enable and start the nfs-server.service. Here since we are using NFSV4, we have not started or installed rpcbind.
You can read more at: Step-by-Step Guide to install and configure NFSv4 and NFSv3 server & client in RHEL/CentOS 7/8

[root@centos-8 ~]# systemctl enable nfs-server --now

Make sure nfs-server service up and running

[root@centos-8 ~]# systemctl status nfs-server
● nfs-server.service - NFS server and services
   Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled; vendor preset: disabled)
  Drop-In: /run/systemd/generator/nfs-server.service.d
   Active: active (exited) since Sun 2020-04-19 19:49:17 IST; 6h ago
  Process: 31119 ExecStopPost=/usr/sbin/exportfs -f (code=exited, status=0/SUCCESS)
  Process: 31117 ExecStopPost=/usr/sbin/exportfs -au (code=exited, status=0/SUCCESS)
  Process: 31116 ExecStop=/usr/sbin/rpc.nfsd 0 (code=exited, status=0/SUCCESS)
  Process: 31144 ExecStart=/bin/sh -c if systemctl -q is-active gssproxy; then systemctl reload gssproxy ; fi (code=exited, status=0/SUCCESS)
  Process: 31132 ExecStart=/usr/sbin/rpc.nfsd (code=exited, status=0/SUCCESS)
  Process: 31131 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=0/SUCCESS)
 Main PID: 31144 (code=exited, status=0/SUCCESS)

Apr 19 19:49:17 systemd[1]: Starting NFS server and services...
Apr 19 19:49:17 systemd[1]: Started NFS server and services.

We are all done with the steps to setup PXE boot server to perform network based installation in Linux. Using kickstart as the mode of installation we also have configure kickstart server on the same node.

Next we will perform VirtualBox PXE Boot Installation on the Client Virtual Machine


Step 7: Perform VirtualBox PXE Boot Installation

I will share the steps to perform VirtualBox PXE Boot installation as I am not using physical hardware here. "Power ON" the client virtual machine and press "F12" to select boot device

Configure kickstart server | PXE boot server | RHEL/CentOS 8


You will get a list of Boot device options to boot from, I will press 'l' to boot from LAN

Configure kickstart server | PXE boot server | RHEL/CentOS 8


In the next screen, DHCP request is sent using the first NIC card. The client will send a broadcast request to all the servers around in the network looking for an IP Address.
As soon as the broadcast request reaches our PXE boot server (also configured as DHCP server), it will release an IP address
You can see below set of messages on your PXE boot server. I am using journalctl to view the system messages

Apr 20 01:49:14 dhcpd[30897]: DHCPOFFER on to 08:00:27:83:1e:2a via eth1
Apr 20 01:49:15 dhcpd[30897]: DHCPDISCOVER from 08:00:27:83:1e:2a via eth1
Apr 20 01:49:15 dhcpd[30897]: DHCPOFFER on to 08:00:27:83:1e:2a via eth1
Apr 20 01:49:17 dhcpd[30897]: Wrote 2 leases to leases file.
Apr 20 01:49:17 dhcpd[30897]: DHCPREQUEST for ( from 08:00:27:83:1e:2a via eth1
Apr 20 01:49:17 dhcpd[30897]: DHCPACK on to 08:00:27:83:1e:2a via eth1

Configure kickstart server | PXE boot server | RHEL/CentOS 8


Once the client gets the IP Address, next it will search of PXE boot files using TFTP.
At this stage you should see below logs in /var/log/messages on the PXE boot Server (also used as TFTP boot server)

Apr 20 01:49:17 systemd[1]: Started Tftp Server.
Apr 20 01:49:17 in.tftpd[19710]: Client ::ffff: finished pxelinux/pxelinux.0
Apr 20 01:49:17 in.tftpd[19711]: Client ::ffff: finished pxelinux/ldlinux.c32
Apr 20 01:49:17 in.tftpd[19722]: Client ::ffff: finished pxelinux/pxelinux.cfg/default
Apr 20 01:49:17 in.tftpd[19723]: Client ::ffff: finished pxelinux/boot.msg
Apr 20 01:49:30 in.tftpd[19732]: Client ::ffff: finished pxelinux/vmlinuz
Apr 20 01:49:36 in.tftpd[19734]: Client ::ffff: finished pxelinux/initrd.img

Configure kickstart server | PXE boot server | RHEL/CentOS 8


if everything is correct, you should get the BOOT MENU which you had created using boot.msg file.

As soon as you press "1", the network based installation would start using kickstart configuration file. Here is a screenshot of my client virtual machine after successful installation.

Configure kickstart server | PXE boot server | RHEL/CentOS 8


Lastly I hope the steps from the article to configure kickstart server and PXE boot server on Linux was helpful. So, let me know your suggestions and feedback using the comment section.

Perform Network Based Installation using PXE Boot Server


Related Searches: network based installation of linux, configure kickstart server linux step step, centos netboot, kickstart installation linux, kickstart linux tutorial, fedora anaconda kickstart, red hat network install, virtualbox PXE boot installation

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

49 thoughts on “Configure kickstart server | PXE boot server | RHEL/CentOS 8”

  1. Thank you for sharing these detailed steps. I am however having a problem with my VM guest booting with PXE. I have VM box version 6.1 the host operating system is win 10. I installed in one VM Red hat Enterprise 8.3 which is also my PXE, TFTP, DHCP, and HTTP server. I am trying to PXE boot from another VM and having the following error message. No clue how to resolve the issue. I would appreciate it if you could shed some light.

    PXE-T02 : option negotiaton failue (file not found or inaccessible?)
    PXE -E3C TFTP Error - Accesss Violation
    PXE -MOF Exiting Intel PXE ROM
    FATAL : NO bootable medium found! system halted

    Thank you

    • with the error it mostly looks like the mounted repo is not accessible. Can you share the progress status from the logs
      You can execute journalctl -f on the TFTP/DHCP server and the share the logs. I need to check if atleast TFTP was success
      Also please share the content of PXE configuration file.

      • journalctl -f log:

        Dec 01 12:26:05 localhost.localdomain systemd[1]: Starting dnf makecache...
        Dec 01 12:26:09 localhost.localdomain dnf[3159]: Updating Subscription Management repositories.
        Dec 01 12:26:12 localhost.localdomain dnf[3159]: Metadata cache refreshed recently.
        Dec 01 12:26:12 localhost.localdomain systemd[1]: dnf-makecache.service: Succeeded.
        Dec 01 12:26:12 localhost.localdomain systemd[1]: Started dnf makecache.
        Dec 01 12:28:24 localhost.localdomain org.gnome.Shell.desktop[2362]: libinput error: client bug: timer event3 debounce: offset negative (-284ms)
        Dec 01 12:28:24 localhost.localdomain org.gnome.Shell.desktop[2362]: libinput error: client bug: timer event3 debounce short: offset negative (-297ms)
        Dec 01 12:31:05 localhost.localdomain systemd[1]: Starting Cleanup of Temporary Directories...
        Dec 01 12:31:06 localhost.localdomain systemd[1]: systemd-tmpfiles-clean.service: Succeeded.
        Dec 01 12:31:06 localhost.localdomain systemd[1]: Started Cleanup of Temporary Directories.
        Dec 01 12:31:30 localhost.localdomain systemd[1]: tftp-server.service: Succeeded.

        PXE config:

        -rwxrwxrwx 1 root root 308 Nov 30 17:29 /var/lib/tftpboot/pxelinux/pxelinux.cfg/default

        – cat /var/lib/tftpboot/pxelinux/pxelinux.cfg/default

        timeout 600
        display boot.msg
        default 1
        prompt  1
        label 1
          menu label ^Install  Linux 7.8
          kernel vmlinuz
          append initrd=initrd.img showopts ks= ip=dhcp net.ifnames=0 biosdevname=0
        label 2
          menu label Boot from ^local drive
          localboot 0x80
        menu end
        • Thanks for sharing the logs, I was looking for logs of the TFTP something similar to what I have shared in Step 7.
          Do you see the TFTP files initrd.img, vmlinuz getting downloaded on the console?
          If yes, then we need to check the media content
          I assume you have copied the content of RHEL/CentOS DVD in some path? All the copied files and directories should be world readable
          if the media is mounted over NFS, try to mount it locally using

          # mount /your/repo /mnt

          Disable firewalld/iptabled/nftables for debug purpose
          Set SELinux to permissive mode using “setenforce 0”

          PS: I see in your default file, you are using “Install Linux 7.8” and this tutorial is for RHEL/CentOS 8, for RHEL/CentOS 7 you can refer to

          • Thanks! I tried the other solution on how to configure PXE for RHEL -7. I also tried with the firewall turned off. It still gives the same error message. Decided to rebuild a fresh new VM PXE server and reconfigure everything from the beginning and yet no avail 🙁 …. I think it has something to do with the settings of my Oracle VM box networking. I set up both of my VM networking settings to NAT. I am reading mixed reviews about the network configuration settings on the internet. The documentation itself on the VM page ( is not clear. I am completely puzzled! not sure if you could shed some light on this…if not, appreciate your time for trying to help.

    • Use the following command to generate hashed password

      python -c 'import crypt,getpass;pw=getpass.getpass();print(crypt.crypt(pw) if (pw==getpass.getpass("Confirm: ")) else exit())'
  2. Hi There,

    First of all i would like to say that your tutorial is awesome.
    the way you explain the steps for each part of the installation is very informative.

    I’d like to consult with you regarding an issue I’m having…

    I configured Centos 8 as my Kickstart server, and i’m trying to deploy Redhat 8.4 Enterprise.
    I followed all your step, and it seems that i’m so close to success but i’m trying to understand what is my point of failure.

    I double checked the settings.
    I disabled the Firewall.
    I validated thee Share you specify are shared accordingly.
    I checked that all the services are up and running (NFS,DHCP,TFTP, etc…).

  3. Continuing my session…

    Here is my Kickstart file:

    ignoredisk --only-use=sda
    # autopart --type=lvm
    # Partition clearing information
    clearpart --all
    # clearpart --none --initlabel
    # Use graphical install
    # Use text install
      GNU nano 2.9.8                                                                             kickstart.conf
    %addon com_redhat_kdump --enable --reserve-mb='auto'
    pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
    pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
    pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
    # Use CDROM installation media
    # Create APPStream Repo
    repo --name="AppStream" --baseurl=file:///run/install/repo/Appstream
    #USE NFS Repo
    nfs --server= --dir /images/
    # Keyboard layouts
    keyboard --vckeymap=us --xlayouts='us'
    # System language
    # Network information
    network  --bootproto=dhcp --device=enp0s3 --ipv6=auto --activate
    network  --hostname=PXE-SERVER
    #repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream
    # Root password
    rootpw --iscrypted $6$dovEtvfFOZN6M/e4$72hrwkHaaovmp09n7Qgu5PsFE4pTmjnzEiXZie9Hf3LVzMzPuxeh1.QeVBOaDbrkYYISVUQNfh.vV7EiVlWwh/
    # X Window System configuration information
    xconfig  --startxonboot
    # Run the Setup Agent on first boot
     firstboot --enable
    # System services
    services --enabled="chronyd"
    # System timezone
    timezone Asia/Jerusalem --isUtc --nontp
    user --groups=wheel --name=nahum --password=$6$SfTXFqaJuy3epxit$27ytbaWytItkBCEci8fM4Ed85gGBiqIpnRwI7reO72Lk5xSVC.Ops2qFEyq32NZof2Qp4SsjpmLVpkj3vD/... --iscrypted --gecos="NahumE"
    %addon com_redhat_kdump --enable --reserve-mb='auto'
    pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
    pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
    pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty

    Hope to hear from you soon.

    • Do you get any specific error message when monitoring with “journalctl -f” on the server side while the PXE is in progress?
      As you said your server is CentOS 8 while you are trying to install RHEL 8, so in such case all the PXE related files should be from RHEL 8 ISO. I hope this is taken care and you are not using files from CentOS8? specially the ones covered in Step 3 of this article.
      Also at what stage does the PXE fails? i.e. does the first step passes where TFTP client will fetch the IP from the DHCP server and load initrd and other files?

      • Hi,

        Actually I don’t see any specific error message regarding the error, or maybe you’ll be kind to tell me the syntax to view the errors.
        I’ll configured this Lab as a testing to learn more about provisioning new servers, so yes, by mistake I mounted the RedHat ISO, instead of the Centos.

        I think for a starting point, i’ll delete the the RHEL ISO files, and copy the Centos ISO.
        further more, regarding your last question, the PXE fails when it reaches the point of using the NFS and i’m getting an error that the NFS can not be found. although the syntax is the same as in the kickstart file you have on this tutorial.

        • So the problem is most likely with your NFS server. If it reaches till that state means TFTP and DHCP are working properly I assume.

          To check if your NFS server is accessible, try to mount /images on your NFS server itself (or it would be good if you have any other Linux node)

          # mount -t nfs /mnt

          If this command is successful, paste the content of /mnt here for further analysis

          # ls -al /mnt

          Also can you please share the logs by following this step. On your Kickstart server execute

          # journalctl -f

          Then trigger the PXE of client node, all the logs created till the stage of failure in the above command output. Please send it to me in a text file to

          • Hi,

            Here is the result for the commands you’ve asked me to type:

            [nahum@PXE-SERVER ~]$  mount -t nfs /mnt
            mount: only root can use "--types" option
            [nahum@PXE-SERVER ~]$ su root
            [root@PXE-SERVER nahum]#  mount -t nfs /mnt
            [root@PXE-SERVER nahum]# ls -al /mnt
            total 16
            drwxr-xr-x.  7 root  root   147 Jun 10 10:02 .
            dr-xr-xr-x. 20 root  root   282 Jun 10 10:47 ..
            dr-xr-xr-x.  4 nahum nahum   38 Jan  3  2020 AppStream
            dr-xr-xr-x.  4 nahum nahum   38 Jan  3  2020 BaseOS
            -r--r--r--.  1 nahum nahum   44 Jan  3  2020 .discinfo
            dr-xr-xr-x.  3 nahum nahum   18 Jan  3  2020 EFI
            dr-xr-xr-x.  3 nahum nahum   76 Jan  3  2020 images
            dr-xr-xr-x.  2 nahum nahum  256 Jan  3  2020 isolinux
            -r--r--r--.  1 nahum nahum   87 Jan  3  2020 media.repo
            -r--r--r--.  1 nahum nahum  664 Jan  3  2020 TRANS.TBL

            -r–r–r–. 1 journal -f output: (this is only some of the logs, i didn’t know if you would likr to see

            Happy to announce that the deployments completed successfully. 🙂
            Thank you very much for your support, and the will to help.

            How do i configure a User and Password from the image so i can login to the machine after it’s up and running?
            and final question, do you have a tutorial on deploying Centos8/Redhat8 using HTTP?

            Take care, and best regards.

            • I am glad it all worked out so the command output is not required 🙂

              >>How do i configure a User and Password from the image so i can login to the machine after it’s up and running?
              Add this in your kickstart file which will enable root user and create user1 and user2

              # Add this to enable root user
              rootpw --iscrypted PASSWORD
              # To have a user with plain text format password
              user --name=user1 --groups=wheel --plaintext --password=abcd@123
              # To have a user with encrypted password
              user --name=user2 --groups=wheel --iscrypted --password=PASSWORD

              To generate encrypted password use:

              # python -c 'import crypt,getpass;pw=getpass.getpass();print(crypt.crypt(pw) if (pw==getpass.getpass("Confirm: ")) else exit())'

              and replace PASSWORD in the above field with the output from above command

              I had written an article on this with RHEL 6 long time back, although the steps to setup HTTP and FTP should still be valid for RHEL/CentOS 8(although haven’t tried it myself)

              Give it a try and let me know if you face any issues.

  4. Hai Again,
    Im getting a error stating. Warning: no suitable images

    mount.nfs: no route to host
    warning: couldnt mount nfs:nfsvers=3:192.168.x.x:/images

    can you please help me out

    • Yes this is only for Legacy BIOS. For UEFI below changes would be required:
      Adapt dhcpd.conf to support UEFI BIOS
      Create new grub.cfg file under /var/lib/tftpboot/linux-install (on RHEL INS) to define linuxefi and initrdefi
      Extract grubx64.efi and shim.efi from grub2-efi-x64 and shim-x64 rpms respectively and again place them inside /var/lib/tftpboot/linux-install

      I will try create an article for this.

  5. Hey. I have done for both bios and uefi and made required changes. UEFI is working fine . But for bios its not fetching kickstart file i guess. vmllinuz initrd is fetched. Its showing “failed to start : Failed to activates service ‘org.fedoraproject.Anaconda.Module.Storge’: timed out(service_start_timeout=600000ms)

    option pxelinux.magic code 208 = string;
    option pxelinux.configfile code 209 = text;
    option pxelinux.pathprefix code 210 = text;
    option pxelinux.reboottime code 211 = unsigned integer 32;
    option arch code 93 = unsigned integer 16;
    allow bootp;
    allow booting;
    subnet 192.x.x.x netmask 255.255.x.0 {
            option routers 192.x.x.x;
            range 192.x.x.x 192.x.x.x;
            class "pxeclients" {
                    match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
                    next-server 192.x.x.x;
                    if option arch = 00:07 {
                        filename "linux-install/grubx64.efi";
                     } else if option arch = 00:08 {
                         filename "linux-install/grubx64.efi";
                     } else if option arch = 00:09 {
                         filename "linux-install/grubx64.efi";
                     } else {
                         filename "pxelinux/pxelinux.0";

    Is it any architecture specification mistake?
    Please Help me out!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1

  6. Hi,
    This is nice but there is one issue. Even OS is installed and when server reboot after install it start process again.
    How can we fix this DHCP release issue?
    I set these in dhcpd.conf
    default-lease-time 600;
    max-lease-time 7200;

    • You can change the boot order of the clients once they are successfully installed. The default boot device should be harddisk instead of network so it won’t go for reinstall after reboot

  7. Hello
    My centos 8 hang on reach basic target system. I use freenas as tftp server and pfsense as dhcp server.
    Here is my ipxe config

    set base
    set iscsi-rootfs iscsi:
    sanhook --drive 0x80 ${iscsi-rootfs}
    prompt -k 0x197e -t 2000 Press F12 to install CentOS... || exit
    kernel initrd=initrd.img inst.repo=${base}

Leave a Comment