Wednesday, September 19, 2018

Kickstart CentOS7

This may be a little late to the game with Kickstart files and the installation of a RedHat / CentOS / Fedora server, but I thought I would share some of the work I have been doing in this realm. The business I work for has a small Linux footprint that is steadily growing and there has been not much in the ways of standardization, or automated installs. I recently switched teams to the Engineering team and found that the installs of Linux servers were done by mounting the ISO, launching the GUI and clicking "Next, Next, Finish" (well, not quite that quick ... however, tedious).

In my spare time I started messing around with Kickstart files in my home lab with libvirt installs where it would only require one line to do a complete install of a virtual machine. Soon after it was adapted for the workplace. I created a number of Kickstart files and had troubles creating a custom ISO, so I worked around this by having floppy images that would mount to the VM. I know what you're thinking ... floppies in 2018, but it worked. The main difference of our installs is the partitioning, something which we are finally coming to a standard on (the biggest being swap space). So I had three separate files, one for 2GB, another for 4GB, and then 8GB. The problem with this is that there were a number of manual steps that could be missed (not to mention that editing the boot menu each time with ks=hd:fd0:/ks.cfg).

This process soon morphed into a single ISO, still with the three different Kickstart files and a custom boot menu. But there was more to be added in, such as users and other quick configurations. We also don't have DHCP or a PXE server to do the installs. To work around this, the Kickstart file asks for all the network configuration such as IP Address, Subnet Mask, etc. As well as hostname and swap size (originally in MB, but added in some quick math to convert from GB). The install also adds a motd banner, and modifies a few other files. With the next step to bootstrap it to Chef and kick off an initial run list with some other config details. I would also like to automatically do the logic for the swap space calculations, and DNS based on server name.

Here is the current version of the Kickstart file:

# Kickstart
#version=DEVEL

# Text only install
text

# Install
install

# Repository
cdrom

# Ignore x environment
skipx

# Include config file
%include /tmp/network.txt
%include /tmp/vg.txt
#%include /tmp/rhel.txt

# Language support
lang en_US.UTF-8

# Keyboard
keyboard us

# timezone
timezone --utc America/Denver

# set root password
rootpw  --iscrypted $6$QWxbTrS.7hAzeNRq$hCrO/f9mqzD/ZqC9XLl46P495H2fdmH0pCSPcmkh/IoGHm4u8v7fQdSzCXntiaSasST0UUOONKK2cR/BF2IMA0

# create patrol user
user --name=patrol --groups=wheel --iscrypted --password=$6$ZeGpbSQHAxj5nvou$4tV5GMq9a1W20EkYb6Y00G9B7Kmn4ilZRftinXjKZKr6h.EMLk5qxEskzkWeth4JfN7KHD7Y9sRK1oZTFIwtn1
user --name=syseng --groups=wheel --iscrypted --password=$6$Rc5TEv9yx7aDL/1t$fVwDgEAb2h8qtfq2UJbxKqnpOspI34pcJv1zgRP3lKFv3zwBs4p4mfm4WZFYRBVp7CESfgfhE20ypWxuQ3DxO1

authconfig --enableshadow --passalgo=sha512
firewall --service=ssh
selinux --enforcing

# clear the MBR (Master Boot Record)
zerombr

# bootloader
bootloader --location=mbr --driveorder=sda --append="crashkernel=auto rhgb quiet"
# remove existing partions
clearpart --all --initlabel

# Reboot after installation
reboot

# packages to install
%packages
@core
wget
%end

##############################################################################
#
# pre installation part of the KickStart configuration file
#
##############################################################################

%pre
exec < /dev/tty6 > /dev/tty6 2>&1
chvt 6
HOSTNAME=""
IPADDR=""
NETMASK=""
GATEWAY=""
DNS=""
SWAP=""

