Secure a Server to CIS Level 1 - Script

CIS Secure Script - Warning Message

Warning! Do not run this script on production machines until you have tested it in a sandbox/test environment first, this script will make changes to the overall function of the server  

This is a very long script about 4000 lines that will run in a 5 to 10 minute window, depending on the server It my take a little less then 5 mins or a little more then 10 mins, if you get a black screen with nothing happening or just a spinner for more then 5 mins that's a sign that something is not working.

I added a interactive menu to collect most of the data and before you ask, none of that data stays after the script run, so you have to remember it, It is fairly easy securing your server using this script. since the standards continually change I will try to keep it as updated as possible.    

This script was written for the OCI version of Oracle Linux 7 originally, but has expanded to cover other versions of RedHat and Ubuntu based Linux servers. I will include screen shots of the menus as well as a description of what its asking you for, you will notice that some of the scripts used here I split out of this script and on to other pages here.

You can download this script here or at the bottom of the page.

Clearing the scroll back buffer and setting the terminal

clear
export TERM=xterm-256color 

User Configuration go here

############################
#### User Configuration ####
############################
RSWP=8 # <-- Set the required swap size 
TCPPORTS=( 22 1521 5666 7001 7002 8000 9090 )
TCP6PORTS=( 22 )
UDPPORTS=( 53 )
UDP6PORTS=( 53 ) 

 System Variables

##########################
#### System Variables ####
##########################
BACKUP="/root/config_Backups"
BOOTLD="/boot/grub2/user.cfg"
BOOTLDCE="/boot/efi/EFI/centos/"
BOOTLDRH="/boot/efi/EFI/redhat/"
BOOTLDUB="/boot/grub/user.cfg"
CRON_RH="/var/spool/cron/root"
CRON_UB="/var/spool/cron/crontab/root"
FIREIP="echo ${VLANIP// /}"
IPTBL="/etc/sysconfig/iptables"
IP6TBL="/etc/sysconfig/ip6tables"
IPTBLUB="/etc/iptables/rules.v4"
IP6TBLUB="/etc/iptables/rules.v6"
GRUBCFG="/boot/grub2/grub.cfg"
GRUBCFGCE="/boot/efi/EFI/centos/grub.cfg"
GRUBCFGRH="/boot/efi/EFI/redhat/grub.cfg"
GRUBCFGUB="/boot/grub/grub.cfg"
HOST=$(uname -n | awk -F. '{print $1}')
HOSTNAME=$(uname -n)
IPADD=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')
LOG=${BACKUP}/install.log
MODPRO="/etc/modprobe.d/cis.conf"
MYIP=$(netstat -putan | awk '/:22 / && /ESTABLISHED/ {split($5,result,":"); print result[1]}')
TMPMNT="/usr/lib/systemd/system"
OS=$(grep PRETTY_NAME /etc/os-release | sed 's/PRETTY_NAME=//g' | tr -d '="' | awk '{print $1}' | tr '[:upper:]' '[:lower:]')
OSVER=$(grep VERSION_ID /etc/os-release | sed 's/VERSION_ID=//g' | tr -d '="' | awk -F. '{print $1}') 

Menu Variables

########################
#### Menu Variables ####
########################
H1=20
R1=3
R2=6
R3=11
W1=80 

Detect OS, OS Version and set package manager 

###########################################################
#### Detect Package Manger from OS and OSVer Variables ####
########################################################### 
if [ "${OS}" = ubuntu ]; then
	PAKMGR="apt-get -y"
elif [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
	if [ "${OSVER}" = 7 ]; then
		PAKMGR="yum -y"
	fi
	if [ "${OSVER}" = 8 ] || [ "${OSVER}" = 9 ]; then
	PAKMGR="dnf -y"
	fi
fi </code

Making sure you are a root user, won't work otherwise

##############################################
#### Check to see if running as Root User ####
##############################################
function check_root() {
	{
		if [ $EUID -ne 0 ]; then
			echo ""
			echo "Script Installation has been Halted!"
			echo ""
			echo "You Must Run This Script as the \"ROOT\" User"
			exit
		fi
	}
}

Create the Backup /dir and log file

#################################
#### Config backup directory ####
#################################
function backup() {
	{
		for dir in ${BACKUP}; do
		[[ ! -d "$dir" ]] && mkdir "$dir"
		touch ${BACKUP}/install.log
		done
	}
}

I use this function in place of cat and echo from time to time it works best for files that have no indenting.

#######################
#### Copy Function ####
#######################
function no_show() {
	{
		expand | awk 'NR == 1 {match($0, /^ */); l = RLENGTH + 1}
			{print substr($0, l)}'
	}
}

Spinner Function - Gives you something to else to watch :-)

##########################
#### Spinner Function ####
##########################
function _spinner() {
    {
		local on_success="COMPLETE"
		local on_fail="ERROR"
		local green="\e[1;32m"
		local red="\e[1;31m"
		local nc="\e[0m"
		case $1 in
			start)
				((column=$(tput cols)-${#2}-8)) 
				echo -ne "\e[7m ${2} \e[0m \n"
				printf "%${column}s"
				i=1
				sp='/-\|/-\:'
				delay=${SPINNER_DELAY:-0.15}
				while :
				do
					printf "\b%s${sp:i++%${#sp}:1}"
					sleep "$delay"
				done
				;;
			stop)
				if [[ -z ${3} ]]; then
					echo "spinner is not running.."
					exit 1
				fi
				kill "$3" > /dev/null 2>&1
				echo -en "\b["
				if [[ $2 -eq 0 ]]; then
					echo -en "${green}${on_success}${nc}"
				else
					echo -en "${red}${on_fail}${nc}"
				fi
				echo -e "]"
				;;
			*)
				echo "invalid argument, try {start/stop}"
				exit 1
				;;
		esac
	}
}

Spinner Start Function

#######################
#### Spinner Start ####
#######################
function start_spinner {
	{
		echo ""
		_spinner "start" "${1}" &
		_sp_pid=$!
		echo ""
		disown
	}
}

Spinner Stop Function

######################
#### Spinner Stop ####
######################
function stop_spinner {
	{
		echo ""
		_spinner "stop" "$1" $_sp_pid
		unset _sp_pid
		echo ""
	}
}

First Message on Start of script - "Warning! Message"

#########################
#### Warning Message ####
#########################
function warn_message() {
	{
		whiptail --backtitle "SecureIt contact@mylinux.work" --title "*** WARNING ***" --yes-button "CONFIRM" --no-button "Exit" --defaultno --yesno "   Running this script will harden this server to CIS Benchmark settings.
		It will change server configuration and will affect server operation


			ONLY RUN THIS SCRIPT IF YOU KNOW WHAT YOU ARE DOING!

			
							You must select CONFIRM to continue." ${H1} ${W1}
			exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
			private_ip
		else
			exit
		fi
	}

}
Warning Menu

I will point out at this point that when you run this on a Ubuntu OS based machine the background will be pink if you run this on a RedHat OS based machine the background will be blue, Just so you know....

What is the connection IP - "Private IP Menu"

#############################
#### Get VLAN IP address ####
#############################
function private_ip() {
	{
		VLANIP=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "Server Connect IP" --ok-button "Continue" --cancel-button "Exit" --inputbox "     What is the IP/Sub or VLAN/Sub you use to connect to this server?
				
										Examples are 192.168.0.0/24
											or   192.168.1.21/32
											or   10.0.10.0/16

	Your current SSH Connection IP is Shown and can be changed if required" ${H1} ${W1} "${MYIP}"/32 3>&1 1>&2 2>&3) 
			exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
			time_zone
		else
			exit
		fi
	}
}
Second Menu - IP setup

The address you see here is auto detected, It should be the address you used to connect with like a VPN if private network or the public address you connected to the machine with.

This is very IMPORTANT! the IP address that is in this box will be the only address in the hosts.allow file so if you make a mistake here you will have to console connect to the server to fix it cause you won't be able to get in any other way. 

You can have more addresses here if you need like multi IP, machines, vlans or subnets. Examples are listed on the menu screen, multi IP's are done like this 192.168.1.10/32, 192.168.2.10/32, 192.168.3.21/32 and so....

What is the Server Timezone - "Get Timezone Menu"

######################
#### Get TimeZone ####
######################
function time_zone() {
	{
		# shellcheck disable=SC2046	
		TIMEZONE=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "Server TimeZone" --ok-button "Continue" --cancel-button "Exit" --menu "                      What is your Server Timezone?

													Example Central" ${H1} ${W1} ${R3} $(find /usr/share/zoneinfo/US/* | cut -d '/' -f 6 | sort | sed "s/$/ ./" | tr '\n' ' ';)  3>&1 1>&2 2>&3)
			exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
			max_count
		else
			exit
		fi
	}
}
SecureIt.sh - TimeZone Menu

This gets the timezone variable which is used at the beginning of the scripts run to set the servers timezone, This is done more for the logs to make it easier to narrow done the time frames for problems or finding selinux issue with auditctl, I only loaded the major time zones for simplicity.

Auto logout/Disconnect Time - "Server Disconnect Menu"

##################################
#### Get Auto Disconnect Time ####
##################################
function max_count() {
	{
		MAXCOUNT=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "Server Disconnect" --ok-button "Continue" --cancel-button "Exit" --radiolist "             What is the MAX time you want before auto disconnect?" ${H1} ${W1} ${R1} \
						"1" "5 mins"  OFF \
						"2" "10 mins" OFF \
						"3" "15 mins" ON  3>&1 1>&2 2>&3)
		exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
				max_logs
		else
				exit
		fi
	}
} 
SecureIt.sh - Time Out Disconnect Menu

CIS recommends 5 mins, but I have defaulted this to 15 mins, for those of you that don't know, this is the amount of keyboard input time inactivity.. The problem I have with this is Oracle updates, and the DBA's I support would get logged out before the script to update Oracle was finished, so I defaulted it to 15 mins and then came up with a work around for the oracle and applmgr users so this would no longer be an issue. Since I mentioned I have a work around you can email me and I'll give it to you.

Select your log type - "Audit Logs Menu"

#################################
#### Get Audit logs Setting ####
################################
function max_logs() {
	{
		MAXLOGS=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "Audit Logs" --ok-button "Continue" --cancel-button "Exit" --inputbox "        If you plan on archiving the audit logs leave \"ignore\" here
						If you have tons of room change this to \"KEEP_LOGS\"" ${H1} ${W1} ignore  3>&1 1>&2 2>&3)
			exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
			syslog_server
		else
			exit
		fi
	}
}
SecureIt.sh - Audit Logs Menu

I think this is self explanatory I have an audit log script that installs with the SecureIt.sh script that will compress the daily logs to a more manageable size, you'll see it later in this doc....

What's your syslog servers name or IP address - "SysLog Server Menu"

###########################
#### Get Syslog Server ####
###########################
function syslog_server() {
	{
		SYSLOG=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "SysLog Server" --ok-button "Continue" --cancel-button "Exit" --inputbox "               What is the Name or IP of your SysLog Server?" ${H1} ${W1}  3>&1 1>&2 2>&3)
			exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
			srv_type
		else
			exit
		fi
	}
}
SecureIt.sh - Syslog Menu

Again self explanatory, but required. (NOTE: to pass Nessus Scan this must match what you have configured Nessus to find)  

What's this server used for - "Server Usage Menu"

##########################
#### Get Server Usage ####
##########################
function srv_type() {
	{
		SRVTYPE=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "Server Disconnect" --ok-button "Continue" --cancel-button "Exit" --radiolist "             What is the use or purpose of this server?" ${H1} ${W1} ${R1} \
						"1" "EBS Server"  OFF      \
						"2" "Weblogic Server" OFF \
						"3" "Regular Server" ON  3>&1 1>&2 2>&3)
		exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
			grub_password
		else
				exit
		fi
	}
}
SecureIt.sh - Server Usage Menu

When I built this script originally, it was for some oracle dba's, I had originnally left out most the security stuff like the grub password, the syslog server and a few I can't mention, but it was an easy provisioning tool that they could use if needed. I have since removed more of the user configurable's and added additional menu's for a more secure run for a sysadmin's use.

Short description of the this menu and what they do...

  •  EBS Server - Thest installs all the prereq's for you to be able to run Oracle EBS     on the server.
  • Weblogic Server - This also installs the prereq's needed for Oracle EBS, but it also has some config changes that must be done so that Weblogic will run in the secured environment.
  • Regular Server - Is Just that a server that isn't running any apps that are affected by the secured server.

Get a Grub Password  - "Grub Password Menu"

#########################
#### Get Grub Passwd ####
#########################
function grub_password() {
	{
		GPASS=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "Grub Password" --ok-button "Continue" --cancel-button "Exit" --inputbox "                  What do you want your Grub Password to be?" ${H1} ${W1} 3>&1 1>&2 2>&3)
			exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
			if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle ]]; then
				G2PASSWD="$(echo -e "${GPASS}\n$GPASS" | grub2-mkpasswd-pbkdf2 2>/dev/null | tail --lines=1 | awk -F " " '{print $7}')"
				main_menu
			elif [ "${OS}" = ubuntu ]; then
				G2PASSWD="$(echo -e "${GPASS}\n$GPASS" | grub-mkpasswd-pbkdf2 2>/dev/null | tail --lines=1 | awk -F " " '{print $7}')"
				main_menu
			fi
		else
			exit
		fi
	}
}
SecureIt.sh - Grub Password Menu

Important! Note - Be sure you put something secure here and that you write it down or remember it otherwise you will not be able to boot in safe mode through the console connection.

OS selection happens here - "OS Select Main" Menu

#############################
#### OS Select Main Menu ####
#############################
function main_menu() {
	{
		while true; do
			CHOICE=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "OS Select Main" --ok-button "Continue" --cancel-button "Exit" --menu "                     Please Select Your Linux Distro" ${H1} ${W1} ${R2} \
				"1)" "Oracle Linux"                 \
				"2)" "RedHat/CentOS/Rocky/Alma"     \
				"3)" "Ubuntu *** Testing ***"       3>&2 2>&1 1>&3)
		exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
			case ${CHOICE} in
			"1)")
				oracle_menu
			;;

			"2)")
				redhat_menu
			;;

			"3)")
				ubuntu_menu
			;;

			"4)")
				
			;;

			esac
		else
			exit
		fi
		done
	}
}
SecureIt.sh - OS Selection Main

Select the type of OS you are trying to harden.

Oracle Selection Menu

#####################
#### Oracle Menu ####
#####################
function oracle_menu() {
	{
		while true; do
			CHOICE=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "Oracle Linux" --ok-button "Install" --cancel-button "Exit" --menu "                     Please Select Your Oracle Version" ${H1} ${W1} ${R2} \
				"1)" "OCI Oracle Linux 7"    \
				"2)" "OCI Oracle Linux 8"    \
				"3)" "Oracle Linux 7"        \
				"4)" "Oracle Linux 8"        3>&2 2>&1 1>&3)
		exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
			case ${CHOICE} in
			"1)")
				oci_oracle_ebs_setup
				oci_rh_ub_common
				oci_only
				complete
			;;

			"2)")
				oci_oracle_ebs_setup
				oci_rh_ub_common
				oci_only
				complete
			;;

			"3)")
				oci_rh_ub_common
				complete
			;;

			"4)")
				oci_rh_ub_common
				complete
			;;

			esac
		else
			exit
		fi
		done
	}
}
SecureIT.sh - Oracle Menu

If you have played on the Oracle Cloud then you will know what OCI refers to, There are some firewall rules that are required for the OCI, hence it's own listing, same with AWS which has the same requirement on their cloud, well not the same but similar firewall requirement, All other cloud and none cloud servers select the regular ones. 

Redhat Selection Menu

#####################
#### Redhat Menu ####
#####################
function redhat_menu() {
	{
		while true; do
			CHOICE=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "Redhat/Centos Linux" --ok-button "Install" --cancel-button "Exit" --menu "                 Please Select Your Redhat/CentOS Version" ${H1} ${W1} ${R2} \
				"1)" "OCI CentOS 7"               \
				"2)" "OCI CentOS 8"               \
				"3)" "AWS Redhat/Centos 7"        \
				"4)" "AWS Redhat/Centos 8"        \
				"5)" "Redhat/CentOS/Rocky/Alma 7" \
				"6)" "Redhat/CentOS/Rocky/Alma 8" \
				"7)" "Redhat/Centos/Rocky/Alma 9" 3>&2 2>&1 1>&3)
		exitstatus=$?
		if [ ${exitstatus} = 0 ]; then
			case ${CHOICE} in
			"1)")
				oci_rh_ub_common
				oci_only
				complete
			;;

			"2)")
				oci_rh_ub_common
				oci_only
				complete
			;;

			"3)")
				oci_rh_ub_common
				aws_only
				complete
			;;

			"4)")
				oci_rh_ub_common
				aws_only
				complete
			;;

			"5)")
				oci_rh_ub_common
				complete
			;;

			"6)")
				oci_rh_ub_common
				complete
			;;

			"7)")
				oci_rh_ub_common
				complete
			;;

			esac
		else
			exit
		fi
		done
	}
}
SecureIt.sh - Redhat Menu

Same here, if your not on OCI or AWS just select the the regular ones for all other cloud providers and regular servers....

Ubuntu Selection Menu

######################
#### Ubuntu Menu ####
#####################
function ubuntu_menu() {
        {
			while true; do
					CHOICE=$(whiptail --backtitle "SecureIt contact@mylinux.work" --title "Ubuntu Linux" --ok-button "Install" --cancel-button "Exit" --menu "                     Please Select Your Ubuntu Version" ${H1} ${W1} ${R2} \
							"1)" "OCI Ubuntu"   \
							"2)" "AWS Ubuntu"   \
							"2)" "Ubuntu"       3>&2 2>&1 1>&3)
			exitstatus=$?
			if [ ${exitstatus} = 0 ]; then
					case ${CHOICE} in
					"1)")
							oci_rh_ub_common
							oci_only
							complete
					;;

					"2)")
							oci_rh_ub_common
							aws_only
							complete
					;;

					"3)")
							oci_rh_ub_common
							complete
					;;

					esac
			else
					exit
			fi
			done
        }
}
SecureIt.sh - Ubuntu Menu

Just like the other 2, you just need to select the last entry if you are on any other cloud service, like Digital Ocean, Contabo or Linode. 

There is one other screen that will pop up at the end of the install, the completion screen, I will include it at the end of the doc for your viewing pleasure :-)

I have a few extra things in here like the mkswap function and a few utilities that are done after the server is hardened, like unattended security updates, a message of the day, cursor colors, audit compression script, SysStat, rkhunter, logwatch and lmd just to name a few... So on with the code!

Mkswap function 

