Pages

CIS RHEL 9 Level 1 Auto-Remediation Script

Overview:
This script performs automated security hardening on a Red Hat Enterprise Linux 9 system based on CIS Level 1 benchmark recommendations.

The goal is to enforce basic security configurations and reduce the system attack surface.

The script focuses on CIS Benchmark Sections 1 through 7 and automatically remediates common security issues such as insecure services, weak system configurations, and improper file permissions.
The script also creates backups before modifying critical configuration files to reduce the risk of system issues.

Key Features
• Root execution validation
• Automatic backup of configuration files before changes
• Automatic remediation of insecure settings
• Persistent kernel parameter configuration
• Service hardening and firewall configuration
• SSH security configuration
• Audit logging configuration
• File permission validation
• Color-coded output for easier review

Log and Backup Locations
Log File
/var/log/cis_rhel9_auto_report.log
Backup Directory
/root/cis_backup_
The backup directory stores copies of configuration files modified by the script.

Script Execution
The script must be executed with root privileges.
Script:
---------------------------------------------------------------------------------------------------------------------
#!/bin/bash
# =====================================================
# CIS RHEL 9 Level 1 Auto Remediation 
# Covers CIS Sections 1–7
# Includes safety checks, backups, and persistent config
# =====================================================

# -------------------------
# Root Check
# -------------------------
if [ "$EUID" -ne 0 ]; then
 echo "Run this script as root"
 exit 1
fi

# -------------------------
# Colors
# -------------------------
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

# -------------------------
# Logging
# -------------------------
REPORT="/var/log/cis_rhel9_auto_report.log"
BACKUP="/root/cis_backup_$(date +%F_%H-%M)"

mkdir -p $BACKUP
> $REPORT

PASS=0
FAIL=0
REMEDIATED=0
MANUAL=0

log_pass() { echo -e "${GREEN}[PASS]${NC} $1" | tee -a $REPORT; ((PASS++)); }
log_fail() { echo -e "${RED}[FAIL]${NC} $1" | tee -a $REPORT; ((FAIL++)); }
log_manual() { echo -e "${YELLOW}[MANUAL]${NC} $1" | tee -a $REPORT; ((MANUAL++)); }
log_remediated() { echo -e "${GREEN}[REMEDIATED]${NC} $1" | tee -a $REPORT; ((REMEDIATED++)); }

backup_file() {
 file=$1
 if [ -f "$file" ]; then
   cp "$file" "$BACKUP"
 fi
}

# -------------------------
# File Permission Check
# -------------------------
check_file_perm() {

file=$1
perm=$2

if [ -f "$file" ]; then

actual=$(stat -c "%a" "$file")

if [ "$actual" != "$perm" ]; then
 chmod "$perm" "$file" && log_remediated "Fixed $file permissions to $perm" || log_fail "Failed to fix $file"
else
 log_pass "$file permissions correct"
fi

else
 log_fail "$file not found"
fi

}

# -------------------------
# Service Control
# -------------------------

disable_service() {

svc=$1

if systemctl list-unit-files | grep -q "^$svc"; then

systemctl disable --now $svc &>/dev/null \
&& log_remediated "$svc disabled" \
|| log_fail "Failed disabling $svc"

else
 log_pass "$svc not installed"
fi

}

enable_service() {

svc=$1

systemctl enable --now $svc &>/dev/null \
&& log_remediated "$svc enabled" \
|| log_fail "Failed enabling $svc"

}

# -------------------------
# SSH Configuration
# -------------------------

set_ssh_config() {

param=$1
value=$2
file="/etc/ssh/sshd_config"

backup_file $file

if grep -q "^$param" $file
then
 sed -i "s/^$param.*/$param $value/" $file
else
 echo "$param $value" >> $file
fi

log_remediated "SSH $param set to $value"

}

# -------------------------
# Sysctl Configuration
# -------------------------

SYSCTL_FILE="/etc/sysctl.d/99-cis.conf"
touch $SYSCTL_FILE