while [[ "$HOSTNAME" == "" ]] || [[ "${IPADDR}" == "" ]] || [[ "${NETMASK}" == "" ]] || [[ "${GATEWAY}" == "" ]] || [[ "${DNS}" == "" ]] || [[ "${SWAP}" == "" ]] ; do
 echo
 echo " *** Please enter the following details: *** "
 echo
 read -p "Hostname: " HOSTNAME
 read -p "IP Address: " IPADDR
 read -p "Netmask: " NETMASK
 read -p "Gateway: " GATEWAY
 read -p "DNS: " DNS
 read -p "Swap Space (GB): " SWAP
done
clear
echo "network --onboot yes --device ens192 --bootproto static --ip ${IPADDR} --netmask ${NETMASK} --gateway ${GATEWAY} --noipv6 --nameserver ${DNS} --hostname ${HOSTNAME}" > /tmp/network.txt

echo -e "Applying the following configuration: \n"
echo "Hostname = ${HOSTNAME}"
echo "IP Address = ${IPADDR}"
echo "Netmask = ${NETMASK}"
echo "Gateway = ${GATEWAY}"
echo "DNS = ${DNS}"

# calculate MB
BYTES=1024
SWAPSIZE=$((SWAP*BYTES))


sleep 5
chvt 1

cat > /tmp/vg.txt <<EOF
part /boot --fstype=ext4 --size=500
part pv.01 --grow --size=1
volgroup vg_${HOSTNAME//-} pv.01
logvol swap --name=lv_swap --vgname=vg_${HOSTNAME//-} --size=${SWAPSIZE}
logvol /tmp --fstype=ext4 --name=lv_tmp --vgname=vg_${HOSTNAME//-} --size=2048
logvol / --fstype=ext4 --name=lv_root --vgname=vg_${HOSTNAME//-} --size=1 --grow
EOF

%end

##############################################################################
#
# post installation part of the KickStart configuration file
#
##############################################################################

%post --nochroot

# bring in hostname collected from %pre, then source it
cp -Rvf network /mnt/sysimage/etc/sysconfig/network
# Set-up ens192 with hostname
cp ifcfg-ens192 /mnt/sysimage/etc/sysconfig/network-scripts/ifcfg-ens192
# force hostname change
/mnt/sysimage/bin/hostname $HOSTNAME

cat > /mnt/sysimage/etc/LoginBanner <<EOF
Hostname = ${HOSTNAME}

!!!WARNING!!!
#################################################
# All sessions are being recorded and monitored #
#################################################
EOF

echo "Banner /etc/LoginBanner" >> /mnt/sysimage/etc/ssh/sshd_config
cp /mnt/sysimage/etc/LoginBanner /mnt/sysimage/etc/motd

# chef-client

if [ ! -e /mnt/sysimage/etc/chef ]; then
        mkdir /mnt/sysimage/etc/chef
fi

cat > /mnt/sysimage/etc/chef/client.rb <<ECLRB
log_level        :info
log_location     STDOUT
chef_server_url  "http://lax:4000"
validation_client_name "chef-validator"
node_name "{$HOSTNAME}"
trusted_certs_dir "/etc/chef/trusted_certs"
ECLRB
chmod 600 /mnt/sysimage/etc/chef/client.rb

cat > /mnt/sysimage/etc/chef/validation.pem << EOVAL
-----BEGIN RSA PRIVATE KEY-----
MIIE...Wg==

-----END RSA PRIVATE KEY-----
EOVAL
chmod 600 /mnt/sysimage/etc/chef/validation.pem

cat > /mnt/sysimage/etc/chef/trusted_certs/lax-inchf01_inucn_com.crt << EOCRT
-----BEGIN CERTIFICATE-----
MIID9zCCAt

-----END CERTIFICATE-----
EOCRT
chmod 600 /mnt/sysimage/etc/chef/validation.pem


# Install Chef packages
yum -y install rubygem-chef
chkconfig chef-client on
yum -y update

##############################################################################

# Done
exit 0
%end