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!