CIS Benchmarks Hardening on Linux

The CIS (Center for Internet Security) Benchmarks are industry-standard security configuration guides that provide prescriptive guidance for hardening Linux systems. This guide covers applying CIS Benchmarks to Ubuntu and CentOS/Rocky Linux, using automated assessment tools, remediating findings, and maintaining continuous compliance.

Prerequisites

  • Ubuntu 20.04/22.04 or CentOS/Rocky Linux 8+
  • Root or sudo access
  • A test/staging environment (apply hardening there first)
  • Review your workload requirements before hardening (some controls affect functionality)

CIS Benchmark Levels Explained

LevelDescription
Level 1Baseline security; minimal performance/functionality impact
Level 2Defense in depth; may impact some functionality

Start with Level 1 controls, then evaluate Level 2 against your operational requirements. Always test in staging first.

Automated Assessment with Lynis

Lynis is an open-source security auditing tool aligned with CIS Benchmarks:

# Install Lynis
sudo apt install -y lynis    # Ubuntu/Debian
sudo dnf install -y lynis    # CentOS/Rocky Linux

# Run a full security audit
sudo lynis audit system

# Output summary:
# Lynis security scan details:
#   Hardening index : 67 [##########          ]
#   Tests performed : 261
#   Plugins enabled : 0
#
# Components:
# - Firewall               [V]
# - Malware scanner        [X]
# - File integrity tool    [X]
# ...

# Save report to a file
sudo lynis audit system --report-file /var/log/lynis-report.dat
sudo lynis audit system 2>&1 | tee /var/log/lynis-audit.log

# Show only warnings and suggestions
sudo lynis audit system | grep -E "^\[WARNING\]|^\[SUGGESTION\]"

# Run specific test group
sudo lynis audit system --tests-from-group authentication
sudo lynis audit system --tests-from-group networking
sudo lynis audit system --tests-from-group filesystems

OpenSCAP Automated Hardening

OpenSCAP can both assess and automatically remediate CIS Benchmark findings:

# Ubuntu
sudo apt install -y openscap-scanner scap-security-guide

# CentOS/Rocky Linux
sudo dnf install -y openscap-scanner scap-security-guide

# List available profiles
oscap info /usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml | grep "Id:"

# Available profiles include:
# xccdf_org.ssgproject.content_profile_cis_level1_server
# xccdf_org.ssgproject.content_profile_cis_level2_server

# Run CIS Level 1 audit (assessment only)
sudo oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_cis_level1_server \
  --results /var/log/scap-results.xml \
  --report /var/log/scap-report.html \
  /usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml

# View the HTML report
# Open /var/log/scap-report.html in a browser

# Generate an auto-remediation script (review before running!)
sudo oscap xccdf generate fix \
  --profile xccdf_org.ssgproject.content_profile_cis_level1_server \
  --fix-type bash \
  /usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml \
  > /tmp/cis-remediation.sh

# Review the script carefully:
less /tmp/cis-remediation.sh

# Apply remediation (after review and testing):
sudo bash /tmp/cis-remediation.sh

Key CIS Controls and Remediation

File System Configuration

# CIS 1.1.1 - Disable unused filesystems
sudo tee /etc/modprobe.d/cis-disable-filesystems.conf > /dev/null <<'EOF'
install cramfs /bin/true
install freevxfs /bin/true
install jffs2 /bin/true
install hfs /bin/true
install hfsplus /bin/true
install squashfs /bin/true
install udf /bin/true
EOF

# CIS 1.1.2-1.1.5 - Secure /tmp
sudo systemctl enable tmp.mount
sudo systemctl start tmp.mount

# Add noexec, nosuid, nodev to /tmp mount options
# Edit /etc/fstab:
echo "tmpfs /tmp tmpfs defaults,rw,nosuid,nodev,noexec,relatime 0 0" | \
  sudo tee -a /etc/fstab

# Apply without reboot
sudo mount -o remount /tmp

Package and Software Management

# CIS 1.2 - Configure package manager
# Ensure GPG keys are configured (Ubuntu)
sudo apt-key list

# Remove unnecessary packages
sudo apt remove -y telnet rsh-server ypserv tftp-server xinetd \
  avahi-daemon cups isc-dhcp-server ldap-server nfs-kernel-server \
  vsftpd samba squid snmpd 2>/dev/null || true

# CIS 1.6 - Disable CUPS (printing)
sudo systemctl disable --now cups 2>/dev/null || true

Kernel and Sysctl Hardening

# Apply CIS-recommended kernel parameters
sudo tee /etc/sysctl.d/99-cis-hardening.conf > /dev/null <<'EOF'
# CIS 3.1 - Network parameters (host only)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

# CIS 3.2 - Network parameters (host and router)
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# CIS 3.3 - Disable source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

# CIS 3.4 - Disable ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0

# CIS 3.5 - Log suspicious packets
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1

# CIS 3.6 - Ignore ping broadcasts
net.ipv4.icmp_echo_ignore_broadcasts = 1

# CIS 3.7 - Ignore bogus ICMP responses
net.ipv4.icmp_ignore_bogus_error_responses = 1

# CIS 3.8 - Enable reverse path filtering
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# CIS 3.9 - Enable TCP SYN cookies
net.ipv4.tcp_syncookies = 1

# CIS 3.10 - Disable IPv6 if not needed
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