#############################
#### Make Swap if Needed ####
#############################
function make_swap() {
	{
		start_spinner 'Configuring Additional Swap Space...'
		echo ""
		if [ "${SRVTYPE}" -ne 3 ]; then
			# size of swapfile in gigabytes
			swpsize="$RSWP"
			# how large the swap needs to be total in mb's
			swpneed=$((swpsize * 1024))
			# / part dir file list
			dir=$(ls -la --block-size=M /)
			# does the swap file already exist?
			swpexist=$(echo "$dir" | grep -i swap | awk '{ print $5 }' | tr -d 'M"')
			# what is the name of the swap file if it exist 
			swpname=$(echo "$dir" | grep -i swap | awk '{ print $9 }')
			# Is there any swap present if yes what size is it
			swppres=$(free -m | sed -n '3 p' | awk '{ print $2 }')
			# If the swap file already exist is it large enough?
			if (( swpneed < swpexist )) || (( swpneed < swppres )); then
				echo -e '\e[01;37m ======================================================================='
				echo -e '\e[01;32m  ====================================================================='
				echo -e '\e[01;32m   ==== \e[01;37m A Large Enough Swapfile was Found! No Changes Needed... \e[01;32m ===='
				echo -e '\e[01;32m  ====================================================================='
				echo -e '\e[01;37m ======================================================================='
			elif (( swpneed > swpexist )) || (( swpneed > swppres )); then
				echo -e '\e[01;37m =================================================================================='
				echo -e '\e[01;31m  ================================================================================'
				echo -e '\e[01;31m   ==== \e[01;37m A Large Enough Swapfile was not found! Creating Larger SwapFile... \e[01;31m ===='
				echo -e '\e[01;31m  ================================================================================'
				echo -e '\e[01;37m =================================================================================='
				# Turn off existing swap if needing replacement 
				if echo "$dir" | grep -i swap; then
					swapoff /"${swpname}"
					rm -f /"$swpname"
				fi
			# Create the swapfile and make it active
				fallocate -l ${swpsize}g /.SwapFile
				chmod 600 /.SwapFile
				mkswap /.SwapFile
				swapon /.SwapFile
				echo -e '\e[01;37m =============================================================================='
				echo -e '\e[01;32m  ============================================================================'
				echo -e '\e[01;32m   ==== \e[01;37m Checking whether the swap space was mounted and active or not! \e[01;32m ===='
				echo -e '\e[01;32m  ============================================================================'
				echo -e '\e[01;37m =============================================================================='
				R=$(swapon -s)
				if [ -n "$R" ]; then
					echo -e '\e[01;32m                                ============'
					echo -e '\e[01;32m                                ============'
					echo -e '\e[01;32m  ============================================================================'
					echo -e "\e[01;37m$R"
					echo -e '\e[01;32m  ============================================================================'
					echo -e '\e[01;37m =============================================================================='
				else
					echo -e '\e[01;31m                                ============'
					echo -e '\e[01;31m                                ============'
					echo -e '\e[01;31m  ============================================================================'
					echo -e "\e[01;37m                  Something Went Wrong no Swap was Loaded"
					echo -e '\e[01;31m  ============================================================================'
					echo -e '\e[01;37m =============================================================================='
				fi
				# Check to see if the created swap is losted in the fstab file
				if ! grep -q "SwapFile" /etc/fstab; then
					echo "/.SwapFile               swap                                      swap    defaults                        0 0" >> /etc/fstab
				fi
			fi
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Swap is configured first the size is set in the user configuration section, this is not a CIS requirement, but gets overlooked often.

Timezone function

############################
#### Set Sever TimeZone ####
############################
function time_set() {
	{
		start_spinner 'Setting System TimeZone...'
		echo ""
		timedatectl set-timezone US/"${TIMEZONE}"
		stop_spinner $?
	} | tee -a $LOG
}

This is set with the menu "Get TimeZone" variable.

Section 1.1.1 Unused File Systems 

########################################
### 1.1.1 Disable Unused Filesystems ###
########################################
function disable_filesystems() {
	{
		start_spinner 'Disabling Unused Filesystems...'
		echo ""
		touch ${MODPRO}
		#### 1.1.1.1 Ensure mounting of cramfs is disabled ####
		echo "install cramfs /bin/true" > ${MODPRO}
		lsmod | grep -qi cramfs
		if [ $? != 1  ]; then
			rmmod cramfs
		fi
		#### 1.1.1.2 Ensure mounting of freevxf filesystem 1s disabled ####
		echo "install freevxfs /bin/true" >> ${MODPRO}
		lsmod | grep -qi freevxfs
		if [ $? != 1  ]; then
			rmmod freevxfs
		fi
		#### 1.1.1.3 Ensure mounting of jiffs2 filesystem is disabled ####
		echo "install jffs2 /bin/true" >> ${MODPRO}
		lsmod | grep -qi jffs2
		if [ $? != 1  ]; then
			rmmod jffs2
		fi
		#### 1.1.1.4 Ensure mounting of hfs filesystem is disabled ####
		echo "install hfs /bin/true" >> ${MODPRO}
		lsmod | grep -qi hfs
		if [ $? != 1  ]; then
			rmmod hfs
		fi
		#### 1.1.1.5 Ensure mounting of hfsplus filesystem is disabled ####
		echo "install hfsplus /bin/true" >> ${MODPRO}
		lsmod | grep -qi hfsplus
		if [ $? != 1  ]; then	
			rmmod hfsplus
		fi
		#### 1.1.1.6 Ensure mounting of squashfs filesystem is disabled ####
		echo "install squashfs /bin/true" >> ${MODPRO}
		lsmod | grep -qi squashfs
		if [ $? != 1  ]; then	
			rmmod squashfs
		fi
		#### 1.1.1.7 Ensure mounting of udf filesystem is disabled ####
		echo "install udf /bin/true" >> ${MODPRO}
		lsmod | grep -qi udf
		if [ $? != 1  ]; then
			rmmod udf
		fi
		#### 1.1.1.8 Ensure mounting of FAT filesystem is disabled #### 
		echo "install fat /bin/true" >> ${MODPRO}
		lsmod | grep -qi fat 
		if [ $? != 1  ]; then	
			rmmod fat
		fi
		#####################################
		#### Additonal Unsed Filesystems ####
		#####################################
		echo "install cifs /bin/true" >> ${MODPRO}
		lsmod | grep -qi cifs
		if [ $? != 1  ]; then	
			rmmod cifs
		fi
		echo "install nfs /bin/true" >> ${MODPRO}
		lsmod | grep -qi nfs
		if [ $? != 1  ]; then	
			rmmod nfs
		fi
		echo "install nfsv3 /bin/true" >> ${MODPRO}
		lsmod | grep -qi nfsv3
		if [ $? != 1  ]; then	
			rmmod nfsv3
		fi
		echo "install nfsv4 /bin/true" >> ${MODPRO}
		lsmod | grep -qi nfsv4
		if [ $? != 1  ]; then	
			rmmod nfsv4
		fi
		echo "install gfs2 /bin/true" >> ${MODPRO}
		lsmod | grep -qi gfs2
		if [ $? != 1  ]; then	
			rmmod gfs2
		fi
		echo "install usb-storage /bin/true" >> ${MODPRO}
		lsmod | grep -qi usb-storage
		if [ $? != 1  ]; then	
			rmmod usb-storage
		fi
		echo "install bnep /bin/true" >> ${MODPRO}
		lsmod | grep -qi bnep
		if [ $? != 1  ]; then	
			rmmod bnep
		fi
		echo "install bluetooth /bin/true" >> ${MODPRO}
		lsmod | grep -qi bluetooth
		if [ $? != 1  ]; then	
			rmmod bluetooth
		fi
		echo "install btusb /bin/true" >> ${MODPRO}
		lsmod | grep -qi btusb
		if [ $? != 1  ]; then	
			rmmod btusb
		fi
		echo "install net-pf-31 /bin/true" >> ${MODPRO}
		lsmod | grep -qi  net-pf-31
		if [ $? != 1  ]; then	
			rmmod net-pf-31
		fi
		echo "install appletalk /bin/true" >> ${MODPRO}
		lsmod | grep -qi appletalk
		if [ $? != 1  ]; then	
			rmmod appletalk
		fi
		{
		echo "blacklist  usb-storage" 
		echo "blacklist firewire-core"
		echo "options ipv6 disable=1" 
		} >> ${MODPRO}
		stop_spinner $?
	} | tee -a $LOG
}

Section 1 of the CIS manual, kills all of these services, under additional I have added some additional services that several of the companies I worked with decided to also kill, I will warn you now tough if you have any NFS mounts you might want to comment out the NFS and NFv3 from the additional's section.

Section 1.1.2 Ensure Separate Partitions

######################################################
#### 1.1.2 Ensure seprate partion exists for /tmp ####
######################################################
function tmp_directory() {
	{
		start_spinner 'Ensuring a Seprate Partion Exists for /tmp...'
		echo ""
		#### Copy Conf Files for Backup #### 
		xargs -n 1 cp -v /etc/fstab <<< ""${BACKUP} /etc/fstab.bak""
		#### Check to see if /tmp is a mount ####
		mount | grep /tmp
		if ! 1; then
			umount /tmp
		fi
		#### /tmp Mount Changes Ubuntu ####
		if [ "${OS}" = ubuntu ]; then
			xargs -n 1 cp -v /usr/share/systemd/tmp.mount <<< ""${BACKUP} /usr/share/systemd/tmp.mount.bak""
			grep nosuid /usr/share/systemd/tmp.mount
			if ! 1;  then
				sed -i 's/Options=mode=1777,strictatime,nosuid,nodev/Options=mode=1777,strictatime,nosuid,nodev,noexec/g' /usr/share/systemd/tmp.mount
			else
				sed -i 's/Options=mode=1777,strictatime/Options=mode=1777,strictatime,nosuid,nodev,noexec/g' /usr/share/systemd/tmp.mount
			fi
		#### /tmp Mount Changes RedHat ####
		elif [ "${OS}" = oracle ]; then 
			xargs -n 1 cp -v /usr/lib/systemd/system/tmp.mount <<< ""${BACKUP} /usr/lib/systemd/system/tmp.mount.bak""
			if [ "${OSVER}" = 7 ]; then
				sed -i 's/Options=mode=1777,strictatime/Options=mode=1777,strictatime,nosuid,nodev,noexec/g' $TMPMNT/tmp.mount	
			fi
			if [ "${OSVER}" = 8 ] || [ "${OSVER}" = 9 ]; then
				sed -i 's/Options=mode=1777,strictatime,nosuid,nodev/Options=mode=1777,strictatime,nosuid,nodev,noexec/g' $TMPMNT/tmp.mount
			fi
		elif [[ ${OS} = centos || ${OS} = redhat || ${OS} = rocky || ${OS} = alma ]]; then
				if [ "${OSVER}" = 7 ]; then
					sed -i 's/Options=mode=1777,strictatime/Options=mode=1777,strictatime,nosuid,nodev,noexec/g' $TMPMNT/tmp.mount
				fi
				if [ "${OSVER}" = 8 ]; then
					sed -i 's/Options=mode=1777,strictatime,nosuid,nodev/Options=mode=1777,strictatime,nosuid,nodev,noexec/g' $TMPMNT/tmp.mount
				fi
				if [ "${OSVER}" = 9 ]; then
					sed -i 's/Options=mode=1777,strictatime,nosuid,nodev,size=50%,nr_inodes=1m/Options=mode=1777,strictatime,nosuid,nodev,noexec,size=50%,nr_inodes=1m/g' $TMPMNT/tmp.mount
				fi
		else
			xargs -n 1 cp -v /etc/systemd/system/local-fs.target.wants/tmp.mount <<< ""${BACKUP} /etc/systemd/system/local-fs.target.wants/tmp.mount.bak""
			no_show << 	EOF > /etc/systemd/system/local-fs.target.wants/tmp.mount
			[Mount]
			What=tmpfs
			Where=/tmp
			Type=tmpfs
			Options=mode=1777,strictatime,noexec,nodev,nosuid
EOF
		fi
		#### Setting /tmp to persist thru reboots ####
		if ! grep -w /tmp /etc/fstab; then 
				echo "tmpfs                   /tmp                                      tmpfs   defaults,nodev,nosuid,noexec     0 0" >> /etc/fstab
		fi
		mount /tmp
		#### 1.1.3, 1.1.4 & 1.1.5 Ensure noexec, nosuid and nodev option set on /tmp partition ####
		#### mount -o remount,noexec,nosuid,nodev /tmp
		#### Setting /var/tmp to persist thru reboots ####
		if ! grep -w /var/tmp /etc/fstab; then
			echo "/tmp                    /var/tmp                                   none    rw,noexec,nosuid,nodev,bind     0 0" >> /etc/fstab
		fi
		#### Binding mount /var/tmp directory to /tmp ####
		mount -o rw,noexec,nosuid,nodev,bind /tmp/ /var/tmp/
		#### 1.1.8, 1.1.9 & 1.1.10 Ensure noexec, nosuid and nodev option set on /var/tmp partition ####
		mount -o remount,noexec,nosuid,nodev /var/tmp
		#### Setting /dev/shm to persist thru reboots ####
		if [ "${SRVTYPE}" -ne 2 ]; then
			if ! grep -w /dev/shm /etc/fstab; then
				echo "tmpfs                   /dev/shm                                  tmpfs   defaults,nodev,nosuid,noexec,relatime     0 0" >> /etc/fstab
				#### 1.1.15, 1.1.16 and 1.1.17	Ensure noexec, nosuid and nodev option set on /dev/shm partition ####
				mount -o remount,noexec,nosuid,nodev,relatime /dev/shm
			fi
		fi
		#### Ensure noexec and nodev option set on /dev partition ####
		mount -o remount,noexec /dev
		#### Setting /dev to persist thru reboots ####
		if ! grep -w devtmpfs /etc/fstab; then
			echo "devtmpfs                /dev                                   devtmpfs    defaults,noexec                 0 0" >> /etc/fstab
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Before you say anything, I know /home is not in here, but what VPS has a separate /home on it without you creating it in your custom image or manually on the cloud server? And YES Nessus dings you for that with a Failed 

Section 1.1.21 Ensure Sticky Bit is Set

#############################################################################
#### 1.1.21 Ensure Sticky Bit is set on "All" World-Writable Directories ####
#############################################################################
function stickybit() {
	{
		start_spinner 'Setting Sticky Bit on "All" World-Writable Directories...'
		echo ""
		df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type d -perm -0002 2>/dev/null | xargs chmod a+t
		stop_spinner $?
	} | tee -a $LOG
}

Required - Sticky bit on all World Writable /dirs. 

Section 1.1.22 Ensure GPG Keys are configured

##############################################
#### 1.2.2 Ensure GPG Keys are Configured ####
##############################################
function gpgkeys() {
	{
		start_spinner 'Checking GPG Keys are Configured...'
		echo ""
		if [ "${OS}" = ubuntu ]; then
			apt-cache policy
			${PKGMGR} update 2>&1 1>/dev/null | sed -ne 's/.*NO_PUBKEY //p' |
			while read -r key; do
				echo 'Processing key:' "$key"
				apt-key adv --keyserver keyserver.ubuntu.com --recv-keys "$key"
			done
			apt-key adv --refresh-keys --keyserver keyserver.ubuntu.com
			apt-key list	
		else
			rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY*
			rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n' 
			grep ^gpgcheck /etc/yum.repos.d/* >> ${LOG} 2>&1
			### 1.2.3 Verify that gpgcheck is Globally Activated ###
			grep -Eq "^(\s*)gpgcheck\s*=\s*\S+(\s*#.*)?\s*$" /etc/yum.conf && sed -ri "s/^(\s*)gpgcheck\s*=\s*\S+(\s*#.*)?\s*$/\1gpgcheck=1\2/" /etc/yum.conf || echo "gpgcheck=1" >> /etc/yum.conf
		fi
		stop_spinner $?
	} | tee -a $LOG
}

This just makes sure that all the repo's have a current cert and gpgceck=1 is set, even though this is configured correctly, Nessus will still give you a warning Warning to check it...  

Section 1.3.1 Ensure Aide is Installed

########################################
#### 1.3.1 Ensure Aide is Installed ####
########################################
function aide_install() {
	{
		start_spinner 'Installing and Configuring AIDE...'
		echo ""
		if [ "${OS}" = ubuntu ]; then
			debconf-set-selections <<< ""postfix postfix/mailname string "${HOSTNAME}"""
			debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Local Only'"
			${PAKMGR} install aide aide-common --assume-yes
			aideinit
			update-aide.conf
			if [ ! -f ${CRON_UB} ]; then
				touch ${CRON_UB}
				crontab ${CRON_UB}
			fi
			if ! grep -qi "aide" ${CRON_UB}; then
				echo "0 5 * * * /usr/bin/aide.wrapper --check" >> ${CRON_UB}
			fi
		else
			${PAKMGR} install aide 
			aide --init
			mv -f /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
			if [ ! -f ${CRON_RH} ]; then
				touch ${CRON_RH}
				crontab ${CRON_RH}
			fi
			if ! grep -qi "aide" ${CRON_RH}; then
				echo "0 5 * * * /usr/sbin/aide --check" >> ${CRON_RH}
			fi
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Aide is a requirement to a secure environment, I also split this off from the sudo requirement for clarity in the script.

Section 1.3 Sudo Commands

###########################
#### 1.3 Sudo Commands ####
###########################
function sudo_changes() {
	{
		start_spinner 'Configuring Sudo Settings...'
		echo ""
		if [ ! -f /etc/sudoers.d/cis ]; then
			touch /etc/sudoers.d/cis
			chmod 440 /etc/sudoers.d/cis
		fi
		#### 1.3.2 Ensure Sudo Commands use Pty ####
		echo "Defaults use_pty" >> /etc/sudoers.d/cis
		#### 1.3.3 Ensure Sudo Log File Exists ####
		echo "Defaults logfile=\"/var/log/sudo.log\"" >> /etc/sudoers.d/cis
		stop_spinner $?
	} | tee -a $LOG
}

Required - this just creates a file in the /sudoers.d dir called cis and copies the pty and log file requirements in there to track sudo users

Section 1.4 Secure Boot Settings

##################################
#### 1.4 Secure Boot Settings ####
##################################
function boot_load() {
	{
		start_spinner 'Securing Boot Settings...'
		echo ""
		#### 1.4.1 Ensure permissions on bootloader config are configured ####
		if [ "${OS}" = "ubuntu" ]; then
			touch ${BOOTLDUB}
			chmod 600 ${BOOTLDUB}
			chown root.root ${BOOTLDUB}
		else
			touch ${BOOTLD}
			chmod 600 ${BOOTLD}
			chown root.root ${BOOTLD}
		fi
		#### Config /boot/efi permissions in fstab !!! This is for OCI !!! I have not seen this on any other cloud provider ####
		mount | grep /boot/efi
		if [ $? != 1  ]; then
			umount /boot/efi
			if [ "${OS}" = oracle ]; then
				if [ "${OSVER}" = 7 ]; then
					sed -i 's/defaults,uid=0,gid=0,umask=0077,shortname=winnt,_netdev,_netdev,x-initrd.mount/defaults,uid=0,gid=0,umask=0077,fmask=0177,shortname=winnt,_netdev,_netdev,x-initrd.mount/g' /etc/fstab
				elif [ "${OSVER}" = 8 ]; then
					sed -i 's/defaults,uid=0,gid=0,umask=077,shortname=winnt/defaults,uid=0,gid=0,umask=077,fmask=0177,shortname=winnt/g' /etc/fstab
				fi
			fi
			if [ "${OS}" = centos ]; then
				sed -i 's/vfat[[:blank:]]*defaults/vfat    defaults,uid=0,gid=0,umask=0077,fmask=0177/g' /etc/fstab
			fi
			mount /boot/efi
		fi
		#### 1.4.2 Ensure bootloader password is set ####
		if [ "${OS}" = centos ]; then
			echo GRUB2_PASSWORD="${G2PASSWD}" > ${BOOTLD}
			cp ${BOOTLD} ${BOOTLDCE}
		elif [ "${OS}" = ubuntu ]; then
			echo GRUB2_PASSWORD="${G2PASSWD}" > ${BOOTLDUB}
		else
			echo GRUB2_PASSWORD="${G2PASSWD}" > ${BOOTLD}
			cp ${BOOTLD} ${BOOTLDRH}
		fi
		stop_spinner $?
	} | tee -a $LOG
}

This sets permissions on the user.cfg file, then sets the password hash that was created earlier when you were asked what you wanted the boot password to be,

What I didn't mention is the section that configures the /boot/efi dir, The OCI configures and load the OS as a UEFI hence the EFI configuration (or eps flag parameter), I have not seen this on other cloud providers yet, but I have seen it on local loads of linux using various other versions of them.

Well let me make it even more clear I have seen the /boot/efi/EFI/distro on other cloud servers, but it's usually empty, so there no mount listed in the fstab.

Section 1.5.1 Restricting core dumps

################################################
#### 1.5.1 Ensure core dumps are restricted ####
################################################
function core_dumps() {
	{
		start_spinner 'Restricting Core Dumps...'
		echo ""
		xargs -n 1 cp -v /etc/security/limits.conf <<<"${BACKUP} /etc/security/limits.conf.bak"
		echo '* hard core 0' >> /etc/security/limits.conf
		stop_spinner $?
	} | tee -a $LOG
}

This just adds "hard core 0" to the limits.conf file.

Section 1.5.3 Ensure ASLR is Enabled

###########################################################################
#### 1.5.3 Ensure address space layout randomization (ASLR) is enabled ####
###########################################################################
function sysctl_conf() {
	{
		start_spinner 'Configuring Sysctl and Tuning Kernel Parameters...'
		echo ""
		xargs -n 1 cp -v /etc/sysctl.conf <<< "${BACKUP} /etc/sysctl.conf.bak"
		no_show << "EOF" > /etc/sysctl.conf
		##################################################################################################
		####       Hardened SysCtl Configuration File edited to match CIS level 1 requirements        ####
		####       for questions or changles please contact Phil Connor contact@mylinux.work          ####
		##################################################################################################

		#### Controls the System Request debugging functionality of the kernel
		kernel.sysrq = 0

		#### Controls whether core dumps will append the PID to the core filename.
		#### Useful for debugging multi-threaded applications.
		kernel.core_uses_pid = 1

		##################################
		#### GENERAL SECURITY OPTIONS ####
		##################################

		#### Automatically Reboot Server 30 Seconds after a Kernel Panic
		vm.panic_on_oom = 1
		kernel.panic = 30
		kernel.panic_on_oops = 30

		#### Enable ExecShield
		#kernel.exec-shield = 1

		kernel.dmesg_restrict = 1
		kernel.kptr_restrict = 1
		kernel.yama.ptrace_scope = 1

		#### 1.5.3 Ensure address space layout randomization (ASLR) is enabled 
		kernel.randomize_va_space = 2

		#################################
		#### COMMUNICATIONS SECURITY ####
		#################################

		#### 3.1.1 Ensure IP forwarding is disabled
		net.ipv4.ip_forward = 0
		net.ipv4.conf.all.forwarding = 0
		net.ipv4.conf.default.forwarding = 0
		net.ipv6.conf.all.forwarding = 0
		net.ipv6.conf.default.forwarding = 0

		#### 3.1.2 Ensure packet redirect sending is disabled
		net.ipv4.conf.all.send_redirects = 0
		net.ipv4.conf.default.send_redirects = 0

		#### 3.2.1 Ensure source routed packets are not accepted
		net.ipv4.conf.all.accept_source_route = 0
		net.ipv4.conf.default.accept_source_route = 0

		#### 3.2.2 Ensure ICMP redirects are not accepted
		net.ipv4.conf.all.accept_redirects = 0
		net.ipv4.conf.default.accept_redirects = 0

		#### 3.2.3 Ensure secure ICMP redirects are not accepted
		net.ipv4.conf.all.secure_redirects = 0
		net.ipv4.conf.default.secure_redirects = 0

		#### 3.2.4 Ensure suspicious packets are logged
		net.ipv4.conf.all.log_martians = 1
		net.ipv4.conf.default.log_martians = 1

		#### 3.2.5 Ensure broadcast ICMP requests are ignored
		net.ipv4.icmp_echo_ignore_broadcasts = 1
		net.ipv4.tcp_timestamps = 0

		#### 3.2.6 Ensure bogus ICMP responses are ignored
		net.ipv4.icmp_ignore_bogus_error_responses = 1

		#### 3.2.7 Ensure Reverse Path Filtering is enabled
		net.ipv4.conf.all.rp_filter = 1
		net.ipv4.conf.default.rp_filter = 1

		#### 3.2.8 Ensure TCP SYN Cookies is enabled
		net.ipv4.tcp_syncookies = 1
		net.ipv4.tcp_syn_retries = 5
		net.ipv4.tcp_synack_retries = 2
		net.ipv4.tcp_max_syn_backlog = 4096

		#### 3.3.1 Ensure IPv6 router advertisements are not accepted
		net.ipv6.conf.all.accept_ra = 0
		net.ipv6.conf.default.accept_ra = 0

		#### 3.3.1.1 Ensure IPv6 router advertisements are not accepted
		net.ipv4.conf.all.accept_source_route=0
		net.ipv6.conf.all.accept_source_route=0
		net.ipv4.conf.default.accept_source_route=0
		net.ipv6.conf.default.accept_source_route=0

		#### 3.3.2 Ensure IPv6 redirects are not accepted
		net.ipv4.conf.all.accept_redirects = 0
		net.ipv6.conf.all.accept_redirects = 0
		net.ipv4.conf.default.accept_redirects = 0
		net.ipv6.conf.default.accept_redirects = 0

		#### 3.3.3 Ensure IPv6 is disabled
		net.ipv6.conf.all.disable_ipv6 = 1
		net.ipv6.conf.default.disable_ipv6 = 1
		net.ipv6.conf.lo.disable_ipv6 = 1

		#### Reduce KeepAlive
		net.ipv4.tcp_keepalive_time = 300
		net.ipv4.tcp_keepalive_probes = 5
		net.ipv4.tcp_keepalive_intvl = 15

		fs.suid_dumpable = 0

		#########################
		#### Oracle Settings ####
		#########################

		# oracle-ebs-server-R12-preinstall setting for fs.file-max is 6815744
		fs.file-max = 6815744
		# oracle-ebs-server-R12-preinstall setting for kernel.sem is '256 32000 100 142'
		kernel.sem = 256 32000 100 142
		# oracle-ebs-server-R12-preinstall setting for kernel.shmmni is 4096
		kernel.shmmni=4096
		# oracle-ebs-server-R12-preinstall setting for kernel.shmall is 1073741824 on x86_64
		# oracle-ebs-server-R12-preinstall setting for kernel.shmall is 2097152 on i386
		kernel.shmall=1073741824
		# oracle-ebs-server-R12-preinstall setting for kernel.shmmax is 4398046511104 on x86_64
		# oracle-ebs-server-R12-preinstall setting for kernel.shmmax is 4294967295 on i386
		kernel.shmmax=4398046511104
		# oracle-ebs-server-R12-preinstall setting for kernel.panic_on_oops is 1
		kernel.panic_on_oops=1
		# oracle-ebs-server-R12-preinstall setting for kernel.msgmax is 8192
		kernel.msgmax = 8192
		# oracle-ebs-server-R12-preinstall setting for kernel.msgmni is 2878
		kernel.msgmni=2878
		# oracle-ebs-server-R12-preinstall setting for kernel.msgmnb is 65535
		kernel.msgmnb=65535
		# oracle-ebs-server-R12-preinstall setting for net.core.rmem_default is 262144
		net.core.rmem_default=262144
		# oracle-ebs-server-R12-preinstall setting for net.core.rmem_max is 4194304
		net.core.rmem_max=4194304
		# oracle-ebs-server-R12-preinstall setting for net.core.wmem_default is 262144
		net.core.wmem_default=262144
		# oracle-ebs-server-R12-preinstall setting for net.core.wmem_max is 1048576
		net.core.wmem_max=1048576
		# oracle-ebs-server-R12-preinstall setting for fs.aio-max-nr is 1048576
		fs.aio-max-nr = 1048576
		# oracle-ebs-server-R12-preinstall setting for net.ipv4.ip_local_port_range is 9000 65500
		net.ipv4.ip_local_port_range = 9000 65500
EOF
		sysctl -p
		stop_spinner $?
	} | tee -a $LOG
}

This is the sysctl.conf config that I have refined over time, the servers perform fairly well with these settings, I left the "Oracle Settings" in there and they can be safely removed if you want.

Section 1.5.4 Ensure prelink is disabled

f##########################################
#### 1.5.4 Ensure prelink is disabled ####
##########################################
function pre_link() {
	{
		start_spinner 'Disabling and removing Prelink...'
		echo ""
		if [ -f /usr/sbin/prelink ]; then
			prelink -ua
			${PAKMGR} remove prelink
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Simply put if prelink is enabled of found disable and remove it.

Section 1.6.1.4 Ensure SE Troubleshoot is not installed

########################################################
#### 1.6.1.4 Ensure SETroubleshoot is not installed ####
########################################################
function se_troubleshoot_mcs() {
	{
		start_spinner 'Removing SE Troubleshoot and MCS Translation Service...'
		echo ""
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			if [ -f /usr/bin/setroubleshoot ]; then
				${PAKMGR} remove setroubleshoot 
			fi
		fi
		#### 1.6.1.5 Ensure the MCS Translation Service (mcstrans) is not installed ####
		if [ "${OS}" = ubuntu ]; then
			systemctl list-units --type=service --all | grep mcstrans
			if ! 1; then
				${PAKMGR} remove policycoreutils
			fi
		else
			systemctl list-units --type=service --all | grep mcstrans
			if ! 1; then
				${PAKMGR} remove mcstrans
			fi
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Just checking for and removing SE Troubleshoot, I also have the mctrans check/removal in here.  

Section 1.6.1.6 Ensure no Unconfined Daemons Exist

######################################################
#### 1.6.1.6 Ensure no unconfigured daemons exist ####
######################################################
function unconf_daemons() {
	{
		start_spinner 'Ensuring no unconfigered daemons exist...'
		echo ""
		process=$(ps -eZ)
		echo "${process}" | grep -E "initrc" | grep -Evw "tr|ps|grep|bash|awk" | tr ':' ' ' | awk '{ print $NF }'
		stop_spinner $?
	} | tee -a $LOG
}

this check is designed to find all unconfined things that are running, what this means is all services a confined under selinux these are considered undefined domains, these include scripts that you may use and put in the /usr/local/bin/ and only include scripts that you run as a service or a loop.

the problem with this check is on new spin ups you've not loaded any of those so this will not detect anything, in fact you will not have any idea about this until Nessus alerts you. Just remember to confine your scripts with selinux to avoid any future issues.

Section 1.6.2 Ensure SELinix is Installed

###########################################
#### 1.6.2 Ensure SELinux is installed ####
###########################################
function se_linux() {
	{
		start_spinner 'Ensuring SELinux is installed...'
		echo ""
		if [ "${OS}" = ubuntu ]; then
			${PAKMGR} install libselinux1
		else
			if ! rpm -qa libselinux; then
				${PAKMGR} install libselinux
			fi
		fi
		stop_spinner $?
	} | tee -a $LOG
}

This again explains itself....

Section 1.7.1.1 Ensure the message of the day is configured

##################################################################
#### 1.7.1.1 Ensure message of the day is configured properly ####
##################################################################
function banners() {
	{
		start_spinner 'Configuring all Message Banners...'
		echo ""
		if [ "${OS}" = ubuntu ]; then
			chmod -x /etc/update-motd.d/*
			touch /etc/motd
		else
			xargs -n 1 cp -v /etc/motd <<< "${BACKUP} /etc/motd.bak"
		fi	
		echo "   All activities performed on this system will be monitored." > /etc/motd
		#### 1.7.1.2 Ensure local login warning banner is configured properly ####
		xargs -n 1 cp -v /etc/issue <<< "${BACKUP} /etc/issue.bak"
		echo "   All activities performed on this system will be monitored." > /etc/issue
		#### 1.7.1.3 Ensure remote login warning banner is configured properly ####
		xargs -n 1 cp -v /etc/issue.net <<< "${BACKUP} /etc/issue.net.bak"
		echo "   All activities performed on this system will be monitored." > /etc/issue.net
		#### 1.7.1.4 Ensure permissions on /etc/motd ore configured ####
		chmod 644 /etc/motd
		chown root.root /etc/motd
		#### 1.7.1.5 Ensure permissions on /etc/issue are configured ####
		chmod 644 /etc/issue
		chown root.root /etc/issue
		#### 1.7.1.6 Ensure permissions on /etc/issue.net are configured ####
		chmod 644 /etc/issue.net
		chown root.root /etc/issue.net
		stop_spinner $?
	} | tee -a $LOG
}

The MOTD - Nessus does not allow for a very long motd so if you have one it will ding you on it and issue and issue.net since it expects all of those to be the same,

I have a banner work around that I use on all the servers that I maintain which doesn't get dinged by Nessus and it shows me the  info I need as well as a long message for the users that ssh in to the boxes, you will see it a little later in this script. I also added some color to it with lolcat to catch the users attn.

Here is an example of it enlarged

MyLinux.Work - Login Banner 

Section 1.8 Ensure Updates, Patches and Security Packages are Installed

#####################################################################################
#### 1.8 ensure updates, patches, and additional security software are installed ####
#####################################################################################
function update_security() {
	{
		start_spinner 'Checking and Installing Security Updates...'
		echo ""
		if [ "${OS}" = ubuntu ]; then
			${PAKMGR} autoremove	
			${PAKMGR} update 
			"${PAKMGR} install -y --only-upgrade $(apt-get --just-print upgrade | awk 'tolower($4) ~ /.*security.*/ || tolower($5) ~ /.*security.*/ {print $2}' | sort | uniq)"
		else
			${PAKMGR} clean all
			${PAKMGR} check-update --security
			${PAKMGR} update --security 
		fi
		stop_spinner $?
	} | tee -a $LOG
}

This checks and updates just the security packages nothing else

Section 2.1 Ensure the Inet Service are Disabled

#############################
#### 2.1 inetd Services ####
############################
function inet_service() {
	{
		start_spinner 'Disabling Unused/Unsecure inetd Services...'
		echo ""
		#### 2.1.1 Ensure chargen services are not enabled ####
		if [ "${OS}" = ubuntu ]; then
			grep -R "^chargen" /etc/inetd.*
			if ! 2; then
				systemctl stop chargen
				systemctl disable chargen
			fi
		else
			systemctl is-enabled chargen-dgram
			if ! 1; then
				systemctl stop chargen-dgram 
				systemctl disable chargen-dgram
			fi
			systemctl is-enabled chargen-stream
			if ! 1; then
				systemctl stop chargen-stream 
				systemctl disable chargen-stream 
			fi
		fi
		#### 2.1.2 Ensure daytime services are not enabled ####
		if [ "${OS}" = ubuntu ]; then
			grep -R "^daytime" /etc/inetd.*
			if ! 2; then
				systemctl stop daytime
				systemctl disable daytime
			fi
		else
			systemctl is-enabled daytime-dgram
			if ! 1; then
				systemctl stop daytime-dgram 
				systemctl disable daytime-dgram
			fi
			systemctl is-enabled daytime-stream
			if ! 1; then
				systemctl stop daytime-stream 
				systemctl disable daytime-stream
			fi
		fi
		#### 2.1.3 Ensure discard services are not enabled ####
		if [ "${OS}" = ubuntu ]; then
			grep -R "^discard" /etc/inetd.*
			if ! 2; then
				systemctl stop discard 
				systemctl disable discard 
			fi
		else
			systemctl is-enabled discard-dgram
			if ! 1; then
				systemctl stop discard-dgram 
				systemctl disable discard-dgram 
			fi
			systemctl is-enabled discard-stream
			if ! 1; then
				systemctl stop discard-stream 
				systemctl disable discard-stream
			fi
		fi
		#### 2.1.4	Ensure echo services are not Enabled ####
		if [ "${OS}" = ubuntu ]; then
			grep -R "^echo" /etc/inetd.*
			if ! 2; then
				systemctl stop echo 
				systemctl disable echo
			fi
		else
			systemctl is-enabled echo-stream
			if ! 1; then
				systemctl stop echo-stream 
				systemctl disable echo-stream 
			fi
		fi
		#### 2.1.5 Ensure time services are not enabled ####
		if [ "${OS}" = ubuntu ]; then
			grep -R "^time" /etc/inetd.*
			if ! 2; then
				systemctl stop time
				systemctl disable time
			fi
		else
			systemctl is-enabled time-dgram
			if ! 1; then
				systemctl stop time-dgram 
				systemctl disable time-dgram
			fi
			systemctl is-enabled time-stream
			if ! 1; then
				systemctl stop time-stream 
				systemctl disable time-stream 
			fi
		fi
		#### 2.1.6 Ensure rsh server is not enabled Ubuntu ####
		if [ "${OS}" = ubuntu ]; then
			grep -R "^shell" /etc/inetd.*
			if ! 2; then
				systemctl stop shell
				systemctl disable shell
			fi
			grep -R "^login" /etc/inetd.*
			if ! 2; then
				systemctl stop login
				systemctl disable login
			fi
			grep -R "^exec" /etc/inetd.*
			if ! 2; then
				systemctl stop exec
				systemctl disable exec
			fi
		fi
		#### 2.1.6 Ensure tftp server is not enabled Others ####
		systemctl is-enabled tftp
		if ! 1; then
			systemctl stop tftp 
			systemctl disable tftp
		fi
		#### 2.1.7 Ensure talk server is not enabled Ubuntu ####
		if [ "${OS}" = ubuntu ]; then
			grep -R "^talk" /etc/inetd.*
			if ! 2; then
				systemctl stop talk
				systemctl disable talk
			fi
			grep -R "^ntalk" /etc/inetd.*
			if ! 2; then
				systemctl stop ntalk
				systemctl disable ntalk
			fi
		fi
		#### 2.1.9 Ensure tftp server is not enabled Ubuntu ####
		if [ "${OS}" = ubuntu ]; then
			grep -R "^tftp" /etc/inetd.*
			if ! 2; then
				systemctl stop tftp
				systemctl disable tftp
			fi
		fi
		#### 2.1.8 Ensure telnet server is not enabled Ubuntu ####
		if [ "${OS}" = ubuntu ]; then
			grep -R "^telnet" /etc/inetd.*
			if ! 2; then
				systemctl stop telnet
				systemctl disable telnet
			fi
		fi
		#### 2.1.10 Ensure xinetd is not enabled All ####
		systemctl is-enabled xinetd
		if ! 1; then
			systemctl stop xinetd 
			systemctl disable xinetd
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Disabling all insecure inet services

Section 2.2.1.1 Ensure Time Synchronization is in Use

#######################################################	
#### 2.2.1.1 Ensure time synchronization is in use ####
#######################################################

#### 2.2.1.2 Ensure ntp is configured ####
function ntp_config() {
	{
		start_spinner 'Configuring NTP Service...'
		echo ""
		if [ "${OS}" = ubuntu ]; then
				DEBIAN_FRONTEND=noninteractive ${PAKMGR} install ntp
		else
			${PAKMGR} install ntp		
		fi
		if [ "${OS}" = centos ]; then
			var1=${OS}
		elif [ "${OS}" = ubuntu ]; then
			var1=${OS}
		else
			var1=rhel
		fi
		if [ "${OS}" = centos ]; then
			sed -i 's/OPTIONS="-g"/OPTIONS="-u ntp:ntp"/g' /etc/sysconfig/ntpd
			if ! grep -qi "server 127.127.1.0" ${NTP_FILE}; then
				echo "server  127.127.1.0  #local clock" >> ${NTP_FILE} 
				echo "fudge   127.127.1.0  stratum 10" >> ${NTP_FILE}
			fi
			if ! grep -qi "disable monitor" ${NTP_FILE}; then 
				echo "disable monitor" >> ${NTP_FILE} 
			fi
			systemctl enable --now ntpd 		
		elif [ "${OS}" = ubuntu ]; then
			if ! grep -qi "server 127.127.1.0" ${NTP_FILE}; then
				echo "server  127.127.1.0  #local clock" >> ${NTP_FILE} 
				echo "fudge   127.127.1.0  stratum 10" >> ${NTP_FILE}
			fi
			if ! grep -qi "disable monitor" ${NTP_FILE}; then 
				echo "disable monitor" >> ${NTP_FILE} 
			fi
			if ! grep -qi "RUNASUSER=ntp" /etc/init.d/ntp; then 
				echo "RUNASUSER=ntp" >> /etc/init.d/ntp
			fi
		else
			xargs -n 1 cp -v ${NTP_FILE} <<< ""${BACKUP} ${NTP_FILE}.bak""
			sed -i 's/restrict default nomodify notrap nopeer noquery/restrict default nomodify notrap nopeer noquery/p' ${NTP_FILE}
			sed -i '8 s/restrict default nomodify notrap nopeer noquery/restrict -4 default kod nomodify notrap nopeer noquery/g' ${NTP_FILE}
			sed -i '9 s/restrict default nomodify notrap nopeer noquery/restrict -6 default kod nomodify notrap nopeer noquery/g' ${NTP_FILE} 
			sed -i 's/OPTIONS="-g"/OPTIONS="-u ntp:ntp"/g' /etc/sysconfig/ntpd
			if ! grep -qi "server 127.127.1.0" "${NTP_FILE}"; then
				echo "server  127.127.1.0  #local clock" >> ${NTP_FILE} 
				echo "fudge   127.127.1.0  stratum 10" >> ${NTP_FILE}
			fi
			if ! grep -qi "disable monitor" ${NTP_FILE}; then 
				echo "disable monitor" >> ${NTP_FILE} 
			fi
			systemctl enable --now ntpd 
			systemctl restart ntpd   	
		fi
		sed -i "s/#server 0.$var1.pool.ntp.org iburst/server 0.$var1.pool.ntp.org iburst/g" ${NTP_FILE} 
		sed -i "s/#server 1.$var1.pool.ntp.org iburst/server 1.$var1.pool.ntp.org iburst/g" ${NTP_FILE}
		sed -i "s/#server 2.$var1.pool.ntp.org iburst/server 2.$var1.pool.ntp.org iburst/g" ${NTP_FILE}
		sed -i "s/#server 3.$var1.pool.ntp.org iburst/server 3.$var1.pool.ntp.org iburst/g" ${NTP_FILE}
		systemctl enable --now ntp
		systemctl enable --now systemd-timesyncd
		stop_spinner $?
	} | tee -a $LOG
}

#### 2.2.1.3 Ensure chrony is configured ####
function chrony_cfg() {
	{
		start_spinner 'Configuring Chrony Service...'
		echo ""
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			if [ "${OSVER}" = 8 ] || [ "${OSVER}" =  9 ]; then
					${PAKMGR} install chrony ntpstat
			fi
		elif [ "${OS}" = ubuntu ]; then
			DEBIAN_FRONTEND=noninteractive ${PAKMGR} install chrony
		else
			${PAKMGR} install chrony
		fi
		if [ "${OS}" = centos ]; then
			var1=${OS}
		else
			var1=rhel
		fi
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			if [ "${OSVER}" = 7 ]; then
				if ! grep $var1.pool.ntp.org /etc/chrony.conf; then
					echo '#################################################################'
					echo '####   Using public servers from the pool.ntp.org project.   ####'
					echo '####   Added for CIS Level 1 Compatibility for questions     ####'
					echo '####       Contact Phil Connor contact@mylinux.work          ####'
					echo '#################################################################'
					echo "server 0.$var1.pool.ntp.org iburst"
					echo "server 1.$var1.pool.ntp.org iburst"
					echo "server 2.$var1.pool.ntp.org iburst"
					echo "server 3.$var1.pool.ntp.org iburst"
					sed -i "s/#server 0.$var1.pool.ntp.org iburst/server 0.$var1.pool.ntp.org iburst/g" /etc/chrony.conf 
					sed -i "s/#server 1.$var1.pool.ntp.org iburst/server 1.$var1.pool.ntp.org iburst/g" /etc/chrony.conf
					sed -i "s/#server 2.$var1.pool.ntp.org iburst/server 2.$var1.pool.ntp.org iburst/g" /etc/chrony.conf
					sed -i "s/#server 3.$var1.pool.ntp.org iburst/server 3.$var1.pool.ntp.org iburst/g" /etc/chrony.conf
					sed -i 's/server 169.254.169.254 iburst/#server 169.254.169.254 iburst/g' /etc/chrony.conf
					sed -i 's/OPTIONS=""/OPTIONS="-u chrony"/g' /etc/sysconfig/chronyd
				fi	
			fi
		fi			
			if [ "${OSVER}" = 8 ] || [ "${OSVER}" =  9 ]; then
				if ! grep $var1.pool.ntp.org /etc/chrony.conf; then 
					chronyd -q 'server 2.rhel.pool.ntp.org iburst'
					sed -i 's/OPTIONS="-F 2"/OPTIONS="-u chrony"/g' /etc/sysconfig/chronyd
					chronyc sourcestats -v
				fi
			systemctl enable --now chronyd
			fi
		if [ "${OS}" = ubuntu ]; then
			if grep -q 'OPTIONS=.*' /etc/sysconfig/chronyd; then
				sed -i -E -e 's/\s*-u\s+\w+\s*/ /' -e 's/^([\s]*OPTIONS=["]?[^"]*)("?)/\1 -u chrony\2/' /etc/sysconfig/chronyd
				if  [ ! -f /etc/sysconfig/chronyd ]; then 
					touch /etc/sysconfig/chronyd
					echo "OPTIONS="-u chrony"" /etc/sysconfig/chronyd
				fi
			fi
			chronyc sourcestats -v
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Configuring NTP and or Chrony services

Section 2.2.2 Ensure X Windows is not installed

#######################################################
#### 2.2.2 Ensure X Window System is not installed ####
#######################################################
function unsecure_services() {
	{
		start_spinner 'Removing X11 and Disabling Insecure Protocols...'
		echo ""
		if [ "${OS}" = ubuntu ]; then
			${PAKMGR} remove xorg*
			${PAKMGR} remove xserver-xorg*
		else
			${PAKMGR} remove xorg-x11* 
		fi
		a=( "$(systemctl list-units --type=service --all)" )
		#### 2.2.3 Ensure Avahi Server is not installed ####
		if echo "${a[@]}" | grep avahi-daemon.service; then	
			systemctl stop avahi-daemon 
			systemctl disable avahi-daemon
		fi
		### 2.2.4 Ensure CUPS is not enabled ###
		if echo "${a[@]}" | grep cups.service; then 
			systemctl stop cups
			systemctl disable cups
		fi
		#### 2.2.5 Ensure DHCP Server is not enabled ####
		if  [ "${OS}" = ubuntu ]; then
			if echo "${a[@]}" | grep isc-dhcp-server.service; then
				systemctl stop isc-dhcp-server
				systemctl disable isc-dhcp-server
			fi
		else
			if echo "${a[@]}" | grep dhcpd.service; then 
				systemctl stop dhcpd
				systemctl disable dhcpd
			fi
		fi
		#### 2.2.6 Ensure LDAP Server is not enabled ####
		if echo "${a[@]}" | grep slapd.service; then 
			systemctl stop slapd
			systemctl disable slapd
		fi
		#### 2.2.7 Ensure NFS and RPC are not enabled ####
		if [ "${OS}" = ubuntu ]; then
			if echo "${a[@]}" | grep nfs-kernel-server.service; then
				systemctl stop nfs-kernel-server
				systemctl disable nfs-kernel-server
			fi
		else
			if echo "${a[@]}" | grep nfs-server.service; then
				systemctl stop nfs-server
				systemctl disable nfs-server
			fi
			if echo "${a[@]}" | grep nfs.service; then
				systemctl stop nfs
				systemctl disable nfs
			fi		
		fi
		if echo "${a[@]}" | grep rpcbind.service; then 
			systemctl stop rpcbind
			systemctl disable rpcbind
		fi
		#### 2.2.8 Ensure DNS Server is not enabled ####
		if echo "${a[@]}" | grep named.service; then 
			systemctl stop named
			systemctl disable named
		fi
		if [ "${OS}" = ubuntu ]; then
			if echo "${a[@]}" | grep bind9.service; then 
				systemctl stop bind9
				systemctl disable bind9
			fi
		fi
		#### 2.2.9 Ensure FTP Server is not enabled ####
		if echo "${a[@]}" | grep vsftpd.service; then 
			systemctl stop vsftpd
			systemctl disable vsftpd
		fi
		#### 2.2.10 Ensure HTTP Server is not enabled ####
		if [ "${OS}" = ubuntu ]; then
			if echo "${a[@]}" | grep apache2.service; then 
				systemctl stop apache2
				systemctl disable apache2
			fi
		else
			if echo "${a[@]}" | grep httpd.service; then 
				systemctl stop httpd
				systemctl disable httpd
			fi
		fi
		#### 2.2.11 Ensure IMAP and POP3 server are not enabled ####
		if echo "${a[@]}" | grep dovecot.service; then 
			systemctl stop dovecot
			systemctl disable dovecot
		fi
		#### 2.2.12 Ensure Samba is not enabled ####
		if echo "${a[@]}" | grep smb.service; then 
			systemctl stop smb
			systemctl disable smb
		fi
		#### 2.2.13 Ensure HTTP Proxy Server is not enabled ####
		if echo "${a[@]}" | grep squid.service; then 
			systemctl stop squid
			systemctl disable squid
		fi
		#### 2.2.14 Ensure SNMP Server is not enabled ####
		if echo "${a[@]}" | grep snmpd.service; then 
			systemctl stop snmpd
			systemctl disable snmpd
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Removing and disabling additional insecure services

Section 2.2.15 Ensure Postfix Only Delivers Locally 

#############################################################################
#### 2.2.15 Ensure mail transfer agent is configured for local-only mode ####
#############################################################################
function mail_config() {
	{
		start_spinner 'Configuring Postfix MTA...'
		echo ""
		if [ "${OS}" = ubuntu ]; then
			debconf-set-selections <<< ""postfix postfix/mailname string "${HOSTNAME}"""
			debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Local Only'"
			DEBIAN_FRONTEND=noninteractive ${PAKMGR} install postfix --assume-yes
			sed -i 's/inet_interfaces = all/inet_interfaces = localhost/g' /etc/postfix/main.cf
		else
			${PAKMGR} install postfix
			sed -i 's/inet_interfaces = localhost/inet_interfaces = loopback-only/g' /etc/postfix/main.cf
		fi
		# shellcheck disable=SC2016
		sed -i 's/#smtpd_banner = $myhostname ESMTP $mail_name/smtpd_banner = $myhostname ESMTP/g' /etc/postfix/main.cf
		# shellcheck disable=SC2016
		sed -i 's/smtpd_banner = $myhostname ESMTP ($mail_version)/#smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)/g' /etc/postfix/main.cf
		if ! grep -qi "mailbox_size_limit" /etc/postfix/main.cf; then
			echo "mailbox_size_limit = 0" >> /etc/postfix/main.cf
		fi
		postconf -e message_size_limit=0
		postconf -e mailbox_size_limit = 0
		systemctl enable --now postfix 
		stop_spinner $?
	} | tee -a $LOG
}

This installs and configures Postfix to deliver all mail locally only

Section 2.2.x Disabling Additional inet Services

################################################
#### 2.2.x Disable Additional inet Services ####
################################################ 
function addon_inet_services() {
	{
		start_spinner 'Disabling Additional Unsecure Services...'
		echo ""
		a=( "$(systemctl list-units --type=service --all)" )
		### 2.2.16 Ensure NIS Server is not enabled ###
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			if echo "${a[@]}" | grep ypserv.service; then 
				systemctl stop ypserv 
				systemctl disable ypserv
			fi
		### 2.2.16 Ensure rsync service is not enabled Ubuntu ###
		elif [ "${OS}" = ubuntu ]; then
			if echo "${a[@]}" | grep rsync.service; then 
				systemctl stop rsync
				systemctl disable rsync
			fi		
		fi
		### 2.1.17 Ensure rsh server is not enabled ###
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle ]]; then
			if echo "${a[@]}" | grep rsh.socket.service; then 
				systemctl stop rsh.socket 
				systemctl disable rsh.socket
			fi
			if echo "${a[@]}" | grep rlogin.socket.service; then 
				systemctl stop rlogin.socket 
				systemctl disable rlogin.socket 
			fi
			if echo "${a[@]}" | grep rexec.socket.service; then 
				systemctl stop rexec.socket 
				systemctl disable rexec.socket
			fi
		### 2.2.17 Ensure NIS Server is not enabled Ubuntu ###
		elif [ "${OS}" = ubuntu ]; then
			if echo "${a[@]}" | grep nis.service; then 
				systemctl stop nis
				systemctl disable nis
			fi
		fi
		### 2.2.18 Ensure talk server is not enabled ###
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle ]]; then
			if echo "${a[@]}" | grep ntalk.service; then
				systemctl stop ntalk 
				systemctl disable ntalk 
			fi
			### 2.2.19 Ensure telnet server is not enabled ###
			if echo "${a[@]}" | grep telnet.socket.service; then 
				systemctl stop telnet.socket 
				systemctl disable telnet-socket
			fi
			### 2.2.20 Ensure tftp server is not enabled ###
			if echo "${a[@]}" | grep tftp.socket.service; then 
				systemctl stop tftp.socket 
				systemctl disable tftp-socket
			fi
			### 2.2.21 Ensure rsync service is not enabled ###
			if echo "${a[@]}" | grep rsyncd.service; then 
				systemctl stop rsyncd 
				systemctl disable rsyncd
			fi
		fi
		stop_spinner $?
	} | tee -a $LOG
}

For some reason the manual breaks up a lot of the process. I tried to write this script to match the flow of the manual the best I could so that finding where something was not working would be easier to track down. 

Section 2.3 Ensure Insecure Service Clients are not Installed

###############################################################
#### 2.3 Ensure Insecure Service Clients are not Installed ####
###############################################################
function service_clients() {
	{
		start_spinner 'Removing Insecure Service Clients...'
		echo ""
		a=( "$(systemctl list-units --type=service --all)" )
		#### 2.3.1 Ensure NIS Client is not installed ####
		if [ "${OS}" = ubuntu ]; then
			if echo "${a[@]}" | grep nis.service; then 
				${PAKMGR} remove nis
			fi
		else
			if echo "${a[@]}" | grep ypbind.service; then 
				${PAKMGR} remove ypbind
			fi
		fi
		#### 2.3.2 Ensure rsh client is not installed ####
		if [ "${OS}" = ubuntu ]; then
			if echo "${a[@]}" | grep rsh-client.service; then 
				${PAKMGR} remove rsh-client rsh-redone-client
			fi
		else
			if echo "${a[@]}" | grep rsh.service; then 
				${PAKMGR} remove rsh
			fi
		fi
		#### 2.3.3 Ensure talk client is not installed ####
		if echo "${a[@]}" | grep talk.service; then 
			${PAKMGR} remove talk
		fi
		#### 2.3.4 Ensure telnet client is not installed ####
		if echo "${a[@]}" | grep telnet.service; then 
			${PAKMGR} remove telnet
		fi
		#### 2.3.5 Ensure LDAP client is not installed ####
		if [ "${OS}" = ubuntu ]; then
			if echo "${a[@]}" | grep libnss-ldap.service; then 
				${PAKMGR} remove libnss-ldap
			fi
			if echo "${a[@]}" | grep libpam-ldap.service; then 
				${PAKMGR} remove libpam-ldap
			fi
			if echo "${a[@]}" | grep ldap-utils.service; then 
				${PAKMGR} remove ldap-utils
			fi
		else
			if echo "${a[@]}" | grep openldap-clients.service; then 
				${PAKMGR} remove openldap-clients
			fi
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Section 3.4 TCP Wrappers 

##########################
#### 3.4 TCP Wrappers ####
##########################
function tcp_wrappers() {
	{
		start_spinner 'Configuring TCP Wrappers...'
		echo ""
		#### 3.4.1 Ensure TCP Wrappers is installed ####
		if [ "${OS}" = ubuntu ]; then
			${PAKMGR} install tcpd
		else
			${PAKMGR} list | grep tcp_wrappers
			if ! 1; then
				${PAKMGR} install tcp_wrappers
			fi
		fi
		#### 3.4.2 Ensure /etc/hosts.allow is configured ####
		echo ALL:"${VLANIP}" > /etc/hosts.allow
		#### 3.4.3 Ensure /etc/hosts.deny is configured ####
		echo "ALL:ALL" >> /etc/hosts.deny
		#### 3.4.4 Ensure permissions on /etc/hosts.allow are configured ####
		chown root.root /etc/hosts.allow
		chmod 644 /etc/hosts.allow
		#### 3.4.5 Ensure permissions on /etc/hosts.deny are configured ####
		chown root.root /etc/hosts.deny
		chmod 644 /etc/hosts.deny
		stop_spinner $?
	}
}

This is no longer supported in Redhat based distro's beyond Version 7

Section 3.5 Uncommon Network Protocals

########################################
#### 3.5 Uncommon Network Protocols ####
########################################
function uncommon_protocols() {
	{
		start_spinner 'Disabling Uncommon Network Protocols...'
		echo ""
		MODPRO="/etc/modprobe.d/cis.conf"
		#### 3.5.1 Ensure DCCP is disabled ####
		echo "install dccp /bin/true" >> ${MODPRO}
		lsmod | grep -qi dccp
		if ! 1; then		
			rmmod dccp 
		fi
		#### 3.5.2 Ensure SCTP is disabled ####
		echo "install sctp /bin/true" >> ${MODPRO}
		lsmod | grep -qi sctp
		if ! 1; then		
			rmmod sctp 
		fi
		#### 3.5.3 ensure RDS is disabled ####
		echo "install rds /bin/true" >> ${MODPRO}
		lsmod | grep -qi rds
		if ! 1; then		
			rmmod rds 
		fi
		#### 3.5.4 Ensure TIPC is disabled ####
		echo "install tipc /bin/true" >> ${MODPRO}
		lsmod | grep -qi tipc
		if ! 1; then		
			rmmod tipc 
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Section 3.6 Firewall Configuration

########################################
#### 3.6 Firewall Configuration AWS ####
########################################
function iptables_config() {
	{
		start_spinner 'Configuring IP Tables...'
		echo ""
		### 3.6.1 Ensure iptables is installed ###
		if [ "${OS}" = ubuntu ]; then
			ufw --force disable
			debconf-set-selections <<< "iptables-persistent iptables-persistent/autosave_v4 boolean true"
			debconf-set-selections <<< "iptables-persistent iptables-persistent/autosave_v6 boolean true"
			DEBIAN_FRONTEND=noninteractive ${PAKMGR} install iptables
			DEBIAN_FRONTEND=noninteractive ${PAKMGR} install iptables-persistent --assume-yes
			service netfilter-persistent start
			service netfilter-persistent save
		else
			systemctl stop firewalld.service 
			systemctl mask firewalld.service 
			systemctl daemon-reload 
			${PAKMGR} install iptables-utils iptables-services
		fi
		#### 3.6.2 Ensure default deny firewall policy ####
		#### Configure IPv4 #### 
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			systemctl enable --now iptables
			cp $IPTBL $BACKUP
			mv -f ${IPTBL} ${IPTBL}.bak
			touch ${IPTBL}
		fi
		# Flush Iptables rules
		iptables -F
		# Forcing SYN packets check
		iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
		# Forcing Fragments packets check
		iptables -A INPUT -f -j DROP
		# Dropping malformed XMAS packets
		iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
		# Drop all NULL packets
		iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
		# Limiting pings to 1 per second
		iptables -N PACKET
		iptables -A DEFAULT_RULES -p icmp -m limit --limit 3/sec --limit-burst 25 -j ACCEPT
		# Setup Connection Tracking
		iptables -N STATE_TRACK
		iptables -A STATE_TRACK -m state --state RELATED,ESTABLISHED -j ACCEPT
		iptables -A STATE_TRACK -m state --state INVALID -j DROP
		# Discouraging Port Scanning
		iptables -N PORTSCAN
		iptables -A PORTSCAN -p tcp --tcp-flags ACK,FIN FIN -j DROP
		iptables -A PORTSCAN -p tcp --tcp-flags ACK,PSH PSH -j DROP
		iptables -A PORTSCAN -p tcp --tcp-flags ACK,URG URG -j DROP
		iptables -A PORTSCAN -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
		iptables -A PORTSCAN -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
		iptables -A PORTSCAN -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
		iptables -A PORTSCAN -p tcp --tcp-flags ALL ALL -j DROP
		iptables -A PORTSCAN -p tcp --tcp-flags ALL NONE -j DROP
		iptables -A PORTSCAN -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
		iptables -A PORTSCAN -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
		iptables -A PORTSCAN -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
		iptables -N COMMON
		iptables -A COMMON -j STATE_TRACK
		iptables -A COMMON -j PORTSCAN
		iptables -A COMMON -j PACKET
		iptables -A INPUT -j COMMON
		iptables -A OUTPUT -j COMMON
		iptables -A FORWARD -j COMMON
		iptables -A FORWARD -j PACKET
		# Ensure loopback traffic is configured
		iptables -A INPUT -i lo -j ACCEPT
		iptables -A INPUT -s 127.0.0.0/8 -j DROP
		iptables -A OUTPUT -o lo -j ACCEPT
		# Ensure outbound and established connections are configured
		iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
		iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT
		iptables -A INPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT
		iptables -A INPUT -p icmp -m state --state NEW,ESTABLISHED -j ACCEPT
		iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
		iptables -A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT
		iptables -A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT
		iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED -j ACCEPT
		iptables -A OUTPUT -j LOG --log-prefix "iptables_output "
		# Add Network Connection IP
		iptables -A INPUT -s "${FIREIP}" -d "${FIREIP}" -m state --state NEW,ESTABLISHED -j ACCEPT
		iptables -A OUTPUT -s "${FIREIP}" -d "${FIREIP}" -m state --state NEW,ESTABLISHED -j ACCEPT
		# Open inbound ssh(22) connections and linit connects to 10 every 10 seconds
		iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
		iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 10 --hitcount 10 -j DROP
		iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
		# Default deny Firewall policy
		iptables -P INPUT DROP
		iptables -P OUTPUT DROP
		iptables -P FORWARD DROP
		for port in "${TCPPORTS[@]}"
		do
			echo "Opening TCP Port $port"
			/sbin/iptables -A INPUT -p tcp -m tcp --dport "$port" -j ACCEPT
		done
		# Open UDP Ports
		for port in "${UDPPORTS[@]}"
		do
			echo "Opening UDP Port $port"
			/sbin/iptables -A INPUT -p udp -m udp --dport "$port" -j ACCEPT
		done
		# Save and Start IPTables
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			iptables-save > ${IPTBL}
			systemctl restart iptables
		elif [ "${OS}" = ubuntu ]; then
			iptables-save > ${IPTBLUB}
			sed -i '/:ufw-/d' ${IPTBLUB}
			sed -i '/-j ufw-/d' ${IPTBLUB}
			iptables-restore < ${IPTBLUB}
		fi
		# Configure IPv6 Firewall Ensure Default Deny Policy
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			cp $IPTBL $BACKUP
			mv -f $IP6TBL $IP6TBL.bak
			touch $IP6TBL
			systemctl enable ip6tables
		fi
		# Flush Iptables rules
		ip6tables -F
		# Default deny Firewall policy
		ip6tables -P INPUT DROP
		ip6tables -P OUTPUT DROP
		ip6tables -P FORWARD DROP
		ip6tables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
		# Forcing Fragments packets check
		ip6tables -A INPUT -f -j DROP
		# Dropping malformed XMAS packets
		ip6tables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
		# Drop all NULL packets
		ip6tables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
		# Limiting pings to 1 per second
		ip6tables -N PACKET
		ip6tables -A DEFAULT_RULES -p icmp -m limit --limit 3/sec --limit-burst 25 -j ACCEPT
		# Setup Connection Tracking
		ip6tables -N STATE_TRACK
		ip6tables -A STATE_TRACK -m state --state RELATED,ESTABLISHED -j ACCEPT
		ip6tables -A STATE_TRACK -m state --state INVALID -j DROP
		# Discouraging Port Scanning
		ip6tables -N PORTSCAN
		ip6tables -A PORTSCAN -p tcp --tcp-flags ACK,FIN FIN -j DROP
		ip6tables -A PORTSCAN -p tcp --tcp-flags ACK,PSH PSH -j DROP
		ip6tables -A PORTSCAN -p tcp --tcp-flags ACK,URG URG -j DROP
		ip6tables -A PORTSCAN -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
		ip6tables -A PORTSCAN -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
		ip6tables -A PORTSCAN -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
		ip6tables -A PORTSCAN -p tcp --tcp-flags ALL ALL -j DROP
		ip6tables -A PORTSCAN -p tcp --tcp-flags ALL NONE -j DROP
		ip6tables -A PORTSCAN -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
		ip6tables -A PORTSCAN -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
		ip6tables -A PORTSCAN -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
		ip6tables -N COMMON
		ip6tables -A COMMON -j STATE_TRACK
		ip6tables -A COMMON -j PORTSCAN
		ip6tables -A COMMON -j PACKET
		ip6tables -A INPUT -j COMMON
		ip6tables -A OUTPUT -j COMMON
		ip6tables -A FORWARD -j COMMON
		ip6tables -A FORWARD -j PACKET
		# Ensure loopback traffic is configured
		ip6tables -A INPUT -i lo -j ACCEPT
		ip6tables -A INPUT -s 127.0.0.0/8 -j DROP
		ip6tables -A OUTPUT -o lo -j ACCEPT
		# Ensure outbound and established connections are configured
		ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
		ip6tables -A INPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT
		ip6tables -A INPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT
		ip6tables -A INPUT -p icmp -m state --state NEW,ESTABLISHED -j ACCEPT
		ip6tables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
		ip6tables -A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT
		ip6tables -A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT
		ip6tables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED -j ACCEPT
		ip6tables -A OUTPUT -j LOG --log-prefix "iptables_output "
		for port in "${TCP6PORTS[@]}"
		do
			echo "Opening TCP Port $port"
			ip6tables -A INPUT -p tcp -m tcp --dport "$port" -j ACCEPT
		done
		# Open UDP Ports
		for port in "${UDP6PORTS[@]}"
		do
			echo "Opening UDP Port $port"
			ip6tables -A INPUT -p udp -m udp --dport "$port" -j ACCEPT

		done
			# Save and Start IPTables
		if [[ ${OS} = ubuntu ]]; then
			ip6tables-save > ${IP6TBLUB}
			sed -i '/:ufw6-/d' ${IP6TBLUB}
			sed -i '/-j ufw6-/d' ${IPTBLUB}
			ip6tables-restore < ${IP6TBLUB}
		else 
			ip6tables-save > ${IP6TBL}
			systemctl restart ip6tables
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Additional Cloud Provider Required Rules.... 

##################################################
#### 3.6a Addional Firewall Configuration AWS ####
##################################################
function iptables_aws() {
	{
		start_spinner 'Adding AWS Required Rules to IP Tables...'
		echo ""
		iptables -t nat -A PREROUTING -p tcp -d 169.254.170.2 --dport 80 -j DNAT --to-destination 127.0.0.1:51679
		iptables -t nat -A OUTPUT -d 169.254.170.2 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 51679
		iptables-save > /etc/sysconfig/iptables
		systemctl restart iptables
		stop_spinner $?
	} | tee -a $LOG
}

##################################################
#### 3.6b Addional Firewall Configuration OCI ####
##################################################
function oci_iptables() {
	{
		start_spinner 'Adding OCI Required Rules to IP Tables...'
		echo ""
		iptables -A OUTPUT -d 169.254.0.0/16 -m state --state NEW,ESTABLISHED -p tcp -m tcp -j REJECT --reject-with tcp-reset -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.0.0/16 -m state --state NEW,ESTABLISHED -p udp -m udp -j REJECT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.0.2/32 -m state --state NEW,ESTABLISHED -p tcp -m tcp --dport 80 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.0.2/32 -m state --state NEW,ESTABLISHED -p tcp -m owner --uid-owner root -m tcp --dport 3260 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.0.3/32 -m state --state NEW,ESTABLISHED -p tcp -m owner --uid-owner root -m tcp --dport 80  -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.0.4/32 -m state --state NEW,ESTABLISHED -p tcp -m tcp --dport 80  -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.2.0/24 -m state --state NEW,ESTABLISHED -p tcp -m owner --uid-owner root -m tcp --dport 3260 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.4.0/24 -m state --state NEW,ESTABLISHED -p tcp -m owner --uid-owner root -m tcp --dport 3260 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.5.0/24 -m state --state NEW,ESTABLISHED -p tcp -m owner --uid-owner root -m tcp --dport 3260 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.169.254/32 -m state --state NEW,ESTABLISHED -p tcp -m tcp --dport 53 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE" 
		iptables -A OUTPUT -d 169.254.169.254/32 -m state --state NEW,ESTABLISHED -p udp -m udp --dport 53 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.169.254/32 -m state --state NEW,ESTABLISHED -p udp -m udp --dport 67 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.169.254/32 -m state --state NEW,ESTABLISHED -p udp -m udp --dport 69 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.169.254/32 -m state --state NEW,ESTABLISHED -p udp -m udp --dport 80 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		iptables -A OUTPUT -d 169.254.169.254/32 -m state --state NEW,ESTABLISHED -p udp -m udp --dport 123 -j ACCEPT -m comment --comment "OCI Required - DO NOT REMOVE"
		# Save and Start IPTables
		if [ "${OS}" = ubuntu ]; then
			iptables-save > ${IPTBLUB}
			sed -i '/:ufw-/d' ${IPTBLUB}
			sed -i '/-j ufw-/d' ${IPTBLUB}
			iptables-restore < ${IPTBLUB}
		else
			iptables-save > ${IPTBL}
			systemctl restart iptables
		fi
		stop_spinner $?
		} | tee -a $LOG
}

Section 4.1 Configure System Accounting

#########################################
#### 4.1 Configure System Accounting ####
#########################################
function auditd_accounting() {
	{
		start_spinner 'Configuring Auditd Service...'
		echo ""
		#### 4.1.1.1 Ensure audit log storage size is configured ####
		#### !!! Our current default configuration is 8MB !!! ####
		#### 4.1.1.2 Ensure system is disabled when audit logs are full ####
		if [ "${OS}" = ubuntu ]; then
			debconf-set-selections <<< ""postfix postfix/mailname string "${HOSTNAME}"""
			debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Local Only'"
			DEBIAN_FRONTEND=noninteractive ${PAKMGR} install auditd --assume-yes
		else
			${PAKMGR} install audit
		fi
		xargs -n 1 cp -v /etc/audit/auditd.conf <<< ""${BACKUP} /etc/audit/auditd.conf.bak""
		### 4.1.1.3 Ensure audit logs are not automaticlly deleted ###
		sed -i 's/^space_left_action.*$/space_left_action = email/' /etc/audit/auditd.conf
		sed -i 's/^action_mail_acct.*$/action_mail_acct = root/' /etc/audit/auditd.conf
		sed -i 's/^admin_space_left_action.*$/admin_space_left_action = halt/' /etc/audit/auditd.conf
		# shellcheck disable=SC2086
		sed -i ""s/max_log_file_action = ROTATE/max_log_file_action = \"${MAXLOGS}\"/g"" /etc/audit/auditd.conf
		### 4.1.2 Ensure auditd service is enabled ####
		service auditd reload
		if ! systemctl is-enabled auditd; then 
			systemctl enable --now auditd
		fi
		### 4.1.3 Ensure auditing for processes that start prior to auditd is enabled"
		xargs -n 1 cp -v /etc/default/grub <<< ""${BACKUP} /etc/default/grub.bak""
		if ! grep "audit=1" /etc/default/grub; then 
			sed -i '/^GRUB_CMDLINE_LINUX=/ s/\(\"[^\"]*\)$/ audit=1 &/' /etc/default/grub
		fi
		if [ "${OS}" = ubuntu ]; then
			grub-mkconfig -o ${BACKUP}/grub.cfg
		else
			grub2-mkconfig -o ${BACKUP}/grub.cfg
		fi
		if [[ ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			cp ${BACKUP}/grub.cfg ${GRUBCFGRH}
			cp ${BACKUP}/grub.cfg ${GRUBCFG} 
		elif [ "${OS}" = ubuntu ]; then
			cp ${BACKUP}/grub.cfg ${GRUBCFGUB}
		elif [ "${OS}" = centos ]; then
			cp ${BACKUP}/grub.cfg ${GRUBCFGCE}
			cp ${BACKUP}/grub.cfg ${GRUBCFG} 
		fi
		if ! dmesg | grep '[NX|DX]*Execute Disable'; then
			echo 0 > /proc/sys/kernel/exec-shield
		fi
		### 4.1.4 Ensure events that modify date and time information are collected ###
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			sed -i 's/RefuseManualStop=yes/RefuseManualStop=no/g' /lib/systemd/system/auditd.service
			systemctl daemon-reload
		fi
		xargs -n 1 cp -v /etc/audit/rules.d/audit.rules <<< ""${BACKUP} /etc/audit/rules.d/audit.rules.bak""
		sed -i 's/RefuseManualStop=yes/RefuseManualStop=no/g' /lib/systemd/system/auditd.service
		systemctl daemon-reload
		{
			echo '##################################################################################################'
			echo '####                Audit Rules File edited to match CIS level 1 requirements                 ####'
			echo '####        for questions or changes please contact Phil Connor contact@mylinux.work          ####'
			echo '##################################################################################################'
			echo ''
			echo '#### First rule - delete all rules ####'
			echo '-D'
			echo ''
			echo '#### 4.1.4 Ensure events that modify date and time information are collected ####'
			echo '-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change'
			echo '-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change'
			echo '-a always,exit -F arch=b64 -S clock_settime -k time-change'
			echo '-a always,exit -F arch=b32 -S clock_settime -k time-change'
			echo '-w /etc/localtime -p wa -k time-change'
			echo ''
			echo '#### 4.1.5 Ensure events that modify user/group information are collected ####'
			echo '-w /etc/group -p wa -k identity'
			echo '-w /etc/passwd -p wa -k identity'
			echo '-w /etc/gshadow -p wa -k identity'
			echo '-w /etc/shadow -p wa -k identity'
			echo '-w /etc/security/opasswd -p wa -k identity'
			echo ''
			echo '#### 4.1.6 Ensure events that modify the system'\''s network environment are collected ####'
			echo '-a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale'
			echo '-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale'
			echo '-w /etc/issue -p wa -k system-locale'
			echo '-w /etc/issue.net -p wa -k system-locale'
			echo '-w /etc/hosts -p wa -k system-locale'
			echo '-w /etc/network -p wa -k system-locale'
			echo '-w /etc/networks -p wa -k system-locale'
			echo ''
			echo '#### 4.1.7 Ensure events that modify the system'\''s Mandatory Access Controls (MAC'\''s) are collected ####'
			echo '-w /etc/selinux/ -p wa -k MAC-policy'
			echo '-w /etc/apparmor/ -p wa -k MAC-policy'
			echo '-w /etc/apparmor.d/ -p wa -k MAC-policy'
			echo ''
			echo '#### 4.1.8 Ensure login and logout events are collected ####'
			echo '-w /var/log/faillog -p wa -k logins'
			echo '-w /var/log/lastlog -p wa -k logins'
			echo '-w /var/log/tallylog -p wa -k logins'
			echo ''
			echo '#### 4.1.9 Ensure session initiation information is collected ###'
			echo '-w /var/run/utmp -p wa -k session'
			echo '-w /var/run/wtmp -p wa -k session'
			echo '-w /var/run/btmp -p wa -k session'
			echo ''
			echo '#### 4.1.10 Ensure discretionary access control permission modification events are collected ####'
			echo '-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod'
			echo '-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod'
			echo '-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod'
			echo '-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod'
			echo '-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod'
			echo '-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod'
			echo ''
			echo '#### 4.1.11 Ensure unsuccessful unauthorized file access attempts are collected ####'
			echo '-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access'
			echo '-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access'
			echo '-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access'
			echo '-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access'
			echo ''
			echo '#### 4.1.12 Ensure use of privileged commands is collected ####'
			echo "$RULES"
			echo ''
			echo '#### 4.1.13 Ensure successful file system mounts are collected ####'
			echo '-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts'
			echo '-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts'
			echo ''
			echo '#### 4.1.14 Ensure file deletion events by users are collected ####'
			echo '-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete'
			echo '-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete'
			echo ''
			echo '#### 4.1.15 Ensure changes to system administration scope (sudoers) is collected ####'
			echo '-w /etc/sudoers -p wa -k scope'
			echo '-w /etc/sudoers.d -p wa -k scope'
			echo ''
			echo '#### 4.1.16 Ensure system administrator actions (sudolog) are collected ####'
			echo '-w /var/log/sudo.log -p wa -k actions'
			echo ''
			echo '#### 4.1.17 Ensure kernel module loading and unloading is collected ####'
			echo '-w /sbin/insmod -p x -k modules'
			echo '-w /sbin/rmmod -p x -k modules'
			echo '-w /sbin/modprobe -p x -k modules'
			echo '-a always,exit -F arch=b64 -S init_module -S delete_module -k modules'
			echo ''
			echo '#### 4.1.18 Ensure the audit configuration is immutable ####'
			echo '-e 2'
		} > /etc/audit/rules.d/audit.rules
		service auditd restart 
		stop_spinner $?
	} | tee -a $LOG
}

Section 4.2.1 Configure Rsyslog

#################################
#### 4.2.1 Configure rsyslog ####
#################################
function rsyslog_service() {
	{
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			if [ "${OSVER}" = 7 ]; then
				os7_rsyslog	
			elif [[ ${OSVER} = 8 || ${OSVER} = 9 ]]; then 
				os8_rsyslog
			fi
		elif [ "${OS}" = ubuntu ]; then
				ub_rsyslog
			
		fi
	}
}

function os7_rsyslog() {
	{
		start_spinner 'Configuring Rsyslog Service...'
		echo ""
		### 4.2.1.1 Ensure rsyslog Service is enabled ###
		systemctl enable --now rsyslog
		### 4.2.1.2 Ensure logging is configured ###
		xargs -n 1 cp -v /etc/rsyslog.conf <<< ""${BACKUP} /etc/rsyslog.conf.bak""
		cat > /etc/rsyslog.conf << 'EOF'   
		##################################################################################################
		####     Hardened Rsyslog Configuration File edited to match CIS level 1 requirements         ####
		####      for questions or changles please contact Phil Connor contact@mylinux.work           ####
		##################################################################################################

		#################
		#### MODULES ####
		#################

		# The imjournal module bellow is now used as a message source instead of imuxsock.
		$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
		$ModLoad imjournal # provides access to the systemd journal
		#$ModLoad imklog # reads kernel messages (the same are read from journald)
		#$ModLoad immark  # provides --MARK-- message capability

		# Provides UDP syslog reception
		#$ModLoad imudp
		#$UDPServerRun 514

		# Provides TCP syslog reception
		#$ModLoad imtcp
		#$InputTCPServerRun 514

		# Enable non-kernel facility klog messages
		# $KLogPermitNonKernelFacility on

		###########################
		#### GLOBAL DIRECTIVES ####
		###########################

		# Reset UMASK
		$umask 0000

		# Set file creation pewrmissions
		$FileCreateMode 0640

		# Set previously cleared UMASK
		$umask 0177

		# Where to place auxiliary files
		$WorkDirectory /var/lib/rsyslog

		# Use default timestamp format
		$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

		# File syncing capability is disabled by default. This feature is usually not required,
		# not useful and an extreme performance hit
		#$ActionFileEnableSync on

		# Include all config files in /etc/rsyslog.d/
		$IncludeConfig /etc/rsyslog.d/*.conf

		# Turn off message reception via local log socket;
		# local messages are retrieved through imjournal now.
		$OmitLocalLogging on

		# File to store the position in the journal
		$IMJournalStateFile imjournal.state

		###############
		#### RULES ####
		###############

		#  ### Log Anything of Level WARN or Higher. ###
		*.warn;mail.none;news.none;authpriv.none;cron.none       /var/log/messages

		# ### Secure Logging Anything of Level WARN or Higher ###
		authpriv.*                                               /var/log/secure

		# ### All Mail Logs ###
		mail.*                                                  -/var/log/mail

		# ### Cron Log ###
		cron.*                                                   /var/log/cron

		# ### Everybody Gets Emergency Messages ###
		*.emerg                                                   :omusrmsg:*
		*.=warning;*.=err                                        -/var/log/warn
		*.crit                                                    /var/log/warn

		# ### News Error Logs ###
		news.crit                                                -/var/log/news/news.crit
		news.err                                                 -/var/log/news/news.err
		news.notice                                              -/var/log/news/news.notice

		# ### Local and Boot Messages ###
		local0,local1.*                                          -/var/log/localmessages
		local2,local3.*                                          -/var/log/localmessages
		local4,local5.*                                          -/var/log/localmessages
		local6.*                                                 -/var/log/localmessages
		local7.*                                                  /var/log/boot.log

		###############################
		#### Begin Forwarding Rule ####
		###############################

		# ### The Remote SysLog Server host is: name/ip:port, e.g. 192.168.0.1:514, port optional ###
		#*.* @@syslog
EOF
		echo "
		*.* @@${SYSLOG}

		####################################
		#### End of the Forwarding Rule ####
		####################################
			" >>  /etc/rsyslog.conf
		sed -i 's/^[\t]*//' /etc/rsyslog.conf
		touch /var/log/warn /var/log/news.crit /var/log/news.err /var/log/news.notice /var/log/localmessages
		chmod og-rwx /var/log/warn /var/log/news.crit /var/log/news.err /var/log/news.notice /var/log/localmessages
		chown root:root /var/log/warn /var/log/news.crit /var/log/news.err /var/log/news.notice /var/log/localmessages
		sed -i 's/*.* @@/#*.* @@/g' /etc/rsyslog.conf
		pkill -hup rsyslog
		stop_spinner $?
	}
}

function os8_rsyslog() {
	{
		start_spinner 'Configuring Rsyslog Service...'
		echo ""
		### 4.2.1.1 Ensure rsyslog Service is enabled ###
		systemctl enable rsyslog
		### 4.2.1.2 Ensure logging is configured ###
		xargs -n 1 cp -v /etc/rsyslog.conf <<< ""${BACKUP} /etc/rsyslog.conf.bak""
		cat > /etc/rsyslog.conf << 'EOF'
		##################################################################################################
		####     Hardened Rsyslog Configuration File edited to match CIS level 1 requirements         ####
		#### for questions or changles please contact Phil Connor contact@mylinux.work ####
		##################################################################################################

		#################
		#### MODULES ####
		#################

		module(load="imuxsock"       	# provides support for local system logging (e.g. via logger command)
		SysSock.Use="off")            	# Turn off message reception via local log socket;
										# local messages are retrieved through imjournal now.
		module(load="imjournal"      	# provides access to the systemd journal
		StateFile="imjournal.state") 	# File to store the position in the journal
		#module(load="imklog")       	# reads kernel messages (the same are read from journald)
		#module(load"immark")        	# provides --MARK-- message capability

		# Provides Rsyslog Forwarding
		module(load="omfwd")

		# Provides UDP syslog reception
		# for parameters see http://www.rsyslog.com/doc/imudp.html
		#module(load="imudp") # needs to be done just once
		#input(type="imudp" port="514")

		# Provides TCP syslog reception
		# for parameters see http://www.rsyslog.com/doc/imtcp.html
		#module(load="imtcp") # needs to be done just once
		#input(type="imtcp" port="514")

		###########################
		#### GLOBAL DIRECTIVES ####
		###########################

		# Reset UMASK
		$umask 0000

		# Set file creation pewrmissions
		$FileCreateMode 0640

		# Set previously cleared UMASK
		$umask 0177

		# Where to place auxiliary files
		global(workDirectory="/var/lib/rsyslog")

		# Use default timestamp format
		module(load="builtin:omfile" Template="RSYSLOG_TraditionalFileFormat")

		# Include all config files in /etc/rsyslog.d/
		include(file="/etc/rsyslog.d/*.conf" mode="optional")

		###############
		#### RULES ####
		###############

		#  ### Log Anything of Level WARN or Higher. ###
		*.warn;mail.none;news.none;authpriv.none;cron.none       /var/log/messages

		# ### Secure Logging Anything of Level WARN or Higher ###
		authpriv.*                                               /var/log/secure

		# ### All Mail Logs ###
		mail.*                                                  -/var/log/mail

		# ### Cron Log ###
		cron.*                                                   /var/log/cron

		# ### Everybody Gets Emergency Messages ###
		*.emerg                                                   :omusrmsg:*
		*.=warning;*.=err                                        -/var/log/warn
		*.crit                                                    /var/log/warn

		# ### News Error Logs ###
		news.crit                                                -/var/log/news/news.crit
		news.err                                                 -/var/log/news/news.err
		news.notice                                              -/var/log/news/news.notice

		# ### Local and Boot Messages ###
		local0,local1.*                                          -/var/log/localmessages
		local2,local3.*                                          -/var/log/localmessages
		local4,local5.*                                          -/var/log/localmessages
		local6.*                                                 -/var/log/localmessages
		local7.*                                                  /var/log/boot.log


		###############################
		#### Begin Forwarding Rule ####
		###############################

		#action(type="omfwd"
		# An on-disk queue is created for this action. If the remote host is
		# down, messages are spooled to disk and sent when it is up again.
		#queue.filename="fwdRule1"       # unique name prefix for spool files
		#queue.maxdiskspace="1g"         # 1gb space limit (use as much as possible)
		#queue.saveonshutdown="on"       # save messages to disk on shutdown
		#queue.type="LinkedList"         # run asynchronously
		#action.resumeRetryCount="-1"    # infinite retries if host is down
		# Remote Logging (we use TCP for reliable delivery)
		# remote_host is: name/ip, e.g. 192.168.0.1, port optional e.g. 10514
		# Target="remote_host" Port="XXX" Protocol="tcp")

EOF
		echo "
		Target=\"${SYSLOG}" Port="514" Protocol="tcp\"

		####################################
		#### End of the Forwarding Rule ####
		####################################
			" >> /etc/rsyslog.conf
		sed -i 's/^[\t]*//' /etc/rsyslog.conf
		touch /var/log/warn /var/log/news.crit /var/log/news.err /var/log/news.notice /var/log/localmessages
		chmod og-rwx /var/log/warn /var/log/news.crit /var/log/news.err /var/log/news.notice /var/log/localmessages
		chown root:root /var/log/warn /var/log/news.crit /var/log/news.err /var/log/news.notice /var/log/localmessages
		sed -i 's/Target="" Port="514" Protocol="tcp"/#Target="" Port="514" Protocol="tcp"/g' /etc/rsyslog.conf
		pkill -hup rsyslog
		stop_spinner $?
	}
}

function ub_rsyslog() {
	{
		start_spinner 'Configuring Rsyslog Service...'
		echo ""
		service rsyslog stop
		mknod -m 640 /dev/xconsole c 1 3
		chown syslog:adm /dev/xconsole
		### 4.2.1.1 Ensure rsyslog Service is enabled ###
		systemctl enable rsyslog
		### 4.2.1.2 Ensure logging is configured ###
		xargs -n 1 cp -v /etc/rsyslog.conf <<< ""${BACKUP} /etc/rsyslog.conf.bak""
		no_show << "EOF" >  /etc/rsyslog.conf
		##################################################################################################
		####     Hardened Rsyslog Configuration File edited to match CIS level 1 requirements         ####
		####       for questions or changles please contact Phil Connor contact@mylinux.work          ####
		##################################################################################################

		#################
		#### MODULES ####
		#################

		module(load="imuxsock") # provides support for local system logging
		#module(load="immark")  # provides --MARK-- message capability

		# provides UDP syslog reception
		#module(load="imudp")
		#input(type="imudp" port="514")

		# provides TCP syslog reception
		#module(load="imtcp")
		#input(type="imtcp" port="514")

		# provides kernel logging support and enable non-kernel klog messages
		module(load="imklog" permitnonkernelfacility="on")

		###########################
		#### GLOBAL DIRECTIVES ####
		###########################

		# Use default timestamp format
		$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

		# Use traditional timestamp format.
		# To enable high precision timestamps, comment out the following line.
		$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

		# Filter duplicated messages
		$RepeatedMsgReduction on

		# Reset UMASK
		$Umask 0000

		# Set the default permissions for all log files.
		$FileOwner syslog
		$FileGroup adm
		$FileCreateMode 0640
		$DirCreateMode 0755
		$Umask 0177
		$PrivDropToUser syslog
		$PrivDropToGroup syslog

		# Where to place spool and state files
		$WorkDirectory /var/spool/rsyslog

		# Include all config files in /etc/rsyslog.d/
		$IncludeConfig /etc/rsyslog.d/*.conf

		###############################
		#### Begin Forwarding Rule ####
		###############################
		$PreserveFQDN on
		$ActionQueueFileName queue
		$ActionQueueMaxDiskSpace 1g
		$ActionQueueSaveOnShutdown on
		$ActionQueueType LinkedList
		$ActionResumeRetryCount -1
		# ### The Remote SysLog Server host is: name/ip:port, e.g. 192.168.0.1:514, port optional ###
		#*.* @@syslog

	EOF
		echo "
		*.* @@${SYSLOG}:514

		####################################
		#### End of the Forwarding Rule ####
		####################################
			" >> /etc/rsyslog.conf
		sed -i 's/^[\t]*//' /etc/rsyslog.conf
		xargs -n 1 cp -v /etc/rsyslog.d/50-default.conf <<< ""${BACKUP} /etc/rsyslog.d/50-default.conf.bak""
		no_show << "EOF" > /etc/rsyslog.d/50-default.conf
		##################################################################################################
		####     Hardened Rsyslog Configuration File edited to match CIS level 1 requirements         ####
		####      for questions or changles please contact Phil Connor contact@mylinux.work           ####
		##################################################################################################


		###############
		#### RULES ####
		###############

		#  Default rules for rsyslog.
		#
		#                       For more information see rsyslog.conf(5) and /etc/rsyslog.conf

		#
		# First some standard log files.  Log by facility.
		#
		auth,authpriv.*                 /var/log/auth.log
		*.*;auth,authpriv.none          -/var/log/syslog
		#cron.*                         /var/log/cron.log
		#daemon.*                       -/var/log/daemon.log
		kern.*                          -/var/log/kern.log
		#lpr.*                          -/var/log/lpr.log
		mail.*                          -/var/log/mail.log
		#user.*                         -/var/log/user.log

		#
		# Logging for the mail system.  Split it up so that
		# it is easy to write scripts to parse these files.
		#
		#mail.info                      -/var/log/mail.info
		#mail.warn                      -/var/log/mail.warn
		mail.err                        /var/log/mail.err

		#
		# Logging for INN news system.
		#
		news.crit                       /var/log/news/news.crit
		news.err                        /var/log/news/news.err
		news.notice                     -/var/log/news/news.notice

		#
		# Some "catch-all" log files.
		#
		#*.=debug;\
		#       auth,authpriv.none;\
		#       news.none;mail.none     -/var/log/debug
		#*.=info;*.=notice;*.=warn;\
		#       auth,authpriv.none;\
		#       cron,daemon.none;\
		#       mail,news.none          -/var/log/messages

		#
		# Emergencies are sent to everybody logged in.
		#
		*.emerg                                :omusrmsg:*

		#
		# I like to have messages displayed on the console, but only on a virtual
		# console I usually leave idle.
		#
		#daemon,mail.*;\
		#       news.=crit;news.=err;news.=notice;\
		#       *.=debug;*.=info;\
		#       *.=notice;*.=warn       /dev/tty8

		# The named pipe /dev/xconsole is for the `xconsole' utility.  To use it,
		# you must invoke `xconsole' with the `-file' option:
		#
		#    $ xconsole -file /dev/xconsole [...]
		#
		# NOTE: adjust the list below, or you'll go crazy if you have a reasonably
		#      busy site..
		#
		daemon.*;mail.*;\
				news.err;\
				*.=debug;*.=info;\
				*.=notice;*.=warn       |/dev/xconsole                                                        
EOF
		touch /var/log/warn /var/log/news.crit /var/log/news.err /var/log/news.notice /var/log/localmessages
		chmod og-rwx /var/log/warn /var/log/news.crit /var/log/news.err /var/log/news.notice /var/log/localmessages
		chown root:root /var/log/warn /var/log/news.crit /var/log/news.err /var/log/news.notice /var/log/localmessages
		sed -i 's/*.* @@[[:blank:]]*:514/#*.* @@/g' /etc/rsyslog.conf
		systemctl start rsyslog
		pkill -hup rsyslog
		stop_spinner $?
	} | tee -a $LOG
}

Section 4.2.1.2 Ensure Journald Service is enabled

####################################################
#### 4.2.1.2 Ensure Journald Service is enabled ####
####################################################
function journald_config() {
	{
		start_spinner 'Configuring Journald Log Retension...'
		echo ""
		### 4.2.2.1 Ensure journald is configured to send logs to rsyslog ###
		sed -i 's/#ForwardToSyslog=yes/ForwardToSyslog=yes/g' /etc/systemd/journald.conf
		### 4.2.2.2 Ensure journald is configured to compress large log files ###
		sed -i 's/#Compress=yes/Compress=yes/g' /etc/systemd/journald.conf
		### 4.2.2.3 Ensure journald is configured to write logfiles to persistent disk ###
		sed -i 's/#Storage=auto/Storage=persistent/g' /etc/systemd/journald.conf
		stop_spinner $?
	} | tee -a $LOG
}

Section 4.2.2 Ensure Journald is Configured

##################################
#### 4.2.2 Configure journald ####
##################################
function logfile_permissions() {
	{
		start_spinner 'Configuring Permissions on all Logfiles...'
		echo ""
		### 4.2.4 Ensure permissions on all logfiles are configured ###
		find /var/log -type f -exec chmod g-wx,o-rwx {} +
		### 4.3 Ensure logrotate is configured ###
		cp /etc/logrotate.conf $BACKUP
		sed -i 's/    create 0664 root utmp/    create 0640 root utmp/g'  /etc/logrotate.conf
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle ]]; then 
			if [ "${OSVER}" = 8 ]; then
				sed -i 's/    create 0664 root utmp/    create 0640 root utmp/g'  /etc/logrotate.d/btmp
				sed -i 's/    create 0664 root utmp/    create 0640 root utmp/g'  /etc/logrotate.d/wtmp
			fi
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Section 5.1.1 Ensure Cron Daemon is Enabled

#############################################
#### 5.1.1 Ensure cron daemon is enabled ####
#############################################
function crond_enabled() {
	{
		start_spinner 'Configuring Permissions on Cron Daemon...'
		echo ""
		### 5.1.1.1 Ensure cron daemon is enabled ###
		if [ "${OS}" = ubuntu ]; then
			if ! systemctl is-enabled cron; then
				systemctl enable cron
			fi
		else
			if ! systemctl is-enabled crond; then 
				systemctl enable crond
			fi
		fi
		### Ensure permissions on /etc/crontab are configured ###
		chown root.root /etc/crontab
		chmod og-rwx /etc/crontab
		### 5.1.3 Ensure permissions on /etc/cron.hourly are configured ###
		chown root.root /etc/cron.hourly
		chmod og-rwx /etc/cron.hourly
		### 5.1.4 Ensure permissions on /etc/cron.daily are configured ###
		chown root.root /etc/cron.daily
		chmod og-rwx /etc/cron.daily
		### 5.1.5 Ensure permissions on /etc/cron.weekly are configured ###
		chown root.root /etc/cron.weekly
		chmod og-rwx /etc/cron.weekly
		### 5.1.6 Ensure permissions on ?etc/cron.monthly are configured ###
		chown root.root /etc/cron.monthly
		chmod og-rwx /etc/cron.monthly
		### 5.1.7 Ensure permissions on /etc/cron.d are configured ###
		chown root.root /etc/cron.d
		chmod og-rwx /etc/cron.d
		### 5.1.8 Ensure at/cron is restricted to authorized users ###
		stat /etc/cron.deny
		if [ $? != 1 ]; then
			rm -rf /etc/cron.deny
		fi
		stat /etc/at.deny
		if [ $? != 1 ]; then
			rm -rf /etc/at.deny
		fi
		if ! stat /etc/cron.allow; then
			touch /etc/cron.allow
			chown root.root /etc/cron.allow
			chmod og-rwx /etc/cron.allow
		fi
		if ! stat /etc/at.allow; then
			touch /etc/at.allow
			chown root.root /etc/at.allow
			chmod og-rwx /etc/cron.allow
		fi
		stop_spinner $?
	} | tee -a $LOG
}

Section 5.2 Ensure SSH Server is Configured

######################################
#### 5.2 SSH Server Configuration ####
######################################
function config_sshd() {
	{
		start_spinner 'Configuring SSh Server...'
		echo ""
		### 5.2.1 Ensure permissions on /etc/ssh/sshd_config are configured ###
		xargs -n 1 cp -v ${SSHD_FILE} <<< ""${BACKUP} ${SSHD_FILE}.bak""
		chown root.root ${SSHD_FILE}
		chmod og-rwx ${SSHD_FILE}
		### 5.2.2. Ensure SSH Protocol is set to 2 ###
		if ! grep -qi "Protocol 2" ${SSHD_FILE}; then
			echo 'Protocol 2' >> ${SSHD_FILE}
		else
			sed -i 's/#Protocol 2/Protocol 2/g' ${SSHD_FILE}
		fi
		### 5.2.3 Ensure SSH LogLevel is set to info ###
		if ! grep -qi "LogLevel INFO" ${SSHD_FILE}; then
			echo "LogLevel INFO" ${SSHD_FILE}
		else
			sed -i 's/#LogLevel INFO/LogLevel INFO/g' ${SSHD_FILE}
		fi	
		### 5.2.4 Ensure SSH X11 forwarding is disabled ###
		if ! grep -qi "X11Forwarding yes" ${SSHD_FILE}; then
			echo "X11Forwarding no" ${SSHD_FILE}
		else
			sed -i 's/X11Forwarding yes/X11Forwarding no/g' ${SSHD_FILE}
		fi
		### 5.2.5 Ensure SSH MaxAuthTries is set to 4 or less ###
		if ! grep -qi "MaxAuthTries 6" ${SSHD_FILE}; then
			echo "MaxAuthTries 4" >> ${SSHD_FILE}
		else
			sed -i 's/#MaxAuthTries 6/MaxAuthTries 4/g' ${SSHD_FILE}
		fi
		### 5.2.6 Ensure SSH IgnoreRhosts is enabled ###
		if ! grep -qi "IgnoreRhosts yes" ${SSHD_FILE}; then
			echo "IgnoreRhosts yes" >> ${SSHD_FILE}
		else
			sed -i 's/#IgnoreRhosts yes/IgnoreRhosts yes/g' ${SSHD_FILE}
		fi
		### 5.2.7 Ensure SSH HostbasedAuthentication is disabled ###
		if ! grep -qi "HostbasedAuthentication no" ${SSHD_FILE}; then
			echo "HostbasedAuthentication no" >> ${SSHD_FILE}
		else
			sed -i 's/#HostbasedAuthentication no/HostbasedAuthentication no/g' ${SSHD_FILE}
		fi
		### 5.2.8 Ensure SSH root login is disabled ###
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle ]]; then
			if ! grep -qi "#PermitRootLogin" ${SSHD_FILE}; then
				sed -i 's/PermitRootLogin yes/PermitRootLogin no/g' ${SSHD_FILE}
			else
				sed -i 's/#PermitRootLogin yes/PermitRootLogin no/g' ${SSHD_FILE}
			fi
		elif [ "${OS}" = ubuntu ]; then
			if ! grep -qi "prohibit-password" ${SSHD_FILE}; then
				sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin no/g' ${SSHD_FILE}
			fi
		fi
		### Ensure SSH PermitEmptyPasswords is disabled ###
		sed -i 's/#PermitEmptyPasswords no/PermitEmptyPasswords no/g' ${SSHD_FILE}
		### 5.2.10 Ensure SSH PermitUserEnvironment is disables ###
		if ! grep -qi "#PermitUserEnvironment" ${SSHD_FILE}; then
			echo "PermitUserEnvironment no" >> ${SSHD_FILE}
		else
			sed -i 's/#PermitUserEnvironment no/PermitUserEnvironment no/g' ${SSHD_FILE}
		fi
		### 5.2.11 Ensure ony approved MAC algorithms are used ###
			if ! grep -qi "MACs" ${SSHD_FILE}; then
			echo "MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256" >> ${SSHD_FILE}
		else
			sed -i 's/MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com/MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256/g' ${SSHD_FILE}
		fi
		if ! grep -qi "#ClientAliveInterval" ${SSHD_FILE}; then
			echo "ClientAliveInterval 300" >> ${SSHD_FILE}
		else
			sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 300/g' ${SSHD_FILE}
		fi
		if ! grep -qi "#ClientAliveCountMax" ${SSHD_FILE}; then
			echo "ClientAliveCountMax ${MAXCOUNT}" >> ${SSHD_FILE}
		else
			sed -i "s/#ClientAliveCountMax 3/ClientAliveCountMax \"${MAXCOUNT}\"/g" ${SSHD_FILE}
		fi
		### 5.2.13 Ensure SSH LoginGraceTime is set to one minute or less ###
		if ! grep -qi "LoginGraceTime 120" ${SSHD_FILE}; then
			sed -i 's/#LoginGraceTime 2m/LoginGraceTime 60/g' ${SSHD_FILE}
		else
			sed -i 's/LoginGraceTime 120/LoginGraceTime 60/g' ${SSHD_FILE}
		fi
		### 5.2.14 Ensure SSH access is limited ###
		echo 'AllowUsers *@*' >> ${SSHD_FILE}
		### 5.2.15 Ensure SSH warning banner is configured ###
		if ! grep -qi "#Banner none" ${SSHD_FILE}; then
			sed -i 's/#Banner \/etc\/issue.net/Banner \/etc\/issue.net/g' ${SSHD_FILE}
		else
			sed -i 's/#Banner none/Banner \/etc\/issue.net/g' ${SSHD_FILE}
		fi
		### 5.2.16 Ensure only strong Key Exchange algorithms are used ###
		if ! grep -qi "kexalgorithms" ${SSHD_FILE}; then
			echo "KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256" >> ${SSHD_FILE}
		fi
		### 5.2.21 Ensure SSH MaxStartups is configured ###
		if ! grep -qi "maxstartups" ${SSHD_FILE}; then
			echo "MaxStartups 10:30:60" >> ${SSHD_FILE}
		else 
			sed -i 's/#MaxStartups 10:30:100/MaxStartups 10:30:60/g' ${SSHD_FILE}
		fi
		### Configuring additional SSH settings ###
		if ! grep -qi "#MaxSessions" ${SSHD_FILE}; then
			echo "MaxSessions 2" >> ${SSHD_FILE}
		else
			sed -i 's/#MaxSessions 10/MaxSessions 2/g' ${SSHD_FILE}
		fi
		if ! grep -qi "#AllowAgentForwarding" ${SSHD_FILE}; then
			echo "AllowAgentForwarding no" >> ${SSHD_FILE}
		else
			sed -i 's/#AllowAgentForwarding yes/AllowAgentForwarding no/g' ${SSHD_FILE}
		fi
		if ! grep -qi "#AllowTcpForwarding" ${SSHD_FILE}; then
			echo "AllowTcpForwarding no" >> ${SSHD_FILE}
		else
			sed -i 's/#AllowTcpForwarding yes/AllowTcpForwarding no/g' ${SSHD_FILE}
		fi
		sed -i 's/#PrintMotd yes/PrintMotd no/g' ${SSHD_FILE}
		if ! grep -qi "PrintLastLog" ${SSHD_FILE}; then
			echo "PrintLastLog no" >> ${SSHD_FILE}
		else
			sed -i 's/#PrintLastLog yes/PrintLastLog no/g' ${SSHD_FILE}
		fi
		if ! grep -qi "TCPKeepAlive" ${SSHD_FILE}; then
			sed -i 's/TCPKeepAlive yes/TCPKeepAlive no/g' ${SSHD_FILE}
		else
			sed -i 's/#TCPKeepAlive yes/TCPKeepAlive no/g' ${SSHD_FILE}
		fi
		if ! grep -qi "Compression" ${SSHD_FILE}; then 
			echo "Compression no" >> ${SSHD_FILE}
		else
			sed -i 's/#Compression delayed/Compression no/g' ${SSHD_FILE}
		fi
		if ! grep -qi "UseDNS" ${SSHD_FILE}; then
			echo "UseDNS no" >> ${SSHD_FILE}
		else
			sed -i 's/#UseDNS yes/UseDNS no/g' ${SSHD_FILE}
			sed -i 's/#UseDNS no/UseDNS no/g' ${SSHD_FILE}
		fi
		if ! grep -qi "#PasswordAuthentication" ${SSHD_FILE}; then
			sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' ${SSHD_FILE}
		else
			sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' ${SSHD_FILE}
		fi
		echo 'Ciphers aes128-ctr,aes192-ctr,aes256-ctr' >> ${SSHD_FILE}
		systemctl restart sshd
		stop_spinner $?
		} | tee -a $LOG
}

Section 5.3 Configure PAM

###########################
#### 5.3 Configure PAM ####
###########################
function config_pam() {
	{
		start_spinner 'Configuring PAM Server...'
		echo ""
		### 5.3.1 Ensure password creation requirements are configured ###
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle ]]; then
			xargs -n 1 cp -v /etc/security/pwquality.conf <<< ""${BACKUP} /etc/security/pwquality.conf.bak""
			sed -i 's/minlen = 8/minlen = 14/g' /etc/security/pwquality.conf
			### 5.3.2 Ensure lockout for failed password attempts is configured ###
			xargs -n 1 cp -v /etc/pam.d/password-auth <<< ""${BACKUP} /etc/pam.d/password-auth.bak""
			no_show << EOF > /etc/pam.d/password-auth
			########################################################################################
			#### This password-auth file edited to match CIS level 1 requirements for questions ####
			####    or changes please contact Phil Connor contact@mylinux.work   #### 
			####             Please don't edit it unless you know what your doing               ####
			########################################################################################
			#%PAM-1.0
			# User changes will be destroyed the next time authconfig is run.
			auth        required      pam_env.so
			auth        required      pam_faildelay.so delay=2000000
			auth        required      pam_faillock.so preauth audit silent deny=5 unlock_time=900
			auth   [success=1 default=bad] pam_unix.so
			auth        sufficient    pam_fprintd.so
			auth        sufficient    pam_unix.so nullok try_first_pass
			auth      [default=die]   pam_faillock.so authfail audit deny=5 unlock_time=900
			auth        sufficient    pam_faillock.so authsucc audit deny=5 unlock_time=900
			auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
			auth        required      pam_deny.so

			account     required      pam_unix.so
			account     sufficient    pam_localuser.so
			account     sufficient    pam_succeed_if.so uid < 1000 quiet
			account     required      pam_permit.so
			account     required      pam_faillock.so

			password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= enforce_for_root
			password    required      pam_pwhistory.so remember=5 use_authlok
			password    sufficient    pam_unix.so remember=5 sha512 shadow try_first_pass use_authtok
			password    required      pam_deny.so

			session     optional      pam_keyinit.so revoke
			session     required      pam_limits.so
			-session     optional      pam_systemd.so
			session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
			session     required      pam_unix.so
			##########################################
			#### Logging key strokes of all USERS ####
			##########################################
			session     required      pam_tty_audit.so disable=*  enable=* log_passwd
EOF
			xargs -n 1 cp -v /etc/pam.d/system-auth <<< ""${BACKUP} /etc/pam.d/system-auth.bak""
			no_show << EOF > /etc/pam.d/system-auth
			######################################################################################
			#### This system-auth file edited to match CIS level 1 requirements for questions ####
			####   or changes please contact Phil Connor contact@mylinux.work  #### 
			####            Please don't edit it unless you know what your doing              ####
			######################################################################################
			#%PAM-1.0
			# User changes will be destroyed the next time authconfig is run.
			auth        required      pam_env.so
			auth        required      pam_faildelay.so delay=2000000
			auth        required      pam_faillock.so preauth audit silent deny=5 unlock_time=900
			auth   [success=1 default=bad] pam_unix.so
			auth        sufficient    pam_fprintd.so
			auth        sufficient    pam_unix.so nullok try_first_pass
			auth      [default=die]   pam_faillock.so authfail audit deny=5 unlock_time=900
			auth        sufficient    pam_faillock.so authsucc audit deny=5 unlock_time=900
			auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
			auth        required      pam_deny.so

			account     required      pam_unix.so
			account     sufficient    pam_localuser.so
			account     sufficient    pam_succeed_if.so uid < 1000 quiet
			account     required      pam_permit.so
			account     required      pam_faillock.so

			password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= enforce_for_root
			password    required      pam_pwhistory.so remember=5 use_authlok
			password    sufficient    pam_unix.so remember=5 sha512 shadow try_first_pass use_authtok
			password    required      pam_deny.so

			session     optional      pam_keyinit.so revoke
			session     required      pam_limits.so
			-session     optional      pam_systemd.so
			session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
			session     required      pam_unix.so
			##########################################
			#### Logging key strokes of all USERS ####
			##########################################
			session     required      pam_tty_audit.so disable=*  enable=* log_passwd
EOF
		fi
		if [ "${OS}" = ubuntu ]; then 
			debconf-set-selections <<< ""postfix postfix/mailname string "${HOSTNAME}"""
			debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Local Only'"
			${PAKMGR} remove libpam-cracklib
			${PAKMGR} install libpam-pwquality --assume-yes
			xargs -n 1 cp -v /etc/pam.d/common-password<<< ""${BACKUP} /etc/pam.d/common-password.bak""  
			#sed -i 's/password[[:blank:]]*requisite[[:blank:]]*pam_pwquality.so retry=3/password	requisite			pam_pwquality.so retry=3 difok=3 reject_username enforce_for_root/g' /etc/pam.d/common-password
			sed -i 's/# minlen = 8/minlen = 14/g' /etc/security/pwquality.conf
			sed -i 's/# dcredit = 0/dcredit=-1/g' /etc/security/pwquality.conf
			sed -i 's/# ucredit = 0/ucredit=-1/g' /etc/security/pwquality.conf
			sed -i 's/# ocredit = 0/ocredit=-1/g' /etc/security/pwquality.conf
			sed -i 's/# lcredit = 0/lcredit=-1/g' /etc/security/pwquality.conf
			no_show << EOF >> /etc/pam.d/common-password
			################################################
			#### 5.3.3 Ensure password reuse is limited ####
			################################################     
			password        required                         pam_unix.so remember=5
			
EOF
			no_show << EOF >> /etc/pam.d/common-auth
			#########################################################################
			#### 5.3.2 Ensure lockout for failed password attempts is configured ####
			#########################################################################       
			auth    required                        pam_tally2.so onerr=fail audit silent deny=5 unlock_time=900

			##########################################
			#### Logging key strokes of all USERS ####
			##########################################
			session     required      pam_tty_audit.so disable=*  enable=* log_passwd
EOF
		fi
		stop_spinner $?
	} | tee -a $LOG
} 

Section 5.4 User Accounts and Enviroments

############################################
#### 5.4 User Accounts and Environments ####
############################################
function accounts() {
	{
		start_spinner 'Configuring User Accts and Environments...'
		echo ""
		LODEFS="/etc/login.defs"
		#### 5.4.1.1 Ensure password expiration is 90 days or less ####
		#### 5.4.1.2 Ensure minimum days between password changes is 7 days or more ####
		#### 5.4.1.3 Ensure password expiration warning days is 7 or more ####
		if [ -e ${LODEFS} ]; then
		cp ${LODEFS} ${LODEFS}.tmp
		awk '($1 ~ /^PASS_MAX_DAYS/) { $2="90" }
			($1 ~ /^PASS_MIN_DAYS/) { $2="7" }
			($1 ~ /^PASS_WARN_AGE/) { $2="10" }
			($1 ~ /^PASS_MIN_LEN/)  { $2="14" }
			{ print }' ${LODEFS}.tmp > ${LODEFS}
		rm ${LODEFS}.tmp
		fi
		cut -d: -f1 /etc/passwd | while read -r NAME
		do
			uid=$(id -u "${NAME}")
			if [ "${uid}" -ge 1000 ] && [ "${uid}" != 65534 ]; then
				chage -M 90 -m 7 -W 10 -I 30 "${NAME}"
			fi
		done
		if [ "${OS}" = ubuntu ]; then
			no_show << EOF >> ${LODEFS}
			##################################################################
			#### Make it More Difficult to Bruteforce the Hashed Password ####
			##################################################################
			SHA_CRYPT_MIN_ROUNDS 5000
			SHA_CRYPT_MAX_ROUNDS 10000
EOF
			sed -i 's/pam_faildelay.so  delay=3000000/pam_faildelay.so  delay=300000000/g' /etc/pam.d/login
		else	
			no_show << EOF >> ${LODEFS}
			############################################################################
			#### Establish a forced five-second minimum delay between failed logins ####
			############################################################################
			FAIL_DELAY 5
			
			##################################################################
			#### Make it More Difficult to Bruteforce the Hashed Password ####
			##################################################################
			SHA_CRYPT_MIN_ROUNDS 5000
			SHA_CRYPT_MAX_ROUNDS 10000
EOF
		fi
		chown root:root ${LODEFS}
		chmod 0640 ${LODEFS}
		#### 5.4.1.4 Ensure inactive password lock is 30 days or less ####
		useradd -D -f 30
		stop_spinner $?
	} | tee -a $LOG
}

function config_users_permissions() {
	{
		start_spinner 'Configuring User Permissions...'
		echo ""
		#### 5.4.2 Ensure system accounts are non-login ####
		awk -F: '($3 < 1000) {print $1 }' /etc/passwd | while read -r user 
		do
			if [ "$user" != "root" ]; then
				usermod -L "$user"
				if [ "$user" != "sync" ] && [ "$user" != "shutdown" ] && [ "$user" != "halt" ]; then
					usermod -s /usr/sbin/nologin "$user"
				fi
			fi
		done
		#### 5.4.3 Ensure default group for the root account is GID 0 ####
		usermod -g 0 root
		groupadd dev
		groupadd dba
		touch /etc/sudoers.d/cis_conf
		chmod 440 /etc/sudoers.d/cis_conf
		if [ "${OS}" = ubuntu ]; then
			sed -i 's/sudo:x:27:/sudo:x:27:root,ubuntu/g' /etc/group
			sed -i 's/sudo:*::/sudo:*::root,ubuntu/g' /etc/gshadow
			sed -i 's/%sudo[[:blank:]]*ALL=(ALL:ALL)[[:blank:]]*ALL/%sudo    ALL=\(ALL:ALL\) NOPASSWD:ALL/g' /etc/sudoers
		else
			grep -qi "wheel" /etc/group  
			if [ $? != 1 ]; then
				sed -i 's/%wheel[[:blank:]]*ALL=(ALL)[[:blank:]]*ALL/# %wheel        ALL=\(ALL\)       ALL/g' /etc/sudoers
				sed -i 's/^#\s*\(%wheel\s*ALL=(ALL)\s*NOPASSWD:\s*ALL\)/\1/' /etc/sudoers
				sed -i 's/wheel:x:10:opc/wheel:x:10:root,opc/g' /etc/group
				sed -i 's/wheel:::opc/wheel:::root,opc/g' /etc/gshadow
			fi
		fi
		{
		echo "####################"	
		echo "#### Networking ####" 
		echo "####################"
		} >> /etc/sudoers.d/local_conf
		if [ "${OS}" = ubuntu ]; then
			{
			echo "Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /sbin/iptables, /sbin/mii-tool" 
			echo ""
			} >> /etc/sudoers.d/local_conf
		else
			{
			echo "Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool" 
			echo ""
			} >> /etc/sudoers.d/local_conf
		fi
		{
		echo "#################################################" 
		echo "#### Installation and management of software ####" 
		echo "#################################################"
		} >> /etc/sudoers.d/cis_conf 
		if [ "${OS}" = ubuntu ]; then
			{
			echo "Cmnd_Alias SOFTWARE = usr/bin/apt, /usr/bin/dpkg, /usr/bin/apt-get" 
			echo ""
			} >> /etc/sudoers.d/local_conf
		else
			{
			echo "Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum" 
			echo ""
			} >> /etc/sudoers.d/local_conf
		fi
		{
			echo "##################"
			echo "#### Services ####"
			echo "##################"
			echo "Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start, /usr/bin/systemctl stop, /usr/bin/systemctl reload, /usr/bin/systemctl restart, /usr/bin/systemctl status, /usr/bin/systemctl enable, /usr/bin/systemctl disable"
			echo ""
			echo "######################################"
			echo "#### Updating the locate database ####"
			echo "######################################"
			echo "Cmnd_Alias LOCATE = /usr/bin/updatedb"
			echo ""
			echo "#################"
			echo "#### Storage ####"
			echo "#################"		
			echo "Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount"
			echo ""
			echo "################################"
			echo "#### Delegating permissions ####"
			echo "################################"
			echo "Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp"
			echo ""
			echo "###################"
			echo "#### Processes ####"
			echo "###################"
			echo "Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall"
			echo ""
			echo "#################"
			echo "#### Drivers ####"
			echo "#################"
			echo "Cmnd_Alias DRIVERS = /sbin/modprobe"
			echo ""
			echo "###########################################################################"
			echo "#### Reboot and ShutDown removed from DBA's and Developers 3/4/20 - PC ####"
			echo "###########################################################################"
			echo "Cmnd_Alias SHUTDOWN = /sbin/shutdown, /sbin/reboot, /sbin/halt, /sbin/poweroff"
			echo ""
			echo "###########################"
			echo "#### Our System Groups ####"
			echo "###########################"
			echo "%dba    ALL= NOPASSWD: /usr/bin/su - applmgr, /usr/bin/su - oracle, !NETWORKING, !SOFTWARE, !SERVICES, !STORAGE, !DELEGATING, !PROCESSES, !LOCATE, !DRIVERS, !SHUTDOWN"
			echo "%dev    ALL= NOPASSWD: /usr/bin/su - applmgr, !NETWORKING, !SOFTWARE, !SERVICES, !STORAGE, !DELEGATING, !PROCESSES, !LOCATE, !DRIVERS, !SHUTDOWN"
		} >> /etc/sudoers.d/local_conf
		#### 5.4.4 Ensure default user umask is 027 or more restrictive ####
		if [ "${OS}" = "ubuntu" ]; then 
			grep -Eq "^(\s*)umask\s+\S+(\s*#.*)?\s*$" /etc/bash.bashrc && sed -ri "s/^(\s*)umask\s+\S+(\s*#.*)?\s*$/\1umask 027\2/" /etc/bash.bashrc || echo "umask 027" >> /etc/bash.bashrc
		else	
			grep -Eq "^(\s*)umask\s+\S+(\s*#.*)?\s*$" /etc/bashrc && sed -ri "s/^(\s*)umask\s+\S+(\s*#.*)?\s*$/\1umask 027\2/" /etc/bashrc || echo "umask 027" >> /etc/bashrc
		fi
		grep -Eq "^(\s*)umask\s+\S+(\s*#.*)?\s*$" /etc/profile && sed -ri "s/^(\s*)umask\s+\S+(\s*#.*)?\s*$/\1umask 027\2/" /etc/profile || echo "umask 027" >> /etc/profile
		#### 5.4.5 Ensure default user shell timeout is 900 seconds or less ####
		if grep TMOUT=900 /etc/bashrc; then
			sed -i 's/TMOUT=900/#TMOUT=900/g' /etc/bashrc
		fi

		if grep TMOUT=900 /etc/profile; then
			sed -i 's/TMOUT=900/#TMOUT=900/g' /etc/profile
		fi
		cat >> /etc/profile << 'EOF'
		if [ "$(id -nu)" == "root" ] || [ "$(id -nu)" == "opc" ]; then
			TMOUT=3600
			readonly TMOUT
			export TMOUT
		else
			TMOUT=900
			readonly TMOUT
			export TMOUT
		fi
EOF
		cat >> /etc/bashrc << 'EOF'
		if [ "$(id -nu)" == "root" ] || [ "$(id -nu)" == "opc" ]; then
			if ! echo $TMOUT | grep -q 3600; then
				TMOUT=3600
				readonly TMOUT
				export TMOUT
			fi
		else
			if ! echo $TMOUT | grep -q 900; then
				TMOUT=900
				readonly TMOUT
				export TMOUT
			fi
		fi
EOF
		#### 5.4.5A Ensure default user umask is configured - system wide ####
		sed -ri 's/^([^#]+\s+)?(umask\s+)(\S+\s*)(\s+.*)?$/\1\2 027\4/' /etc/login.defs
		sed -ri 's/^([^#]+\s+)?(umask\s+)(\S+\s*)(\s+.*)?$/\1\2 027\4/' /etc/profile
		sed -ri 's/^([^#]+\s+)?(umask\s+)(\S+\s*)(\s+.*)?$/\1\2 027\4/' /etc/bashrc
		touch /etc/profile.d/cis_profile.sh
		chmod 644 /etc/profile.d/cis_profile.sh
		echo "
		################################
		### Added for CIS Compliance ###
		################################
		umask 077
			" > /etc/profile.d/cis_profile.sh
		#### 5.5 Ensure root login is restricted to system console ####
		xargs -n 1 cp -v /etc/securetty <<< ""${BACKUP} /etc/securetty.bak""
		echo "console" > /etc/securetty
		### 5.6 Ensure access to the su command is restricted ###
		PAMSU="/etc/pam.d/su"
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle ]]; then
			xargs -n 1 cp -v ${PAMSU} <<< ""${BACKUP} ${PAMSU}.bak""
			if [ -e ${PAMSU} ]; then
				cp ${PAMSU} ${PAMSU}.tmp
				awk '( $1=="#auth" && $2=="required" && $3~"pam_wheel.so" ) { print "auth\t\trequired\t",$3,"\tuse_uid"; next };
					{ print }' ${PAMSU}.tmp > ${PAMSU}
				chown root:root ${PAMSU}
				chmod 0644 ${PAMSU}
				rm ${PAMSU}.tmp
			fi
		elif [ "${OS}" = ubuntu ]; then
			sed -i 's/# auth[[:blank:]]*required[[:blank:]]*pam_wheel.so/auth        required    pam_wheel.so use_uid/g' /etc/pam.d/su
			sed -i 's/auth        required    pam_wheel.so use_uid deny group=nosu/#auth        required    pam_wheel.so deny group=nosu/g' /etc/pam.d/su
		fi
		stop_spinner $?
	} | tee -a $LOG
} 

Section 6.1 System Permissions

################################
#### 6.1 System Permissions ####
################################
function audit_file_permissions() {
	{
	start_spinner 'Auditing File Permissions...'
	echo ""
	### 6.1.1 Audit system file permissions ###
	if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle ]]; then
		rpm -Va --nomtime --nosize --nomd5 --nolinkto
	elif [ "${OS}" = ubuntu ]; then 
		${PAKMGR} install debsums
		debsums -s
	fi
	### 6.1.2 Ensure permissions on /etc/passwd are configured ###
	chmod 644 /etc/passwd
	chown root.root /etc/passwd
	### 6.1.3 Ensure permissions on /etc/shadow are configured ###
	chmod 000 /etc/shadow
	chown root.root /etc/shadow
	### 6.1.4 Ensure permissions on /etc/group are configured ###
	chmod 644 /etc/group
	chown root.root /etc/group
	### 6.1.5 Ensure permissions on /etc/gshadow are configured ###
	chmod 000 /etc/gshadow
	chown root:root /etc/gshadow
	### 6.1.6 Ensure permissions on /etc/passwd- are configured ###
	chmod 644 /etc/passwd-
	chown root.root /etc/passwd-
	### 6.1.7 Ensure permissions on /etc/shadow- are configured ###
	chmod 000 /etc/shadow-
	chown root.root /etc/shadow-
	### 6.1.4 Ensure permissions on /etc/group- are configured ###
	chmod 644 /etc/group-
	chown root.root /etc/group-
	### 6.1.5 Ensure permissions on /etc/gshadow- are configured ###
	chmod 000 /etc/gshadow-
	chown root:root /etc/gshadow-
	stop_spinner $?
	} | tee -a $LOG
} 

Section 6.1.1 World Writable Files

####################################
#### 6.1.1 World Writable Files ####
####################################
function world_writable_files() {
	{
		start_spinner 'Resetting Permissions on all World Writable, Unowned and Ungrouped Files...'
		echo ""
		#### 6.1.10 Ensure no world writable files exist ####
		df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002 
		#### 6.1.11 Ensure no unowned files or directories exist ####
		df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nouser -ls 
		#### 6.1.12 Ensure no ungrouped files or directories exist ####
		df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nogroup -ls 
		#### 6.1.12 Audit SUID executables ####
		df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -4000 -print 
		#### 6.1.14 Audit SGID executables ####
		df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -2000 -print
		stop_spinner $?
	} | tee -a $LOG
} 

Section 6.2 User and Group Settings

#####################################
#### 6.2 User and Group Settings ####
#####################################
function user_group_settings() {
	{
		start_spinner 'Configuring User and Group Settings...'
		echo ""
		### 6.2.1 Ensure password fields are not empty ###
		awk -F: '($2 == "" ) { print $1 " does not have a password "}' /etc/shadow
		### 6.2.2 Ensure no legacy "+" entries exist in /etc/passwd ###
		grep '^+:' /etc/passwd
		### 6.2.3 Ensure no legacy "+" entries exist in /etc/shadow ###
		grep '^+:' /etc/shadow
		### 6.2.4 Ensure no legacy "+" entries exist in /etc/group ###
		grep '^+:' /etc/group
		### 6.2.5 Ensure root is the only UID 0 account ###
		awk -F: '($3 == 0) { print $1 }' /etc/passwd
		### 6.2.6 Ensure root PATH Intergrity ###
		if [ "$(echo "$PATH" | grep ::)" != "" ]; then
			echo "Empty Directory in PATH (::)"
		fi
		if [ "$(echo "$PATH" | grep :$)"  != "" ]; then
			echo "Trailing : in PATH"
		fi
		p=$(echo "$PATH" | sed -e 's/::/:/' -e 's/:$//' -e 's/:/ /g')
		set -- "$p"
		while [ "$1" != "" ]; 
		do
			if [ "$1" = "." ]; then
				echo "PATH contains ."
				shift
				continue
			fi
			if [ -d "$1" ]; then
				# shellcheck disable=SC2012
				dirperm=$(ls -ldH "$1" | cut -f1 -d" ")
				if [ "$(echo "${dirperm}" | cut -c6)" != "-" ]; then
					echo "Group Write permission set on directory $1"
				fi
				if [ "$(echo "${dirperm}" | cut -c9)" != "-" ]; then
					echo "Other Write permission set on directory $1"
				fi
				# shellcheck disable=SC2012
				dirown=$(ls -ldH "$1" | awk '{print $3}')
				if [ "${dirown}" != "root" ] ; then
					echo "$1 is not owned by root"
				fi
				else
					echo "$1 is not a directory"
			fi
		shift
		done
		stop_spinner $?
	} | tee -a $LOG
} 

Section 6.2 Continued - Part 1

###############################################
#### 6.2 User and Group Settings Continued ####
###############################################
function home_directories() {
	{
		start_spinner 'Checking and Configuring User Directories...'
		echo ""
		#### 6.2.7 Ensure all users' home directories exist ####
		awk -F: '{ print $1 " " $3 " " $6 }' /etc/passwd | while read -r user uid dir 
		do
			if [ "${uid}" -ge 500 ] && [ -d "${dir}" ] && [ "${user}" != "nfsnobody" ]; then
				owner=$(stat -L -c "%U" "${dir}")
				if [ "${owner}" != "${user}" ]; then
					echo "The home directory (${dir}) of user ${user} is owned by ${owner}."
				fi
			fi
		done
		#### 6.2.8 Ensure users' home directories permissions are 750 or more restrictive ####
		grep -Ev '(root|halt|sync|shutdown)' /etc/passwd | awk -F: '($8 == "PS" && $7 != "/sbin/nologin") { print $6 }' | while read -r dir 
		do
			# shellcheck disable=SC2012
			dirperm=$(ls -ld "${dir}" | cut -f1 -d" ")
			if [ "$( echo "${dirperm}" | cut -c6 )" != "-" ]; then
				echo "Group Write permission set on directory $dir"
			fi
			if [ "$( echo "${dirperm}" | cut -c8 )" != "-" ]; then
				echo "Other Read permission set on directory $dir"
			fi
			if [ "$( echo "${dirperm}" | cut -c9 )" != "-" ]; then
				echo "Other Write permission set on directory $dir"
			fi
			if [ "$( echo "${dirperm}" | cut -c10 )" != "-" ]; then
				echo "Other Execute permission set on directory $dir"
			fi
		done
		#### 6.2.9 Ensure users own their home directories ####
		awk -F: '{ print $1 " " $3 " " $6 }' /etc/passwd | while read -r user uid dir 
		do
			if [ "$uid" -ge 500 ] && [ ! -d "$dir" ] && [ "$user" != "nfsnobody" ]; then
				echo "The home directory ($dir) of user $user does not exist."
			fi
		done
		stop_spinner $?
	} | tee -a $LOG
} 

Section 6.2 Continued - Part 2

########################################################
#### 6.2 User and Group Settings Continued - Part 2 ####
########################################################
function dot_files() {
	{
		start_spinner 'Checking and Configuring Hidden Files and Directories...'
		echo ""
		#### 6.2.10 Ensure users' dot files are not group or world writable ####
		grep -Ev '(root|sync|halt|shutdown)' /etc/passwd | awk -F: '($7 != "/sbin/nologin") { print $6 }' | while read -r dir
		do
			for file in "$dir"/.[A-Za-z0-9]* 
			do
				if [ ! -h "${file}" ] && [ -f "${file}" ]; then
					# shellcheck disable=SC2012
					fileperm=$(ls -ld "$file" | cut -f1 -d" ")
					if [ "$(echo "$fileperm" | cut -c6 )" != "-" ]; then
						echo "Group Write permission set on file $file"
					fi
					if [ "$(echo "$fileperm" | cut -c9 )" != "-" ]; then
						echo "Other Write permission set on file $file"
					fi
				fi
			done
		done
		awk -F: '($3 >= 500) { print $6 }' /etc/passwd | while read -r DIR
		do
			for FILE in "$DIR"/.[A-Za-z0-9]*
			do
				if [ ! -h "$FILE" ] && [ -f "$FILE" ]; then
					chmod go-w "$FILE"
				fi
			done
		done
		#### 6.2.11 Ensure no users have .forward files ####
		awk -F: '{ print $6 }' /etc/passwd | while read -r dir 
		do
			if [ ! -h "$dir/.forward" ] && [ -f "$dir/.forward" ]; then
				echo ".forward file $dir/.forward exists"
			fi
		done
		#### 6.2.12 Ensure no users have .netrc files ####
		awk -F: '{ print $6 }' /etc/passwd | while read -r dir 
		do
			if [ ! -h "$dir/.netrc" ] && [ -f "$dir/.netrc" ]; then
				echo ".netrc file $dir/.netrc exists"
			fi
		done
		#### Ensure users' .netrc Files are not group or world accessible ####
		grep -Ev '(root|halt|sync|shutdown)' /etc/passwd | awk -F: '($7 != "/sbin/nologin") { print $6 }' | while read -r dir 
		do
			for file in $dir/.netrc 
			do
				if [ ! -h "$file" ] && [ -f "$file" ]; then
					# shellcheck disable=SC2012
					fileperm=$(ls -ld "$file" | cut -f1 -d" ")
					if [ "$(echo "$fileperm" | cut -c5 )" != "-" ]; then
						echo "Group Read set on $file"
					fi
					if [ "$(echo "$fileperm" | cut -c6 )" != "-" ]; then
						echo "Group Write set on $file"
					fi
					if [ "$(echo "$fileperm" | cut -c7 )" != "-" ]; then
						echo "Group Execute set on $file"
					fi
					if [ "$(echo "$fileperm" | cut -c8 )" != "-" ]; then
						echo "Other Read  set on $file" 
					fi
					if [ "$(echo "$fileperm" | cut -c9 )" != "-" ]; then
						echo "Other Write set on $file"
					fi
					if [ "$(echo "$fileperm" | cut -c10 )" != "-" ]; then
						echo "Other Execute set on $file"
					fi
				fi	
			done
		done
		#### Ensure no users have .rhosts files ####
		grep -Ev '(root|halt|sync|shutdown)' /etc/passwd | awk -F: '($7 != "/sbin/nologin") { print $6 }' | while read -r dir 
		do
			for file in $dir/.rhosts; do
				if [ ! -h "$file" ] && [ -f "$file" ]; then
					echo ".rhosts file in $dir" 
				fi
			done
		done
		stop_spinner $?
	} | tee -a $LOG
} 

Section 6.2 Continued - Part 3

########################################################
#### 6.2 User and Group Settings Continued - Part 3 ####
########################################################
function group_gid_uid() {
	{
		start_spinner 'Checking that all Group and UserIDs are valid...'
		echo ""
		#### Ensure all groups in etc/passwd exist in /etc/group ####
		cut -s -d: -f4 /etc/passwd | sort -u | while read -r i
		do
			if ! grep -q -P "^.*?:x:$i:" /etc/group; then
				echo "Group $i is referenced by /etc/passwd but does not exist in /etc/group" 
			fi
		done
		#### Ensure no duplicate UIDs exist ####
		cut -f3 -d":" /etc/passwd | sort -n | uniq -c | while read -r x  
		do
			[ -z "${x}" ] && break
			# shellcheck disable=SC2086
			set - ${x}
			if [ "$1" -gt 1 ]; then
				users=$(awk -F: '($3 == n) { print $1 }' n="$2" /etc/passwd | xargs)
				echo "Duplicate UID ($2): ${users}" 
			fi
		done
		#### 6.2.17 Ensure no duplicate GIDs exist ####
		cut -f3 -d":" /etc/group | sort -n | uniq -c | while read -r x  
		do
			[ -z "${x}" ] && break
			# shellcheck disable=SC2086
			set - ${x}
			if [ "$1" -gt 1 ]; then
				grps=$(gawk -F: '($3 == n) { print $1 }' n="$2" /etc/group | xargs)
				echo "Duplicate GID ($2): ${grps}" >> ${LOG} 2>&1
			fi
		done
		#### 6.2.18 Ensure no duplicate user names exist ####
		cut -f1 -d":" /etc/passwd | sort -n | /usr/bin/uniq -c | while read -r x  
		do
			[ -z "${x}" ] && break
			# shellcheck disable=SC2086
			set - ${x}
			if [ "$1" -gt 1 ]; then
				uids=$(gawk -F: '($1 == n) { print $3 }' n="$2" /etc/passwd | xargs)
				echo "Duplicate User Name ($2): ${uids}" 
			fi
		done
		#### 6.2.19 Ensure no duplicate group names exist ####
		cut -f1 -d":" /etc/group | sort -n | uniq -c | while read -r x  
		do
			[ -z "${x}" ] && break 
			set - "${x}" 
			if [ "$1" -gt 1 ]; then
				gids=$(gawk -F: '($1 == n) { print $3 }' n="$2" /etc/group | xargs) 
				echo "Duplicate Group Name ($2): ${gids}" 
			fi 
		done
		stop_spinner $?
	} | tee -a $LOG
} 

This is the end of the security code blocks.

now for the additional addons,

Add-on 1 - Unattended Upgrade

#########################################
#### Auto Unattended Security Upates ####
#########################################
function auto_updates() {
	{
		start_spinner 'Configuring Auto Security Updates...'
		echo ""
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
			if [ "${OSVER}" = 7 ]; then
				${PAKMGR} install yum-cron 
				sed -i 's/update_cmd = default/update_cmd = security/g' /etc/yum/yum-cron.conf
				sed -i 's/apply_updates = no/apply_updates = yes/g' /etc/yum/yum-cron.conf
				sed -i 's/download_updates = no/download_updates = yes/g' /etc/yum/yum-cron-hourly.conf
				systemctl enable yum-cron 
				systemctl start yum-cron
			fi
			if [ "${OSVER}" = 8 ]; then
				${PAKMGR} install dnf-automatic 
				sed -i 's/upgrade_type = default/upgrade_type = security/g' /etc/dnf/automatic.conf
				sed -i 's/apply_updates = no/apply_updates = yes/g' /etc/dnf/automatic.conf
				systemctl enable --now dnf-automatic.timer
			fi
		elif [ "${OS}" = ubuntu ]; then
			${PAKMGR} install unattended-upgrades apticron
			touch /etc/apt/apt.conf.d/20auto-upgrades
			no_show << EOF > /etc/apt/apt.conf.d/20auto-upgrades
			APT::Periodic::Update-Package-Lists "1";
			APT::Periodic::Download-Upgradeable-Packages "1";
			APT::Periodic::AutocleanInterval "7";
			APT::Periodic::Unattended-Upgrade "1";
EOF
			sed -i 's/\/\/Unattended-Upgrade\:\:Mail "root";/Unattended-Upgrade\:\:Mail "root";/g' /etc/apt/apt.conf.d/50unattended-upgrades
		fi
		stop_spinner $?
	} | tee -a $LOG
}

this part of the script only set auto update for the security packages, when your working with a large server farm this makes it a little easier to keep up with them, not required just something I use, (also with a slight change you can do full upgrades if you wanted)

Add-on 2 - Audit  Log compression

################################
#### Auditd Compression Log ####
################################
function compress_auditd() {
	{
		start_spinner 'Installing Auditd Cmpression Cron Script...'
		echo ""
		touch /etc/cron.daily/audit
		{
		echo '#!/bin/bash'
		echo ""
		echo "##############################################################################################"
		echo "#### This auditd script is to get a daily compressed log rotation using a daily cron job. ####"
		echo "#### in /etc/cron.daily for questions or changles please contact  Phil Connor             ####"
		echo "#### Phil Connor contact@mylinux.work  Remember to set                     ####"
		echo "####  max_log_file_action = ignore in /etc/audit/auditd.conf when using this script       ####"
		echo "##############################################################################################"
		echo ""
		echo "FORMAT=\"%F_%T\"  # Customize timestamp format as desired Default is (%F_%T which gives you audit.log.2015-02-26_15:43:46)"
		echo "COMPRESS=gzip   # Change to bzip2 or xz as desired (Default is gzip)"
		echo "KEEP=60         # Number of days of compressed log files to keep (Default is 60)"
		echo "ROTATE_TIME=5   # Amount of time in seconds to wait for auditd to rotate its logs. (Default is 5)"
		echo ""
		echo "rename_and_compress_logs() {"
		echo "    for file in \$(find /var/log/audit/ -regextype posix-extended -regex '.*audit.log.[0-9]{1,}\$')" 
		echo "    do"
		echo "        timestamp=\$(ls -l --time-style=\"+ \${FORMAT}\" \${file} | awk '{print \$6}')"
		echo "        newfile=\${file%.[0-9]}.\${timestamp}"
		echo "        mv -v \"\${file} \"\${newfile}\""
		echo "        \"\${COMPRESS}\" -v \"\${newfile}\""
		echo "    done"
		echo "}"
		echo ""
		echo "delete_old_compressed_logs() {"
		echo "    find /var/log/audit/ -mtime +\"\${KEEP}\" -regextype posix-extended -regex \".*audit\\.log\\..*(xz|gz|bz2)\$\" -delete"
		echo "}"
		echo ""
		echo "service auditd rotate"
		echo -e "sleep \$ROTATE_TIME"
		echo "rename_and_compress_logs"
		echo "delete_old_compressed_logs"
		} > /etc/cron.daily/audit
		chmod 755 /etc/cron.daily/audit
		stop_spinner $?
	} | tee -a $LOG
}

No matter what you picked in the Audit Log Menu, this little script will compress and date the file for you to conserve drive space.  

Addon 3 - SysStat

#######################################################
#### Install SysStat Redhat/CentOS 7 and 8, Ubuntu ####
#######################################################
function install_sysstat() {
	{
		start_spinner 'Installing and Configuring SysStat...'
		echo ""
		${PAKMGR} install sysstat
		if [ "${OS}" = ubuntu ]; then
			sed -i 's/ENABLED="false"/ENABLED="true"/g' /etc/default/sysstat
			no_show << EOF > /etc/cron.d/sysstat
			# The first element of the path is a directory where the debian-sa1
			# script is located
			PATH=/usr/lib/sysstat:/usr/sbin:/usr/sbin:/usr/bin:/sbin:/bin
		
			# Activity reports every 10 minutes everyday
			5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1
			
			# Additional run at 23:59 to rotate the statistics file
			59 23 * * * root command -v debian-sa1 > /dev/null && debian-sa1 60 2
EOF
		else
			if [ ! -d /var/log/sa ]; then
				mkdir /var/log/sa
			fi
		fi
		systemctl enable sysstat 
		systemctl start sysstat 
		stop_spinner $?
	} | tee -a $LOG
}

Add-on 4 - Rootkit Hunter

##############################################################
#### Install RootKit Hunter Redhat/CentOS 7 and 8, Ubuntu ####
##############################################################
function install_rkhunter() {
	{
		start_spinner 'Installing and Configuring RKHunter...'
		echo ""
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = rocky || ${OS} = alma ]]; then
			${PAKMGR} install epel-release 
			${PAKMGR} install rkhunter 
		elif [ "${OS}" = oracle ]; then
			if [ "${OSVER}" = 7 ]; then
				${PAKMGR} install oracle-epel-release-el7
				sed -i 's/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-epel-ol7.repo
			fi
			if [ "${OSVER}" = 8 ]; then
				${PAKMGR} install oracle-epel-release-el8
				sed -i 's/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-epel-ol8.repo
			fi		
			${PAKMGR} install rkhunter 
		elif [ "${OS}" = ubuntu ]; then
			debconf-set-selections <<< ""postfix postfix/mailname string "${HOSTNAME}"""
			debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Local Only'"
			DEBIAN_FRONTEND=noninteractive ${PAKMGR} install rkhunter >> ${LOG} 2>&1
		fi
		rkhunter --update
		rkhunter --propupd
		sed -i 's/ALLOW_SSH_ROOT_USER=unset/ALLOW_SSH_ROOT_USER=no/g' /etc/rkhunter.conf
		stop_spinner $?
	} | tee -a $LOG
} 

Add-on 5 - LMD (Linux Malware Detect)

###################################################
#### Install LMD Redhat/CentOS 7 and 8, Ubuntu ####
###################################################
function install_lmd() {
	{
		start_spinner 'Installing and Configuring MalDetect...'
		echo ""
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = rocky || ${OS} = alma ]]; then
			${PAKMGR} install epel-release 
			${PAKMGR} install mailx inotify-tools tar wget
		elif [ "${OS}" = oracle ]; then
			if [ "${OSVER}" = 7 ]; then
				${PAKMGR} install oracle-epel-release-el7
				sed -i 's/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-epel-ol7.repo
			fi
			if [ "${OSVER}" = 8 ]; then
				${PAKMGR} install oracle-epel-release-el8
				sed -i 's/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-epel-ol8.repo
			fi
			${PAKMGR} install mailx inotify-tools tar wget
		elif [ "${OS}" = ubuntu ]; then
			export DEBIAN_FRONTEND=noninteractive
			${PAKMGR} install inotify-tools wget
		fi
			wget http://www.rfxn.com/downloads/maldetect-current.tar.gz 
			tar -xvzf maldetect-current.tar.gz 
			cd maldetect-1* || return $?
			./install.sh 
			cd .. || return $?
			rm -rf maldetect-*
		if [ "${OS}" = ubuntu ]; then
			ln -s /usr/local/maldetect/maldet /bin/maldet
			hash -r
		fi
		sed -i 's/email_alert="0"/email_alert="1"/g' /usr/local/maldetect/conf.maldet
		sed -i 's/email_addr="you@domain.com"/email_addr="root@localhost"/g' /usr/local/maldetect/conf.maldet
		sed -i 's/quarantine_hits="0"/quarantine_hits="1"/g' /usr/local/maldetect/conf.maldet
		sed -i 's/quarantine_clean="0"/quarantine_clean="1"/g' /usr/local/maldetect/conf.maldet
		if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle ]]; then
			${PAKMGR} install clamav clamav-devel
		elif [ "${OS}" = ubuntu ]; then
			export DEBIAN_FRONTEND=noninteractive
			${PAKMGR} install clamav clamav-daemon clamdscan clamav-freshclam
		fi
		freshclam
		stop_spinner $?
		} | tee -a $LOG
} 

