Configure IPv4 UEFI PXE Boot with Kickstart [RHEL/CentOS 8]


CentOS 8

In this tutorial I will share step by step instructions to configure UEFI PXE Boot using Kickstart. I have tested these steps on RHEL/CentOS 8 environment. We will perform the setup in the following order

 

Order of Performing UEFI PXE Boot with Kickstart

  1. Setup Installation Repo
  2. Install and Configure TFTP
  3. Install and Configure DHCP
  4. Install and Configure HTTP
  5. Prepare kickstart file
  6. Perform UEFI PXE Boot

 

Lab Environment

I have two physical hardware with support of UEFI BIOS. The first server is installed with CentOS 8 while we plan to UEFI PXE Boot the second server which also has UEFI BIOS. Here are my server details:

Hostname: server.example.com
Release: CentOS Linux release 8.2.2004 (Core)
IP Address: 192.151.6.151/26

 

Pre-requisite

  • You must have RHEL/CentOS 8 installed OS on a server. Now this server may or may not have UEFI BIOS.
  • If you are using RHEL 8 then you must have an active RHN subscription
  • If you are using CentOS 8 then you must have an active internet connection to download and install package. Although you may also configure offline repository if your server doesn't have active internet connection

 

Steps to configure UEFI PXE Boot Server using Kickstart

Step-1: Setup Installation Repository

First of all we would have to setup our installation repo which will be used for the installation over network. I have mounted the CentOS 8 ISO image on the server

~]# mount /dev/sr0 /mnt
mount: /mnt: WARNING: device write-protected, mounted read-only.

Next I will copy the content of this ISO to a local directory so that I don't have to rely on the ISO image. I will create a local directory:

~]# mkdir /image

Next copy all the files from the ISO to this directory

~]# cp -apr /mnt/* /images/

After copying all the files:

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

IMPORTANT NOTE:
It is important to copy .treeinfo and .discinfo from the image or else your installation is expected to fail. These are referred during the installation over the network using PXE to validate the integrity of the repository.

 

Step-2: Install and Configure TFTP Server

Next we would need a TFTP server to transfer the UEFI PXE Boot files required for installing the target nodes over network. Use the following command to install tftp packages:

~]# dnf install tftp-server xinetd -y

With later releases of RHEL/CentOS, we may not need xinetd as in previous releases the tftp was managed by xinetd. But now it is managed by systemd so you may choose to exclude it but I have kept it for legacy reasons.

Once the package is installed, you can check for the path of systemd unit file using following command:

  ~]# rpm -ql tftp-server | grep -E "service|socket"

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

Next you can check the content of the service unit file:

~]# cat /usr/lib/systemd/system/tftp.service

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

Here you see that by default the tftp service will search for TFTP files inside /var/lib/tftpboot. So we will place all our UEFI PXE Boot files under this location. If you plan to use a different path then you can modify this service file and execute following command to update your changes:

]# systemctl daemon-reload
]# systemctl restart tftp.service

Next enable and start this service to make sure the service is started automatically post reboot.

]# systemctl enable tftp.service --now
Created symlink /etc/systemd/system/sockets.target.wants/tftp.socket → /usr/lib/systemd/system/tftp.socket.

Check the status of the service to make sure it was started successfully

 ~]# systemctl status tftp.service

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

 

Step-3: Configure UEFI PXE Boot Server

Next to perform UEFI {XE Boot installation, we will need PXE boot files. Normally for Legacy BIOS PXE boot we needed pxelinux.0 and ldlinux.c32 part of syslinux-tftpboot rpm.

But for UEFI BIOS we need following files:

  • grubx64.efi provided by grub2-efi-x64 rpm
  • shimx64.efi provided by shim-x64 rpm
  • BOOTX64.EFI provided by shim-x64 rpm

You can copy the mentioned rpms from the image to some temporary location such as /tmp and extract the rpm to get the required files:

]# cp /image/BaseOS/Packages/grub2-efi-x64-2.02-81.el8.x86_64.rpm /tmp/

]# cp /image/BaseOS/Packages/shim-x64-15-11.el8.x86_64.rpm /tmp/

