Why Automate Hardening?

Manual server hardening is error-prone and doesn't scale. When you're managing 200+ servers, you need consistency. This Ansible playbook implements CIS Benchmark Level 1 controls automatically.

Project Structure

rhel-hardening/
├── playbook.yml
├── inventory/
│ └── hosts.ini
└── roles/
└── hardening/
├── tasks/
│ ├── main.yml
│ ├── ssh.yml
│ ├── kernel.yml
│ ├── filesystem.yml
│ └── audit.yml
├── handlers/
│ └── main.yml
└── defaults/
└── main.yml

SSH Hardening Tasks

---
# roles/hardening/tasks/ssh.yml
- name: Configure SSH hardening
lineinfile:
path: /etc/ssh/sshd_config
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: present
loop:
- { regexp: '^PermitRootLogin', line: 'PermitRootLogin no' }
- { regexp: '^PasswordAuthentication', line: 'PasswordAuthentication no' }
- { regexp: '^X11Forwarding', line: 'X11Forwarding no' }
- { regexp: '^MaxAuthTries', line: 'MaxAuthTries 3' }
- { regexp: '^LoginGraceTime', line: 'LoginGraceTime 60' }
- { regexp: '^AllowTcpForwarding', line: 'AllowTcpForwarding no' }
- { regexp: '^ClientAliveInterval', line: 'ClientAliveInterval 300' }
- { regexp: '^ClientAliveCountMax', line: 'ClientAliveCountMax 0' }
notify: Restart SSHD

Kernel Hardening

- name: Apply kernel security parameters
sysctl:
name: "{{ item.key }}"
value: "{{ item.value }}"
state: present
reload: yes
loop:
# Disable IP forwarding (unless router)
- { key: net.ipv4.ip_forward, value: '0' }
# Protect against SYN flood attacks
- { key: net.ipv4.tcp_syncookies, value: '1' }
# Ignore ICMP broadcast requests
- { key: net.ipv4.icmp_echo_ignore_broadcasts, value: '1' }
# Disable source routing
- { key: net.ipv4.conf.all.accept_source_route, value: '0' }
# Enable reverse path filtering
- { key: net.ipv4.conf.all.rp_filter, value: '1' }
# Disable IPv6 if not needed
- { key: net.ipv6.conf.all.disable_ipv6, value: '1' }

Running the Playbook

# Dry run first
ansible-playbook -i inventory/hosts.ini playbook.yml --check --diff

# Apply to a test server first
ansible-playbook -i inventory/hosts.ini playbook.yml --limit test-server-01

# Apply to all servers
ansible-playbook -i inventory/hosts.ini playbook.yml

Compliance Reporting

# Generate compliance report with OpenSCAP
oscap xccdf eval
--profile xccdf_org.ssgproject.content_profile_cis
--results /tmp/scan-results.xml
--report /tmp/scan-report.html
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

This playbook is available on my GitHub. Star it if it helps you!