set_sysctl() {

key=$1
value=$2

if grep -q "$key" $SYSCTL_FILE
then
 sed -i "s/^$key.*/$key = $value/" $SYSCTL_FILE
else
 echo "$key = $value" >> $SYSCTL_FILE
fi

sysctl -w $key=$value >/dev/null

log_remediated "Sysctl $key set to $value"

}

# -------------------------
# SECTION 1
# Initial Setup
# -------------------------

echo "==== SECTION 1 INITIAL SETUP ====" | tee -a $REPORT

log_manual "Verify OS version and updates manually"

# -------------------------
# SECTION 2
# Services
# -------------------------

echo "==== SECTION 2 SERVICES ====" | tee -a $REPORT

services=(
telnet
tftp
avahi-daemon
cups
rpcbind
)

for s in "${services[@]}"
do
 disable_service $s
done

# -------------------------
# SECTION 3
# Network Security
# -------------------------

echo "==== SECTION 3 NETWORK ====" | tee -a $REPORT

set_sysctl net.ipv4.ip_forward 0
set_sysctl net.ipv4.conf.all.send_redirects 0
set_sysctl net.ipv4.conf.default.send_redirects 0
set_sysctl net.ipv4.icmp_echo_ignore_broadcasts 1
set_sysctl net.ipv4.icmp_ignore_bogus_error_responses 1
set_sysctl net.ipv4.conf.all.accept_redirects 0
set_sysctl net.ipv4.conf.default.accept_redirects 0
set_sysctl net.ipv4.tcp_syncookies 1

sysctl --system >/dev/null

# -------------------------
# SECTION 4
# Firewall
# -------------------------

echo "==== SECTION 4 FIREWALL ====" | tee -a $REPORT

enable_service firewalld

firewall-cmd --reload &>/dev/null \
&& log_remediated "Firewall reloaded" \
|| log_fail "Firewall reload failed"

# -------------------------
# SECTION 5
# Access Control
# -------------------------

echo "==== SECTION 5 ACCESS CONTROL ====" | tee -a $REPORT

backup_file /etc/ssh/sshd_config

if [ -f /root/.ssh/authorized_keys ]
then
 set_ssh_config PermitRootLogin no
 set_ssh_config PasswordAuthentication no
else
 log_manual "SSH keys not detected. PasswordAuthentication unchanged."
fi

check_file_perm /etc/ssh/sshd_config 600

systemctl restart sshd || log_fail "SSH restart failed"

# -------------------------
# Sudo Hardening
# -------------------------

backup_file /etc/sudoers

sed -i 's/^%wheel.*NOPASSWD/%wheel ALL=(ALL) ALL/' /etc/sudoers

visudo -c >/dev/null \
&& log_remediated "Sudoers updated and validated" \
|| log_fail "Sudoers syntax error"

# -------------------------
# SECTION 6
# Audit Logging
# -------------------------

echo "==== SECTION 6 AUDIT ====" | tee -a $REPORT

enable_service auditd

RULE_FILE="/etc/audit/rules.d/99-cis.rules"

backup_file $RULE_FILE

cat <<EOF > $RULE_FILE
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k scope
-w /var/log/secure -p wa -k logins
EOF

augenrules --load && log_remediated "Audit rules loaded"

# -------------------------
# SECTION 7
# File Permissions
# -------------------------

echo "==== SECTION 7 FILE SECURITY ====" | tee -a $REPORT

check_file_perm /etc/passwd 644
check_file_perm /etc/shadow 600
check_file_perm /etc/group 644
check_file_perm /etc/gshadow 600

if find / -xdev -type f -perm -0002 -print -quit | grep .
then
 log_fail "World writable files detected"
else
 log_pass "No world writable files"
fi

log_manual "Review SUID files manually"

# -------------------------
# SUMMARY
# -------------------------

echo
echo "===== CIS REMEDIATION COMPLETE =====" | tee -a $REPORT
echo "PASS: $PASS" | tee -a $REPORT
echo "FAIL: $FAIL" | tee -a $REPORT
echo "REMEDIATED: $REMEDIATED" | tee -a $REPORT
echo "MANUAL: $MANUAL" | tee -a $REPORT