Next extract these rpms using rpm2cpio command.

]# cd /tmp

]# rpm2cpio shim-x64-15-11.el8.x86_64.rpm | cpio -idm

]# rpm2cpio grub2-efi-x64-2.02-81.el8.x86_64.rpm | cpio -idm

We will store all our PXE files inside /var/lib/tftpboot/pxelinux. Now if you recall, by default TFTP will look into /var/lib/tftpboot so we must handle the extra pxelinux directory while setting up our UEFI PXE Boot server.

]# mkdir /var/lib/tftpboot/pxelinux

Copy the PXE boot files from /tmp where we extracted the rpm to this location:

]# cp /tmp/boot/efi/EFI/BOOT/BOOTX64.EFI /var/lib/tftpboot/pxelinux/

]# cp /tmp/boot/efi/EFI/centos/shimx64.efi /var/lib/tftpboot/pxelinux/

]# cp /tmp/boot/efi/EFI/centos/grubx64.efi /var/lib/tftpboot/pxelinux/

Next we need initrd and vmlinuz file to load the Operating System until hard disk and other interfaces are detected. I hope you are familiar with the steps of Linux Boot Process. These files can again be copied from the image, so we will copy and place them also inside /var/lib/tftpboot/pxelinux/

]# cp /image/isolinux/vmlinuz /var/lib/tftpboot/pxelinux/

]# cp /image/isolinux/initrd.img /var/lib/tftpboot/pxelinux/

Following is the content of my /var/lib/tftpboot/pxelinux at this stage:

~]# ls -l /var/lib/tftpboot/pxelinux/
total 78460
-rwx------. 1 root root  1877384 Jan  2 11:02 ,
-rwxr-xr-x. 1 root root  1211224 Jan  2 11:00 BOOTX64.EFI
-rwxr-xr-x. 1 root root  1877384 Jan  2 11:02 grubx64.efi
-r--r--r--. 1 root root 65114456 Jan  2 11:01 initrd.img
-rwxr-xr-x. 1 root root  1211224 Jan  2 11:02 shimx64.efi
-r-xr-xr-x. 1 root root  8913656 Jan  1 22:17 vmlinuz

 

Step-4: Configure DHCP for UEFI PXE Boot

Next we need to install and configure DHCP to support UEFI PXE Boot installation.

]# dnf -y install dhcp-server

Next we need to configure our dhcp server configuration file available at /etc/dhcp/dhcpd.conf. Here is my sample DHCP configuration file:

# cat /etc/dhcp/dhcpd.conf
#
# DHCP Server Configuration file.
#   see /usr/share/doc/dhcp-server/dhcpd.conf.example
#   see dhcpd.conf(5) man page
#
non-authoritative;
allow bootp;
option space pxelinux;
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 architecture-type code 93 = unsigned integer 16;

subnet 192.151.6.128 netmask 255.255.255.192 {
        option routers 192.151.6.190;
        range 192.151.6.170 192.151.6.180;

        class "pxeclients" {
          match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
          next-server 192.151.6.151;
          filename "pxelinux/BOOTX64.EFI";
        }
}

I will not be able to explain the entire configuration file, you can check CONFIGURING A DHCPV4 SERVER for more information. Although let me explain at least the important part of this configuration file i.e. below subnet section:

subnet 192.151.6.128 netmask 255.255.255.192 {
        option routers 192.151.6.190;
        range 192.151.6.170 192.151.6.180;

        class "pxeclients" {
          match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
          next-server 192.151.6.151;
          filename "pxelinux/BOOTX64.EFI";
        }
}

Here we have basically defined our subnet and netmask value. You can get this using different linux commands such as:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.151.6.190   0.0.0.0         UG    100    0        0 eno49
192.151.6.128   0.0.0.0         255.255.255.192 U     100    0        0 eno49
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

