2021.04.13 - KickStart

Automating Red Hat Enterprise Linux 8 / AlmaLinux installation with custom partitioning

Intro

When installing Linux on a Hyper-V server and using the EXT4 file system Microsoft suggests some special formatting commands be used. Also getting the partition layout I like can be a bit difficult with the graphical installer. So I'm going to be making a KickStart file which will automaticlly take care of a bunch of things and speed up the installation. This assumes that your Linux system is on a network with a DHCP server and you have a server that can server files over HTTP. It also assumes you'll be using EFI and not BIOS, and not using IPv6, using the Minimal install ISO (although I think the full would work as well) and a bunch of other little things that I'll try to call out as I remember.

What I Put in the KickStart File

It's not clear to me exactly what order is important in a KickStart File, as best I can tell the sections (the parts that start with %word and end with %end) seem to be able to go anywhere, but the stuff outside of those sections seem to be slightly affected by order. Or it could just be whenever I changed the order I messed up something else in the file and thought the order change was the problem. In any case, the order of commands present here works. If you change the order your results may vary

#version=RHEL8 graphical keyboard --xlayouts='us' lang en_US.UTF-8 timezone America/Chicago --isUtc

First the basics, we'll be going a graphical installation (you could also choose text) and we'll be using a standard US keyboard and the system language will be set to US English using the UTF-8 Charator set. The time zone will be US Central Time.

%packages --multilib @^Minimal Install %end cdrom repo --name="Minimal" --baseurl=file:///run/install/sources/mount-0000-cdrom/Minimal

Then we tell it what packages we want to install. I've added the --multilib flag so that both the 64-bit and 32-bit binaries are installed. If you don't install the 32-bit and then try and run a 32-bit program you get weird errors like "file not found". @^Minimal Install selects the Minimal Install option with no extra packages, exactly what I want on a server. You can also specify partiular packages to install, or packages to exclude from the group, but in my case I'll be using some packages from the epel repo so I'm just going to install all those at the end.

The cdrom and repo line tell it to use the data on the iso to install packages. You can also configure it to use the network and download the lastest packages for install, but I just want the install done as quickly as possible.

selinux --disabled network --bootproto=dhcp --device=eth0 --noipv6 --activate firewall --enabled --ssh

I have never taken the time to learn how to properly use SELinux. It's a very powerful security tool and something that really should be used to help lockdown Linux machines. I'll just disable it.

Eth0 is already enabled with DHCP becuase to use a kickstart file over the network it's kinda required that the server have a connection to the network, I've just set IPv6 disabled. If you wanted to you could specify the hostname as well using this line: network --hostname=test.example.com . At one time I had setup this code to ask the user to input the hostname, but it seemed like a lot of extra work when they could just as easily enter it on the installation screen. In case you are interested that code will be further down. Also the firewall is set enabled with an execption in place for ssh.

clearpart --all part /boot/efi --fstype="efi" --size=600 --fsoptions="umask=0077,shortname=winnt" part /boot --fstype="ext4" --size=1024 part swap --fstype="swap" --recommended part / --fstype="ext4" --size 2048 --grow --mkfsoptions="-G 4096"

Now for the whole reason I went through all this trouble, the custom partitioning/formatting commands. clearpart --all means that the first drive the installer finds will have all data erased and will be partitioned and formatted using this layout. I'll say I can no clue why we need a /boot and a /boot/efi partition. I also have no idea what the significates of the fsoptions are. These are just want the installer suggested to me.

Rather then manually set the swap size I'm letting the installer pick the size it feels is correct. Back in the day I was told to make the swap the same size as the RAM but as RAM sizes got bigger I'm assuming that advice is no longer valid.

I've set the / as a mininum size of 2gb but to grow to fill any remaining space on the disk. Also the -G 4096 option is passed onto mkfs as recommened by Microsoft. After the install is complete if you'd like to verify it worked correctly you can use this command: tune2fs -l /dev/sda4 | grep Flex .

reboot --eject

Just a quick line telling the installed to eject the media/iso at the end of installation and reboot