# Kernel hardening
kernel.randomize_va_space = 2    # ASLR: full randomization
kernel.dmesg_restrict = 1        # Restrict dmesg to root
kernel.kptr_restrict = 2         # Hide kernel pointers
kernel.sysrq = 0                 # Disable magic SysRq
fs.suid_dumpable = 0             # Disable SUID core dumps
EOF

# Apply immediately
sudo sysctl -p /etc/sysctl.d/99-cis-hardening.conf

User and Authentication Hardening

# CIS 5.1 - Configure cron access
sudo rm -f /etc/cron.deny /etc/at.deny
echo "root" | sudo tee /etc/cron.allow
echo "root" | sudo tee /etc/at.allow
sudo chmod 600 /etc/cron.allow /etc/at.allow

# CIS 5.2 - SSH Server configuration
sudo tee /etc/ssh/sshd_config.d/99-cis-hardening.conf > /dev/null <<'EOF'
# CIS SSH hardening settings
Protocol 2
LogLevel VERBOSE
X11Forwarding no
MaxAuthTries 4
IgnoreRhosts yes
HostbasedAuthentication no
PermitRootLogin no
PermitEmptyPasswords no
PermitUserEnvironment no
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,[email protected],[email protected]
MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256
KexAlgorithms curve25519-sha256,[email protected],ecdh-sha2-nistp256
ClientAliveInterval 300
ClientAliveCountMax 3
LoginGraceTime 60
Banner /etc/issue.net
AllowTcpForwarding no
MaxStartups 10:30:60
MaxSessions 10
EOF

# Test SSH config before applying
sudo sshd -t && sudo systemctl restart sshd

# CIS 5.3 - Password policies
sudo tee -a /etc/security/pwquality.conf > /dev/null <<'EOF'
minlen = 14
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
EOF

# CIS 5.4 - Password aging
sudo sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS   365/' /etc/login.defs
sudo sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS   1/' /etc/login.defs
sudo sed -i 's/^PASS_WARN_AGE.*/PASS_WARN_AGE   7/' /etc/login.defs

# CIS 5.6 - Restrict su command
echo "auth required pam_wheel.so use_uid" | \
  sudo tee -a /etc/pam.d/su
sudo groupadd -f wheel

Filesystem and Permission Hardening

# CIS 6.1 - Verify system file permissions
# Check for world-writable files
sudo find / -xdev -type f -perm -0002 2>/dev/null | \
  grep -v -E "/proc|/sys|/run|/dev" | head -20

# Check for SUID/SGID files (review carefully — some are legitimate)
sudo find / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null

# Check for unowned files
sudo find / -xdev \( -nouser -o -nogroup \) -type f 2>/dev/null | head -20

# Fix permissions on sensitive files
sudo chmod 600 /etc/shadow
sudo chmod 644 /etc/passwd
sudo chmod 644 /etc/group
sudo chown root:root /etc/shadow /etc/passwd /etc/group
sudo chmod 0700 /root
sudo chmod 0644 /etc/crontab
sudo chmod 0700 /etc/cron.d

Continuous Compliance Monitoring

# Schedule regular CIS compliance scans
sudo tee /usr/local/bin/cis-audit.sh > /dev/null <<'EOF'
#!/bin/bash
DATE=$(date +%Y-%m-%d)
REPORT_DIR="/var/log/cis-reports"
mkdir -p "$REPORT_DIR"

# Run Lynis audit
sudo lynis audit system \
  --report-file "$REPORT_DIR/lynis-report-$DATE.dat" \
  2>&1 | tee "$REPORT_DIR/lynis-audit-$DATE.log"

# Extract hardening index
SCORE=$(grep "hardening_index" "$REPORT_DIR/lynis-report-$DATE.dat" | cut -d= -f2)
echo "CIS Hardening Score on $DATE: $SCORE" | \
  mail -s "Monthly CIS Audit: $(hostname) - Score $SCORE" [email protected]
EOF

sudo chmod +x /usr/local/bin/cis-audit.sh

# Schedule monthly
echo "0 1 1 * * root /usr/local/bin/cis-audit.sh" | \
  sudo tee /etc/cron.d/cis-audit

Common Issues

SSH hardened ciphers break older clients:

# Check which ciphers the client supports
ssh -Q cipher | sort

# If needed, add a less-strict cipher (after CIS exception process):
# Add to sshd_config.d/99-cis-hardening.conf:
# Ciphers aes128-ctr,aes256-ctr,[email protected],[email protected],aes256-cbc

Applications fail after sysctl changes:

# If ip_forward=0 breaks containerization:
# Exception: Docker/Kubernetes requires ip_forward=1
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-docker-override.conf
sudo sysctl -p /etc/sysctl.d/99-docker-override.conf

Password policy breaks service accounts:

# Exclude service accounts from password aging
sudo chage -I -1 -M 99999 serviceaccount   # Never expire
sudo chage -l serviceaccount  # Verify

# Document the exception in your compliance records

Conclusion

CIS Benchmark hardening systematically reduces the attack surface of Linux servers by addressing insecure defaults, unnecessary services, weak authentication, and unprotected kernel parameters. Start with Level 1 controls and measure your Lynis hardening score before and after each change. Maintain exceptions documentation for controls that conflict with your workload requirements, and schedule regular automated scans to detect configuration drift and new vulnerabilities.