Here eno49 is our primary interface which has 192.151.6.128 as the subnet and 255.255.255.192 as the netmask value. The option routers contain the gateway of your server IP, which we can again get using following command:

 ~]# ip route
default via 192.151.6.190 dev eno49 proto static metric 100
192.151.6.128/26 dev eno49 proto kernel scope link src 192.151.6.151 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown

Here 192.151.6.190 is our default gateway which will act as a router for all incoming DHCP request.

Next under the class section we have defined next-server as the IP address of our Kickstart server i.e. localhost and filename contains the path of BOOTX64.EFI which will be used to perform the UEFI PXE Boot over the network.

We have defined a range between 192.151.6.170 and 192.151.6.180 to assign the IP address to our destination nodes which will be installed over the network. This range must be free and must not be in use by any other server.

Next enable and start the DHCP server service:

# systemctl enable dhcpd --now
Created symlink /etc/systemd/system/multi-user.target.wants/dhcpd.service → /usr/lib/systemd/system/dhcpd.service.

Check the status of the service to make sure it has started successfully:

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

 

Step-5: Configure Kickstart file for automated installation

Next we will create our kickstart file to have an un-attended automated installation. Now I have already explained different syntax and parameters used in kickstart file so I will not repeat the same here.

By default, when we install CentOS or RHEL server, we will have /root/anaconda.cfg file available which will contain the parameters used for the current installation. You can always take this file as your base and further modify it based on your requirement.

I will create a new directory to store our kickstart file for the UEFI PXE Boot purpose:

~]# mkdir /ks

~]# cp /root/anaconda-ks.cfg /ks/kickstart.conf

Make sure the kickstart.conf file is readable for all users:

# ls -l /ks/kickstart.conf
-rw-r--r--. 1 root root 1608 Nov 28 15:09 /ks/kickstart.conf

Here is my sample kickstart configuration file:

~]# cat /ks/kickstart.conf
#version=RHEL8
ignoredisk --only-use=sda,sdb
autopart --type=lvm

# Partition clearing information
clearpart --all --initlabel --drives=sda,sdb

# Use graphical install
graphical

# Use CDROM installation media
cdrom

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

# System language
lang en_US.UTF-8

# Network information
network  --bootproto=dhcp  --onboot=off --ipv6=auto
network  --hostname=server.example.com

# Create AppStream repo
repo --name="AppStream" --baseurl=http:///run/install/repo/AppStream

# Root password
rootpw --iscrypted $6$tGzXiAuBPTVcSiLX$4YD9A43gq2QJ7r5TqtL8uCwtQQWRON.CDYNkRkEx2vcsnrA5Jbv44jvZUyhS28VrKr0aU8/E8csTDZcb.VYUY.

# 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/Kolkata --isUtc
user --groups=wheel --name=deepak --password=$6$.TNszXKGs9V0flRV$J.1piXFKbXJHHH9dkZdIfWfoUdWkfWAgz5ZNHdoN42VudL.1rehBONmkEZv/nRyyWUDt3puHJIlAhIYRFGB7y. --iscrypted --gecos="deepak"

%packages
@^minimal-environment

%end

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

%end

%anaconda
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
%end

 

Step-6: Configure HTTP Server

Now we also need a service to host our image repository, we can use FTP or HTTP or NFS to host our image repository which we created in Step-1 of this tutorial. In my previous example where I had setup kickstart server using Legacy BIOS, I had used NFS so this time I decided to use HTTP server.

~]# dnf -y install httpd

Next we will configure Virtual Hosting to host our image repo path. I have created a new file ks-server.conf under /etc/httpd/conf.d/ with the following content:

<VirtualHost 192.151.6.151:80>
    ServerAdmin root@server1.example.com
    DocumentRoot /
    ServerName server.example.com
    ErrorLog logs/ks-server.example.com-error_log
    CustomLog logs/ks-server.example.com-access_log common
    <Directory /ks>
        AllowOverride All
        Require all granted
    </Directory>
    <Directory /image>
        Options Indexes MultiViews
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