Add-on 6 - Logwatch 

##########################
#### Install Logwatch ####
##########################
function install_logwatch() {
	{
		start_spinner 'Installing and Configuring LogWatch...'
		${PAKMGR} install logwatch
		LOG_ZZ=/usr/share/logwatch/default.conf/services/zz-disk_space.conf
		# shellcheck disable=SC2016
		sed -i 's/#$show_home_dir_sizes = 1/$show_home_dir_sizes = 1/g' $LOG_ZZ
		# shellcheck disable=SC2016
		sed -i 's/#$home_dir = "\/home"/$home_dir = "\/home"/g' $LOG_ZZ
		# shellcheck disable=SC2016
		sed -i 's/#$show_mail_dir_sizes = 1/#$show_mail_dir_sizes = 1/g' $LOG_ZZ
		# shellcheck disable=SC2016
		sed -i 's/#$mail_dir = "\/var\/spool\/mail/$mail_dir = "\/var\/spool\/mail/g' $LOG_ZZ
		# shellcheck disable=SC2016
		sed -i 's/#$show_disk_usage = 1/$show_disk_usage = 1/g' $LOG_ZZ
		# shellcheck disable=SC2016
		sed -i 's/$HTTP_IGNORE_ERROR_HACKS = 0/$HTTP_IGNORE_ERROR_HACKS = 1/g' /usr/share/logwatch/default.conf/services/http.conf
		sed -i 's/Detail = Low/Detail = Med/g' /usr/share/logwatch/default.conf/logwatch.conf
		stop_spinner $?
	} | tee -a $LOG
} 

