Website/SecureIt.sh

3984 lines
141 KiB
Bash

#!/bin/bash
###############################################################################
#### Hardening Script for Oracle Linux, Centos/Redhat and Ubuntu Servers. ####
#### Author: Phil Connor 02/10/2020 ####
#### Contact: contact@mylinux.work ####
#### Version 3.30.03.26.22 ####
#### ####
#### To Use chmod to 755 or simply type bash <SecureIt.sh> ####
###############################################################################
clear
export TERM=xterm-256color
############################
#### User Configuration ####
############################
RSWP=8 # <-- Set the required swap size
TCPPORTS=( 22 53 1521 5666 7001 7002 8000 9090 10000 ) # <-- Firwall ports that you need open, don't remove 22 unless you will only contecting with a console
TCP6PORTS=( 22 ) # <-- IPv6 is disabled but Nessus scans requires it configured
UDPPORTS=( 53 ) # <-- Gotta have DNS
UDP6PORTS=( 53 ) # <-- Gotta have DNS
##########################
#### 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"
HOSTNAME=$(uname -n)
LOG=${BACKUP}/install.log
MODPRO="/etc/modprobe.d/cis.conf"
MYIP=$(netstat -putan | awk '/:22 / && /ESTABLISHED/ {split($5,result,":"); print result[1]}')
NTP_FILE="/etc/ntp.conf"
if [ "$(command -v lsb_release)" ]; then
OS=$(lsb_release -i | awk '{print $3}' | tr '[:upper:]' '[:lower:]')
OSVER=$(lsb_release -r | awk '{print $2}' | awk -F. '{print $1}')
else
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}')
fi
SSHD_FILE='/etc/ssh/sshd_config'
TMPMNT="/usr/lib/systemd/system"
########################
#### Menu Variables ####
########################
H1=20
R1=3
R2=6
R3=11
W1=80
###########################################################
#### Detect Package Manger from OS and OSVer Variables ####
###########################################################
if [[ ${OS} = alma || ${OS} = amazon || ${OS} = centos || ${OS} = red || ${OS} = rocky || ${OS} = oracle ]]; then
if [ "${OSVER}" = 7 ]; then
PAKMGR="yum -y"
else
PAKMGR="dnf -y"
fi
elif [ "${OS}" = ubuntu ]; then
PAKMGR="apt -y"
fi
##############################################
#### 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
}
}
#################################
#### Config backup directory ####
#################################
function backup() {
{
for dir in ${BACKUP}; do
[[ ! -d "$dir" ]] && mkdir "$dir"
touch ${BACKUP}/install.log
done
}
}
#######################
#### Copy Function ####
#######################
function no_show() {
{
expand | awk 'NR == 1 {match($0, /^ */); l = RLENGTH + 1}
{print substr($0, l)}'
}
}
##########################
#### 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 start_spinner {
{
echo ""
_spinner "start" "${1}" &
_sp_pid=$!
echo ""
disown
}
}
######################
#### Spinner Stop ####
######################
function stop_spinner {
{
echo ""
_spinner "stop" "$1" $_sp_pid
unset _sp_pid
echo ""
}
}
#########################
#### 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
}
}
#############################
#### 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
}
}
######################
#### 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
}
}
##################################
#### 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
}
}
################################
#### 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
}
}
###########################
#### 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
}
}
##########################
#### 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
}
}
#########################
#### 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}" = ubuntu ]; then
G2PASSWD="$(echo -e "${GPASS}\n$GPASS" | grub-mkpasswd-pbkdf2 2>/dev/null | tail --lines=1 | awk -F " " '{print $7}')"
main_menu
else
G2PASSWD="$(echo -e "${GPASS}\n$GPASS" | grub2-mkpasswd-pbkdf2 2>/dev/null | tail --lines=1 | awk -F " " '{print $7}')"
main_menu
fi
else
exit
fi
}
}
#############################
#### 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
}
}
#####################
#### 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
}
}
#####################
#### 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
}
}
#####################
#### 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
}
}
##########################
#### Install Complete ####
##########################
function complete() {
{
whiptail --backtitle "SecureIt contact@mylinux.work" --title "Configuration Complete" --msgbox " This script has configured and hardened this server to
CIS Level 1 Benchmark settings.
It is recommended that you try to ssh to the sever as any user
or root to make sure you can connect and once you know all is working
properly the system should be rebooted.
Please select \"OK\" to EXIT." ${H1} ${W1} 3>&1 1>&2 2>&3
exitstatus=$?
if [ ${exitstatus} = 0 ]; then
exit
fi
}
}
#####################################################################
### The following is in line with the CIS BenchMark Manual v3.0.0 ###
#####################################################################
#############################
#### 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
}
############################
#### Set Sever TimeZone ####
############################
function time_set() {
{
start_spinner 'Setting System TimeZone...'
echo ""
timedatectl set-timezone US/"${TIMEZONE}"
stop_spinner $?
} | tee -a $LOG
}
########################################
### 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
}
######################################################
#### 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} = red || ${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
}
#############################################################################
#### 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
}
##############################################
#### 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
}
########################################
#### 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
}
###########################
#### 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
}
##################################
#### 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
}
################################################
#### 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
}
###########################################################################
#### 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
}
##########################################
#### 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
}
########################################################
#### 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} = red || ${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
}
######################################################
#### 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
}
###########################################
#### 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
}
##################################################################
#### 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
}
#####################################################################################
#### 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
}
############################
#### 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
}
#######################################################
#### 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} = red || ${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} = red || ${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
}
#######################################################
#### 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
}
#############################################################################
#### 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
}
################################################
#### 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} = red || ${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} = red || ${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} = red || ${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
}
###############################################################
#### 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
}
##########################
#### 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 $?
}
}
########################################
#### 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
}
########################################
#### 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} = red || ${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} = red || ${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} = red || ${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
}
##################################################
#### 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
}
#########################################
#### 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} = red || ${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} = red || ${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
}
#################################
#### 4.2.1 Configure rsyslog ####
#################################
function rsyslog_service() {
{
if [[ ${OS} = centos || ${OS} = red || ${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
}
####################################################
#### 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
}
##################################
#### 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} = red || ${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
}
#############################################
#### 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
}
######################################
#### 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} = red || ${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
}
###########################
#### 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} = red || ${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
}
############################################
#### 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
}
######################################################
#### 5.4 User Accounts and Environments Continued ####
######################################################
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} = red || ${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
}
################################
#### 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} = red || ${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
}
####################################
#### 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
}
#####################################
#### 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
}
########################################################
#### 6.2 User and Group Settings Continued - Part 1 ####
########################################################
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
}
########################################################
#### 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
}
########################################################
#### 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
}
#########################################
#### Auto Unattended Security Upates ####
#########################################
function auto_updates() {
{
start_spinner 'Configuring Auto Security Updates...'
echo ""
if [[ ${OS} = centos || ${OS} = red || ${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
}
#######################################################
#### 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
}
##############################################################
#### Install RootKit Hunter Redhat/CentOS 7 and 8, Ubuntu ####
##############################################################
function install_rkhunter() {
{
start_spinner 'Installing and Configuring RKHunter...'
echo ""
if [[ ${OS} = centos || ${OS} = red || ${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
}
###################################################
#### Install LMD Redhat/CentOS 7 and 8, Ubuntu ####
###################################################
function install_lmd() {
{
start_spinner 'Installing and Configuring MalDetect...'
echo ""
if [[ ${OS} = centos || ${OS} = red || ${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} = red || ${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
}
##########################
#### 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
}
###############################
#### Oracle EBS PreInstall ####
###############################
function oci_oracle_ebs_setup() {
{
start_spinner 'Configuring Server for Oracle EBS/WebLogic...'
if [ "${SRVTYPE}" != 3 ]; then
if [[ ${OS} = centos || ${OS} = red || ${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
}
########################
#### 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 Only ####
##################
function oci_only() {
{
oci_iptables
}
}
##################
#### AWS Only ####
##################
function aws_only() {
{
aws_iptables
}
}
warn_message