So here I am basically serving two different PATH over my HTTP server i.e. my kickstart configuration file and my image repository. I have also provided the required permission to access these path, you may check Apache DirectoryListings for more information.

Next enable and start the httpd service:

# systemctl enable httpd --now

Make sure the service has started successfully:

~]# systemctl status httpd

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

The next important thing we must do is to allow visibility of hidden files in the HTTP server as I mentioned earlier, installation over network requires validation of the repository using .treeinfo file which is basically a hidden file in Linux. So by default this file will not be visible on the web server.

So to fix this we must remove .??* from IndexIgnore parameter of /etc/httpd/conf.d/autoindex.conf file.

Change

IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t

To

IndexIgnore *~ *# HEADER* README* RCS CVS *,v *,t

and restart the httpd service.

~]# systemctl restart httpd

Next try to access the image repository path over the web server:

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

Similarly try to access the kickstart config file on the web browser:

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

NOTE:
If you face any issues accessing these location, then you can refer the /etc/httpd/logs/ks-server.example.com-error_log or ks-server.example.com-access_log file which we had mentioned in our virtual hosting config file.

 

Step-7: Update kickstart configuration file

Next update the image repository location in the kickstart file i.e. /ks/kickstart.conf which we created above. Since we are using HTTP, so we need to replace cdrom with following line:

# Use CDROM installation media
url --url=http://192.151.6.151/image/AppStream

By default if you had installed your server using DVD Media, then you will have cdrom as the installation media. So, we will change that to our HTTP url which contains the image for the installation.

Update the AppStream repo url, as with CDROM by default file:// handler is used but since we place to use HTTP so we will have to use following path, additionally also mention the path of BaseOS repository.

# Create AppStream repo 
repo --name="AppStream" --baseurl=http://192.151.6.151/image/AppStream
repo --name="BaseOS" --baseurl=http://192.151.6.151/image/BaseOS

 

Step-8: Create grub.cfg file

For UEFI PXE Boot we need a grub.cfg file with the details of PXE boot files required for installation over network. Following is the content from my grub.cfg file:

~]# cd /var/lib/tftpboot/pxelinux

~]# cat grub.cfg
set timeout=30
menuentry 'Install CentOS 8' {
    linuxefi pxelinux/vmlinuz inst.ks=http://192.151.6.151/ks/kickstart.conf inst.stage2=http://192.151.6.151/image/ quiet
    initrdefi pxelinux/initrd.img
}

Here we have created a single menu entry with the location of our kickstart configuration file. The inst.stage2= boot option specifies the location of the installation program’s runtime image. This option expects the path to a directory that contains a valid .treeinfo file and reads the runtime image location from the .treeinfo file.

 

Step-9: Configure Firewall

We have three services which must be allowed in the firewall i.e. DHCP, TFTP and HTTP. Since we are using firewalld, we will use firewall-cmd to enable these service/ports:

~]# firewall-cmd --add-service=http --add-service=tftp --add-service=dhcp --permanent
~]# firewall-cmd --reload
success

Verify the rules are added properly

~]# firewall-cmd --list-service
cockpit dhcp dhcpv6-client http ssh tftp

 

Step-10: Configure SELinux

I have kept my SELinux into Permissive mode for the sake of this tutorial.

~]# getenforce
Permissive

You can also set it to permissive mode using following command

~]# setenforce 0

or you may also choose to completely disable it.

 

Step-11: Perform PXE Boot

We are all setup to perform UEFI PXE Boot of our target blades to install them over network. Boot your client node and perform a network based installation. Now the shortcut button to boot over network may vary for different hardware but on most cases we are expected to press F12 to boot from network:

If your UEFI PXE Boot Server configuration is proper, then the TFTP files should get successfully downloaded as shown below

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

 

In the next screen you will see the boot menu entry as we had configured in our grub.cfg file. Hit Enter to start the automated installation using kickstart configuration file:

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

 