Include 1 - Oracle EBS Pre Install

###############################
#### Oracle EBS PreInstall ####
###############################
function oci_oracle_ebs_setup() {
	{
		start_spinner 'Configuring Server for Oracle EBS/WebLogic...'
		if [ "${SRVTYPE}" != 3 ]; then
			if [[ ${OS} = centos || ${OS} = redhat || ${OS} = rocky || ${OS} = alma ]]; then 
				${PAKMGR} install oracle-ebs-server-R12-preinstall openmotif21
				oci-network-config -X ens3
				sed -i 's/PRESERVE_HOSTINFO=0/PRESERVE_HOSTINFO=2/g' /etc/oci-hostname.conf
				groupadd dba
				groupadd dev
				touch /etc/oraInst.loc
				chmod 600 /etc/oraInst.loc
				chown applmgr. /etc/oraInst.loc
			elif [ "${OS}" = ubuntu ]; then
				echo ""
				echo -e "\e[7m**** !EBS PreInstall for Ubuntu is not supported! ****\e[0m"
				echo ""
			fi
		fi
		if [ "${SRVTYPE}" == 3 ]; then
			oci-network-config -X ens3
			sed -i 's/PRESERVE_HOSTINFO=0/PRESERVE_HOSTINFO=2/g' /etc/oci-hostname.conf
		fi	
	} | tee -a $LOG
} 