%post exec < /dev/tty6 > /dev/tty6 2> /dev/tty6 chvt 6 yum -y install epel-release yum -y install nano telnet nmap lftp rsync wget whois logwatch expect ntsysv rsyslog net-tools bind-utils mlocate lsof tar zip ftp mailx echo -e 'Service = All\nService = "-dovecot"\nService = "-pam_unix"\nService = "-systemd"' >> /etc/logwatch/conf/logwatch.conf chvt 1 exec < /dev/tty1 > /dev/tty1 2> /dev/tty1 %end

Then finally the post installation commands. I'm not really sure exactly why I need to switch TTYs to run the yum commands, but the TTY6 is chosen arbitrarily. There's also some default settings in there for the logwatch service (I find on a public server that the dovecot and pam_unix services are too chatty with people trying to hack into user accounts).

The Complete KickStart File

#version=RHEL8 graphical keyboard --xlayouts='us' lang en_US.UTF-8 timezone America/Chicago --isUtc %packages --multilib @^Minimal Install %end cdrom repo --name="Minimal" --baseurl=file:///run/install/sources/mount-0000-cdrom/Minimal selinux --disabled network --bootproto=dhcp --device=eth0 --noipv6 --activate firewall --enabled --ssh clearpart --all part /boot/efi --fstype="efi" --size=600 --fsoptions="umask=0077,shortname=winnt" part /boot --fstype="ext4" --size=1024 part swap --fstype="swap" --recommended part / --fstype="ext4" --size 2048 --grow --mkfsoptions="-G 4096" reboot --eject %post exec < /dev/tty6 > /dev/tty6 2> /dev/tty6 chvt 6 yum -y install epel-release yum -y install nano telnet nmap lftp rsync wget whois logwatch expect ntsysv rsyslog net-tools bind-utils mlocate lsof tar zip ftp mailx echo -e 'Service = All\nService = "-dovecot"\nService = "-pam_unix"\nService = "-systemd"' >> /etc/logwatch/conf/logwatch.conf chvt 1 exec < /dev/tty1 > /dev/tty1 2> /dev/tty1 %end

Using the KickStart File

It's pretty straight-forward. First on a webserver save your KickStart file (in my case I'll be calling it ks.cfg). Probably a good idea to give it a test and make sure if you enter the URL into a computer the file comes up. This is also why I'm not setting the root password in the config file. If you wanted to you could add a root password to the config file and then the whole installation would run without any user input, but I figure if I'm putting this up on a public webserver I don't want the world seeing even my encrypted root password.

If you did want to include a root password in your KickStart config you would use the either the rootpw --plaintext AwesomePassWdHere or rootpw --iscrypted $6$T6sFCctsyRQYmat7$bNqSRUAxTLdY5.... You can use this Python command to generate the encrypted password: python -c 'import crypt,getpass;pw=getpass.getpass();print(crypt.crypt(pw) if (pw==getpass.getpass("Confirm: ")) else exit())'

Once you've got your ks.cfg file online then boot the AlmaLinux installer. When you get to the boot menu highlight the Install AlmaLinux 8 option and push e to edit it. At the end of the linuxefi line, just after quiet add inst.ks=http://example.com/ks.cfg and then push Ctrl+x to boot. If all goes well your server should get a DHCP address and use that to request the ks.cfg file and then proccess the commands inside it.

DHCP is automaticly enabled on eth0 when you use the inst.ks= command. There are other command line options you can set if you don't have DHCP or want to use an FTP of NFS server, here's the KickStart guide for Red Hat Enterprise Linux 8

Getting User Input in a KickStart File

Becuase of the way KickStart runs getting user input is weird. It's not as easy as just having a user enter a response and saving that response as a variable for later use. As best I can tell you have to write out user responses to a text file and then import that text file into your KickStart file. Ultimately I found the whole thing too fiddly to want to mess with, but if you wanted to implement it here's some code to get and set the server hostname:

%pre exec < /dev/tty6 > /dev/tty6 2> /dev/tty6 chvt 6 IFS=$'\n' touch /tmp/user clear echo -n "Enter hostname: " read USERINPUT echo "network --hostname=""$USERINPUT" >> /tmp/user echo clear chvt 1 exec < /dev/tty1 > /dev/tty1 2> /dev/tty1 %end %include /tmp/user

-Nick