Hit Enter to start the installation. If you see the following screen, that would mean you can now sit back and have your coffee!!

Configure UEFI PXE Boot with Kickstart [RHEL/CentOS 8]

 

 

Summary

In this tutorial we learned how to create UEFI PXE Boot server using RHEL/CentOS 8 Linux server. I have shared step by step instructions to create and setup your kickstart server. Although there are many other ways to achieve the same, for example you could use DNSMASQ instead of DHCP or use FTP or NFS instead of HTTP to host your kickstart file and image repository. So you can customize the installation steps as per your requirement. Although this article should give you a base to setup your first every PXE boot server.

Let me know if you face any issues via comments section.

 

Deepak Prasad

Deepak Prasad

He is the founder of GoLinuxCloud and brings over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels in various domains, from development to DevOps, Networking, and Security, ensuring robust and efficient solutions for diverse projects. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

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 send mail to admin@golinuxcloud.com

Thank You for your support!!

36 thoughts on “Configure IPv4 UEFI PXE Boot with Kickstart [RHEL/CentOS 8]”

  1. Hey Admin

    when i start the installation from pxe i get the message:

    “disk sda given in ignoredisk command does not exist”

    what im gonna do?

    Reply
    • You will have to update kickstart file based on your environment.

      If you don’t have sda then remove it from ignoredisk. Accordingly update your disk configuration or else that will also fail

      Reply
  2. Hey Admin

    when i try to boot pxe i get this line:

    >>Start PXE over IPv4.
    Station IP address is 10.189.200.133
    
    Server IP address is 10.189.199.40 
    NBP filename is pxelinux/BOOTX64.EFI
    NBP filename is 0 Bytes
    PXE-E23: Client received TFTP error from server

    and i get in blue window:

    Boot faild, press any key to continue.

    can you explaine me what is the problem and how to fix it?
    i did it according the guide

    Reply
    • The TFTP server seems to be working as it is able to serve request but the file download is failing means some problem in network/firewall/permission
      Try to access the same locally using tftp client with GET. If that works then try disabling the firewall and re-try.
      Is SELinux in Enforcing state?

      Reply
  3. Hai excellent set up. Can u do it for Ubuntu as well. Since many are starting to shift from centos/rhel to Ubuntu . Please do it and update here. Eagerly waiting

    Reply
  4. Hai great work. Have you done pxe with kickstart for Ubuntu server? if so please share me the link it.
    If not please, can u create one article on pxe+kickstart+ubuntu. It would be very useful.

    Reply
  5. Hai,
    I am inserting iso file directly in virtual box. I want to kickstart the installation . Kickstart is hosted through nfs.
    Once i get the installation page i type “e” to edit and at the end of linuxefi…..quit, i type “inst.ks=nfs:nfsip:/kickstart/ks.cfg

    ip=staticip:24 :eth0 gateway= gatewayip "

    I think there is some parameter issue in the above line

    dracut error: network is unreachable
                       cp:cannot stat '/run/nfs_mnt1/ks.cfg' : No such file or directory
                      Warning: anaconda: failed to fetch kickstart from nfs:xxxx:/kicksttart/ks.cfg

    Note: Using centos8.3 UEFI mode
    Please let me know what has gone wrong

    Reply
  6. Hai admin, good job.
    I am in a critical situation where I want to configure the same for dhcpv6. That is for ipv6.
    1.Can u please mention the changes to be done in /etc/dhcp/dhcpd6.conf
    2.Can you share reference link to configure dhcpv6, where i need to send ipv6 to client requesting for ip

    Reply
  7. Its working well and good. Thank you for the post
    One doubt is, authconfig is replaced by authselect in Kickstart (throwing a warning message, but doesnt affect the flow)

    authconfig  --enableshadow --enablecache --passalgo=sha512 --enablenis --nisdomain=domain --nisserver=domain.com

    how can i convert the above line to authselect in Kickstart. can you help me with the changes?

    Reply

Leave a Comment