All Combined Function Calls

########################
#### Function Calls ####
########################
function oci_rh_ub_common() {
	{
		check_root
		backup
		make_swap
		time_set
		disable_filesystems
		tmp_directory
		stickybit
		gpgkeys
		aide_install
		sudo_changes
		boot_load
		core_dumps
		sysctl_conf
		pre_link
		se_troubleshoot_mcs
		unconf_daemons
		se_linux
		banners
		inet_service
		ntp_config
		chrony_cfg
		update_security
		unsecure_services
		mail_config
		addon_inet_services
		service_clients
		tcp_wrappers
		auto_updates
		uncommon_protocols
		iptables_config
		audit_accounting
		rsyslog_service
		journald_config
		logfile_permissions
		crond_enabled
		compress_auditd
		config_sshd
		config_pam
		accounts
		config_users_permissions
		audit_file_permissions
		world_writable_files
		user_group_settings
		home_directories
		dot_files
		group_gid_uid
		install_sysstat
		install_rkhunter
		install_lmd
		install_logwatch
	}
} 

OCI and AWS Firewall Change Calls

##################
#### OCI Only ####
##################
function oci_only() {
	{
		oci_iptables
	} 
}

##################
#### AWS Only ####
##################
function aws_only() {
	{
		aws_iptables
	}
} 

Install Complete

Install Complete Image

This shows that the install has completed, it is strongly recommend that you open another ssh window to the server while this window is there to make sure you can still connect, otherwise you will have to console into the system to fix it.

You can download this script here

Comments