echo
echo "Backup location: $BACKUP"
echo "Report: $REPORT"
---------------------------------------------------------------------------------------------------------------------
Example:
sudo ./cis_rhel9_hardening.sh
During execution, the script prints status messages and writes results to the log file.

Status types include:
PASS – configuration already compliant
FAIL – configuration check failed
REMEDIATED – configuration automatically corrected
MANUAL – manual verification required

The script runs sequential checks and remediation steps across seven CIS benchmark areas.

Section Details:

Section 1 – Initial Setup
This section performs basic verification tasks.
Some checks require manual review because they depend on environment-specific configuration.
Example checks include:
• Operating system version verification
• Kernel version verification
• System update status
These checks are flagged for manual review.

Section 2 – Service Hardening
Unnecessary or insecure services are disabled to reduce the system attack surface.
The following services are disabled if installed:
telnet
tftp
avahi-daemon
cups
rpcbind
The script uses systemctl to stop and disable services immediately.

Section 3 – Network Security
Kernel networking parameters are configured to improve system security.
The script writes persistent configuration to:
/etc/sysctl.d/99-cis.conf
The following parameters are configured:
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.tcp_syncookies = 1
After configuration, the script reloads system kernel parameters using:
sysctl --system

Section 4 – Firewall Configuration
The script ensures that the system firewall is enabled and active.
Actions performed:
• Enable firewalld service
• Start firewalld
• Reload firewall configuration
Commands used:
systemctl enable --now firewalld
firewall-cmd --reload

Section 5 – Access Control and SSH Hardening
This section applies multiple access control improvements.
SSH Security
The script modifies the SSH configuration file:
/etc/ssh/sshd_config
Settings enforced:
PermitRootLogin no
PasswordAuthentication no
Before disabling password authentication, the script verifies that SSH key authentication exists for the root account to prevent accidental lockout.
File permissions for sshd_config are also validated and corrected.
After changes, the SSH service is restarted.
Sudo Hardening
The script updates the sudo configuration to ensure users in the wheel group must provide a password when executing privileged commands.
The configuration file modified:
/etc/sudoers
The script validates the configuration using:
visudo -c
This prevents syntax errors that could break sudo access.

Section 6 – Logging and Auditing
The script enables system auditing using auditd.
Actions performed:
• Enable and start auditd service
• Configure audit rules
• Load rules using augenrules
Audit rule file:
/etc/audit/rules.d/99-cis.rules
The following files are monitored for changes:
/etc/passwd
/etc/shadow
/etc/group
/etc/gshadow
/etc/sudoers
/var/log/secure
Monitoring these files helps detect unauthorized modifications to authentication and logging systems.

Section 7 – File Permission Security
Critical system files must have secure permissions.
The script validates and corrects permissions for the following files:
/etc/passwd – 644
/etc/shadow – 600
/etc/group – 644
/etc/gshadow – 600

World Writable File Check:
The script scans the system for world-writable files that may pose a security risk.
Command used:
find / -xdev -type f -perm -0002 -print -quit
If such files are found, the script reports them for review.
SUID/SGID Review
The script flags SUID and SGID files for manual inspection because these files allow elevated privilege execution.
Example review command:
find / -type f ( -perm -4000 -o -perm -2000 )

Script Summary:
At the end of execution, the script displays a summary showing the number of checks in each category.
Example output:
  • PASS – configurations already compliant
  • FAIL – issues that require attention
  • REMEDIATED – issues automatically corrected
  • MANUAL – items that require administrator review
The script also displays the location of:
• the backup directory
• the execution log file

Operational Use Cases
This script can be used for:
• Initial Linux server hardening
• CIS Level 1 compliance preparation
• Security baseline enforcement
• Security audits and compliance verification
• Automated system configuration in provisioning workflows

Limitations:
Not all CIS controls can be safely automated.
Some security configurations depend on application requirements or environment-specific policies.
Administrators should always review the log file and verify system functionality after running the script.

Post-Execution Recommendation:
After running the script, administrators should:
• Review the log file for failures
• Validate SSH access
• Confirm application services are operating normally
• Review world-writable files if reported
• Perform SUID/SGID audit checks

No comments:

Post a Comment