System Hardening: CIS Benchmarks & STIG
Chapter 15: System Hardening: CIS Benchmarks & STIG
Section titled “Chapter 15: System Hardening: CIS Benchmarks & STIG”Learning Objectives
Section titled “Learning Objectives”- Understand what system hardening means and why it’s required
- Know the CIS Benchmarks framework and how to apply it
- Understand STIG and DoD security requirements
- Know how to automate hardening with tools like Lynis, OpenSCAP
- Apply production-grade hardening scripts
Prerequisites
Section titled “Prerequisites”What is this? (Beginner On-Ramp)
Section titled “What is this? (Beginner On-Ramp)”System hardening is the process of locking down a server to reduce its ‘attack surface’. Think of it as securing a house: you lock the doors, close the windows, turn off unnecessary outside lights, and ensure only trusted people have the keys.
15.1 What is System Hardening?
Section titled “15.1 What is System Hardening?”System hardening is the process of reducing a system’s attack surface by eliminating unnecessary services, applying secure configurations, and enforcing security policies.
Hardening Philosophy: Reduce Attack Surface ─────────────────────────────────────────────
Default Server Installation: ┌────────────────────────────────────────────────┐ │ Running services: 47 │ │ Open ports: 23 │ │ Installed packages: 1,247 │ │ SUID binaries: 22 │ │ World-writable files: 134 │ │ Attack Surface: LARGE │ └────────────────────────────────────────────────┘
After Hardening: ┌────────────────────────────────────────────────┐ │ Running services: 8 (only what's needed) │ │ Open ports: 3 (SSH, app, monitoring) │ │ Installed packages: 312 (minimal) │ │ SUID binaries: 4 (essential only) │ │ World-writable files: 2 (/tmp, /var/tmp) │ │ Attack Surface: MINIMAL │ └────────────────────────────────────────────────┘
Principle: If it's not needed, remove it. If it runs, restrict it. If it exists, audit it.15.2 CIS Benchmarks
Section titled “15.2 CIS Benchmarks”CIS (Center for Internet Security) Benchmarks are internationally recognized security configuration guidelines developed by cybersecurity professionals.
CIS Benchmark Levels ─────────────────────
Level 1 (L1): Essential Security - Minimal performance impact - Can be applied to most environments - Quick wins with high impact - Examples: disable unused services, enforce passwords
Level 2 (L2): Advanced Security - May impact functionality - Suitable for high-security environments - Stricter controls - Examples: strict filesystem permissions, SELinux enforcingCIS Ubuntu/RHEL Benchmark: Key Controls
Section titled “CIS Ubuntu/RHEL Benchmark: Key Controls”# ── Section 1: Initial Setup ──────────────────────────────
# 1.1: Filesystem Configuration# Disable unused filesystemscat >> /etc/modprobe.d/blacklist.conf << 'EOF'install cramfs /bin/true # Old filesysteminstall freevxfs /bin/true # Rare filesysteminstall jffs2 /bin/true # Embedded filesysteminstall hfs /bin/true # Apple HFSinstall hfsplus /bin/true # Apple HFS+install squashfs /bin/true # Snap packages (if not used)install udf /bin/true # DVD filesystemEOF
# 1.2: Separate filesystem partitions (prevent one area filling another)# In production, use separate LVM volumes or partitions:# /tmp - separate, noexec, nosuid, nodev# /var - separate (prevents log fills from crashing system)# /var/log - separate (audit logs isolated)# /home - separate
# Mount /tmp with restrictionscat >> /etc/fstab << 'EOF'tmpfs /tmp tmpfs defaults,nodev,nosuid,noexec 0 0EOF
# Or if /tmp is on separate partition:# UUID=... /tmp ext4 defaults,nodev,nosuid,noexec 0 2
# ── Section 2: Services ───────────────────────────────────
# 2.1: Disable unused servicesUNUSED_SERVICES=( "avahi-daemon" # Zeroconf/mDNS - not needed on servers "cups" # Printer service - not needed on servers "nfs-server" # NFS server - only if not an NFS server "rpcbind" # RPC - not needed without NFS "rsync" # Rsync daemon - only if needed "talk" # Chat service - obsolete "telnet" # Telnet - NEVER on production (cleartext!) "xinetd" # Super-server - obsolete)
for service in "${UNUSED_SERVICES[@]}"; do if systemctl is-active "$service" &>/dev/null; then systemctl stop "$service" systemctl mask "$service" echo "Masked: $service" fidone
# ── Section 3: Network Configuration ─────────────────────
# 3.1: Disable unused network protocolscat >> /etc/modprobe.d/blacklist.conf << 'EOF'install dccp /bin/true # DCCP protocolinstall sctp /bin/true # SCTP protocolinstall rds /bin/true # RDS protocolinstall tipc /bin/true # TIPC protocolEOF
# 3.2: IP forwarding (disable unless this is a router)echo "net.ipv4.ip_forward = 0" >> /etc/sysctl.d/99-cis.conf
# 3.3: ICMP and redirect settingscat >> /etc/sysctl.d/99-cis.conf << 'EOF'net.ipv4.conf.all.send_redirects = 0net.ipv4.conf.default.send_redirects = 0net.ipv4.conf.all.accept_source_route = 0net.ipv4.conf.default.accept_source_route = 0net.ipv4.conf.all.accept_redirects = 0net.ipv4.conf.default.accept_redirects = 0net.ipv4.conf.all.secure_redirects = 0net.ipv4.conf.default.secure_redirects = 0net.ipv4.conf.all.log_martians = 1net.ipv4.conf.default.log_martians = 1net.ipv4.icmp_echo_ignore_broadcasts = 1net.ipv4.icmp_ignore_bogus_error_responses = 1net.ipv4.conf.all.rp_filter = 1net.ipv4.conf.default.rp_filter = 1net.ipv4.tcp_syncookies = 1net.ipv6.conf.all.accept_ra = 0net.ipv6.conf.default.accept_ra = 0net.ipv6.conf.all.accept_redirects = 0net.ipv6.conf.default.accept_redirects = 0EOF
sysctl -p /etc/sysctl.d/99-cis.conf
# ── Section 4: Logging and Auditing ──────────────────────
# 4.1: Configure auditd (see Chapter 19 for deep dive)systemctl enable --now auditd
# 4.2: Configure rsyslogcat >> /etc/rsyslog.conf << 'EOF'# Send auth logs to separate fileauth,authpriv.* /var/log/auth.log# Send all logs to secure remote server*.* @@siem.example.com:514EOF
# ── Section 5: Access, Authentication & Authorization ────
# 5.1: Configure sudo# Restrict sudo to wheel group onlyecho "%wheel ALL=(ALL) ALL" > /etc/sudoers.d/99-wheelecho "Defaults requiretty" >> /etc/sudoers.d/99-wheelecho "Defaults logfile=/var/log/sudolog" >> /etc/sudoers.d/99-wheel
# 5.2: SSH configuration (see Chapter 20 for full SSH hardening)
# 5.3: Password policies (see Chapter 22)
# ── Section 6: System Maintenance ───────────────────────
# 6.1: Verify permissions on critical fileschmod 644 /etc/passwdchmod 000 /etc/shadow # Only root should ever accesschmod 644 /etc/groupchmod 700 /rootchmod 700 /root/.sshchmod 600 /root/.ssh/authorized_keys 2>/dev/null || true
# 6.2: Find unowned files (potential leftovers from deleted users)find / -xdev \( -nouser -o -nogroup \) 2>/dev/null | head -2015.3 STIG (Security Technical Implementation Guides)
Section titled “15.3 STIG (Security Technical Implementation Guides)”STIG is the DoD (Department of Defense) security standard, more stringent than CIS.
CIS vs STIG Comparison ───────────────────────────────────────────────────────── Feature CIS Benchmark STIG ───────────────────────────────────────────────────────── Publisher Center for Internet DISA (DoD) Security Audience All organizations Government/DoD contractors Strictness Level 1 (moderate) Very strict Level 2 (strict) Focus Best practices Compliance requirement Format PDF + XCCDF XCCDF + OVAL Tool CIS-CAT, Lynis OpenSCAP, STIG Viewer ─────────────────────────────────────────────────────────STIG Key Requirements
Section titled “STIG Key Requirements”# STIG V-238200: OS must use DoD PKI for authentication# Implementation: Configure PAM for smart card auth
# STIG V-238201: Password must meet complexity# /etc/security/pwquality.confcat >> /etc/security/pwquality.conf << 'EOF'minlen = 15dcredit = -1ucredit = -1ocredit = -1lcredit = -1maxrepeat = 3dictcheck = 1EOF
# STIG V-238210: SSH must use FIPS-compliant algorithms# /etc/ssh/sshd_config# See Chapter 20 for full SSH STIG hardening
# STIG V-238217: All audit records must contain user info# Configure auditd:echo "-a always,exit -F arch=b64 -S execve" >> /etc/audit/rules.d/audit.rules
# STIG V-238314: OS must disable CTRL-ALT-DELETEsystemctl mask ctrl-alt-del.target15.4 Automated Hardening Tools
Section titled “15.4 Automated Hardening Tools”Lynis: Security Auditing
Section titled “Lynis: Security Auditing”# Install Lynisapt-get install lynis # Debian/Ubuntu# or download from cisofy.com
# Run security auditlynis audit system
# Output: hardening score + recommendations# Hardening index: 68 [############# ]
# Check specific categorieslynis audit system --tests-from-group authenticationlynis audit system --tests-from-group malware
# Generate reportlynis audit system --quiet --report-file /tmp/lynis-report.dat
# Continuous monitoring# Run lynis via cron weekly, compare report for changesOpenSCAP: SCAP Compliance Scanning
Section titled “OpenSCAP: SCAP Compliance Scanning”# Install OpenSCAPapt-get install openscap-scanner ssg-debian # Debian/Ubuntuyum install openscap-scanner scap-security-guide # RHEL
# Available profilesoscap info /usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml | grep "Profile"
# Run CIS benchmark scanoscap xccdf eval \ --profile xccdf_org.ssgproject.content_profile_cis_level1_server \ --results /tmp/scan-results.xml \ --report /tmp/scan-report.html \ /usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml
# View HTML report# Open /tmp/scan-report.html in browser
# Remediation (apply fixes automatically)oscap xccdf eval \ --profile xccdf_org.ssgproject.content_profile_cis_level1_server \ --remediate \ /usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xmlAnsible-based Hardening (Production Recommended)
Section titled “Ansible-based Hardening (Production Recommended)”---- name: CIS Level 1 Server Hardening hosts: all become: yes roles: - { role: devsec.os_hardening } - { role: devsec.ssh_hardening }
# Install roles:# ansible-galaxy install devsec.os_hardening devsec.ssh_hardening
# Run:# ansible-playbook -i inventory hardening-playbook.yml --check # Dry run# ansible-playbook -i inventory hardening-playbook.yml # Apply15.5 Hardening Checklist for Production Servers
Section titled “15.5 Hardening Checklist for Production Servers” ✅ Production Server Hardening Checklist ─────────────────────────────────────────
OS Configuration: □ Minimal OS installation (no X11, no games, no compilers) □ Remove unused packages: apt autoremove / yum autoremove □ Separate /tmp, /var, /var/log partitions □ /tmp mounted with noexec,nosuid,nodev □ Disable unused filesystems □ Disable unused network protocols (DCCP, SCTP, etc.)
User Management: □ No empty passwords (cat /etc/shadow | awk -F: '$2 == "" {print}') □ No duplicate UIDs/GIDs □ Root login disabled (PermitRootLogin no) □ Minimum password length: 12+ □ Password expiry configured □ Lock inactive accounts after 30 days
SSH: □ Protocol 2 only □ Key-based auth only (no passwords) □ Allowed users/groups restricted □ Port changed (or firewall restricts to known IPs) □ AllowTcpForwarding disabled (unless needed)
Services: □ Only required services running □ All services running as non-root □ firewalld/iptables configured (default deny)
Logging: □ auditd running and configured □ All auth events logged □ Logs forwarded to central SIEM □ Log rotation configured
Updates: □ Automatic security updates enabled □ Process for emergency patching documented15.6 Production Automation Script
Section titled “15.6 Production Automation Script”#!/bin/bash# cis-harden.sh — CIS Level 1 Hardening Script# Test in staging first! Some settings may break applications.
set -euo pipefailLOG=/var/log/hardening-$(date +%Y%m%d).log
log() { echo "[$(date)] $*" | tee -a "$LOG"; }
log "=== Starting CIS Level 1 Hardening ==="
# --- Remove unused packages ---log "Removing unused packages..."apt-get purge -y telnet rsh-client rsh-redone-client talk xserver-xorg* \ 2>/dev/null || true
# --- Disable unused filesystems ---log "Disabling unused filesystems..."for fs in cramfs freevxfs jffs2 hfs hfsplus udf; do echo "install $fs /bin/true" >> /etc/modprobe.d/blacklist.confdone
# --- Configure /tmp ---log "Configuring /tmp..."if ! grep -q "tmpfs /tmp" /etc/fstab; then echo "tmpfs /tmp tmpfs defaults,rw,nosuid,nodev,noexec,relatime 0 0" >> /etc/fstab mount -o remount /tmp 2>/dev/null || truefi
# --- Disable unused services ---log "Disabling unused services..."for svc in avahi-daemon cups isc-dhcp-server isc-dhcp-server6 slapd \ nfs-kernel-server rpcbind bind9 vsftpd apache2 dovecot exim4; do systemctl disable --now "$svc" 2>/dev/null || truedone
# --- Network hardening ---log "Applying network hardening..."cat > /etc/sysctl.d/99-cis.conf << 'SYSCTL'net.ipv4.conf.all.send_redirects = 0net.ipv4.conf.default.send_redirects = 0net.ipv4.conf.all.accept_source_route = 0net.ipv4.conf.default.accept_source_route = 0net.ipv4.conf.all.accept_redirects = 0net.ipv4.conf.default.accept_redirects = 0net.ipv4.conf.all.log_martians = 1net.ipv4.icmp_echo_ignore_broadcasts = 1net.ipv4.conf.all.rp_filter = 1net.ipv4.tcp_syncookies = 1kernel.randomize_va_space = 2SYSCTLsysctl -p /etc/sysctl.d/99-cis.conf
# --- File permissions ---log "Setting critical file permissions..."chmod 644 /etc/passwd /etc/groupchmod 640 /etc/shadow /etc/gshadowchmod 700 /rootchown root:root /etc/passwd /etc/shadow /etc/group /etc/gshadow
# --- SUID audit ---log "Auditing SUID files..."find / -xdev -perm -4000 -type f 2>/dev/null >> "$LOG"
log "=== Hardening Complete. Review $LOG ==="log "=== Run 'lynis audit system' to verify score ==="15.7 Interview Questions
Section titled “15.7 Interview Questions”Q1: What is the difference between CIS Benchmark Level 1 and Level 2?
Answer: CIS Benchmark Level 1 is the “essential security” tier — controls that have minimal performance or functionality impact and are recommended for all environments. These are the quick wins: disabling unused services, configuring password policies, setting appropriate file permissions, enabling firewall. Level 2 is “advanced security” — more restrictive controls that may impact functionality or require significant configuration, suitable for high-security environments. Examples: SELinux in Enforcing mode, strict auditing of all file system events, stricter kernel parameters. Level 2 often requires more customization per environment.
Q2: What is STIG and who must comply with it?
Answer: STIG (Security Technical Implementation Guide) is published by DISA (Defense Information Systems Agency) and represents the DoD’s security hardening requirements. It’s mandatory for: US federal government IT systems, DoD contractors, systems handling classified information, and many state/local government systems. STIGs are stricter than CIS Benchmarks — they specify exact configuration values, have specific vulnerability IDs (V-numbers), and often require formal documentation of compliance or exceptions. STIGs are evaluated using tools like OpenSCAP with SCAP content, and compliance is often audited by government auditors.
Q3: Walk me through how you would harden a new production web server.
Answer: (1) Minimal installation: Start with a server-only OS profile, no GUI, no compilers. (2) Update: Apply all patches immediately. (3) Remove unused: Purge telnet, FTP, X11, unused services. (4) Filesystem: Separate /tmp, /var with noexec/nosuid mounts. (5) Network: Configure firewall (deny all in, allow only needed ports), apply sysctl hardening (syncookies, rp_filter, disable redirects). (6) SSH: Key-only auth, disable root login, restrict to known IPs. (7) User management: Strong password policy, no shared accounts. (8) Services: Disable unnecessary services, run all services as non-root. (9) Audit: Enable auditd, configure logging to SIEM. (10) Verify: Run Lynis or OpenSCAP to confirm compliance. (11) Automate: Apply the same hardening via Ansible to all servers in the fleet.
15.8 Summary
Section titled “15.8 Summary”| Framework | Organization | Use Case |
|---|---|---|
| CIS Benchmark | CIS | General enterprise hardening |
| STIG | DISA/DoD | Government and defense |
| PCI-DSS | PCI Council | Payment card environments |
| HIPAA Security | HHS | Healthcare systems |
| Tool | Purpose |
|---|---|
| Lynis | Linux security audit |
| OpenSCAP | SCAP/CIS/STIG compliance scanning |
| CIS-CAT | CIS Benchmark scanner |
| Ansible + devsec | Automated hardening |
Next Chapter: Chapter 16: SELinux: Architecture, Policies & Troubleshooting
Section titled “Next Chapter: Chapter 16: SELinux: Architecture, Policies & Troubleshooting”Prerequisites
Section titled “Prerequisites”Chapter 14 (Security Fundamentals).
Advantages & Disadvantages
Section titled “Advantages & Disadvantages”Advantages: Drastically reduces attack surface, stops automated worms and script kiddies. Disadvantages: Time-consuming, over-hardening can break legitimate applications.
Common Mistakes
Section titled “Common Mistakes”- Applying STIGs blindly without testing — can break production applications.
- Leaving default passwords or default services enabled.
- Forgetting to harden the bootloader (GRUB password).
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Diagnosis | Fix |
|---|---|---|---|
| Application breaks after hardening | Too strict permissions or disabled features | Review hardening audit logs | Revert specific controls or add exceptions |
Hands-on Lab
Section titled “Hands-on Lab”Objective: Perform basic hardening checks.
# 1. Check for empty passwordsawk -F: '($2 == "") {print}' /etc/shadow
# 2. Check root login via SSHgrep "^PermitRootLogin" /etc/ssh/sshd_config
# 3. List enabled servicessystemctl list-unit-files --state=enabledExercises
Section titled “Exercises”- Run a basic CIS benchmark script (like Lynis) on a test system and review the score.
- Disable unused network protocols (e.g., DCCP, SCTP, RDS) via modprobe blacklisting.
Revision Notes
Section titled “Revision Notes”- Hardening is about reducing the attack surface.
- CIS Benchmarks and STIGs provide standardized checklists for securing systems.
- Disable unused services, enforce strong passwords, and restrict network access.
Further Reading
Section titled “Further Reading”- CIS Benchmarks: https://www.cisecurity.org/cis-benchmarks/
- OpenSCAP: https://www.open-scap.org/
Related Chapters
Section titled “Related Chapters”- Chapter 45 — Compliance Frameworks
Last Updated: July 2026