CIS + inital

This commit is contained in:
2026-01-26 21:22:41 -05:00
parent 5b6e1567f9
commit 28db1d2104
65 changed files with 4555 additions and 2 deletions
+42
View File
@@ -0,0 +1,42 @@
---
# AppArmor Configuration (CIS 1.3.x)
- name: Install AppArmor packages (CIS 1.3.1)
ansible.builtin.apt:
name:
- apparmor
- apparmor-utils
state: present
update_cache: yes
- name: Enable AppArmor service (CIS 1.3.2)
ansible.builtin.service:
name: apparmor
state: started
enabled: yes
- name: Check AppArmor status
ansible.builtin.command: aa-status --json
register: apparmor_status
changed_when: false
failed_when: false
- name: Parse AppArmor status
ansible.builtin.set_fact:
apparmor_json: "{{ apparmor_status.stdout | from_json }}"
when: apparmor_status.rc == 0
- name: Set all AppArmor profiles to enforce mode (CIS 1.3.3)
ansible.builtin.command: aa-enforce /etc/apparmor.d/*
register: apparmor_enforce
changed_when: "'Setting' in apparmor_enforce.stdout"
failed_when: false
when: apparmor_enforce_all | default(true)
- name: Display AppArmor status
ansible.builtin.debug:
msg:
- "AppArmor status: {{ apparmor_json.apparmor if apparmor_json is defined else 'unknown' }}"
- "Profiles loaded: {{ apparmor_json.profiles | length if apparmor_json is defined and apparmor_json.profiles is defined else 0 }}"
- "Profiles in enforce mode: {{ apparmor_json.profiles | selectattr('mode', 'equalto', 'enforce') | list | length if apparmor_json is defined and apparmor_json.profiles is defined else 0 }}"
when: apparmor_json is defined
+57
View File
@@ -0,0 +1,57 @@
---
# Auditd Configuration Tasks (CIS 4.1.x)
- name: Ensure auditd is installed (CIS 4.1.1)
ansible.builtin.apt:
name:
- auditd
- audispd-plugins
state: present
- name: Configure auditd max log file size (CIS 4.1.3)
ansible.builtin.lineinfile:
path: /etc/audit/auditd.conf
regexp: '^max_log_file\s*='
line: "max_log_file = {{ auditd_max_log_file }}"
state: present
- name: Configure auditd log retention (CIS 4.1.4)
ansible.builtin.lineinfile:
path: /etc/audit/auditd.conf
regexp: '^max_log_file_action\s*='
line: "max_log_file_action = keep_logs"
state: present
- name: Configure auditd space left action (CIS 4.1.5)
ansible.builtin.lineinfile:
path: /etc/audit/auditd.conf
regexp: '^space_left_action\s*='
line: "space_left_action = email"
state: present
- name: Configure auditd admin space left action
ansible.builtin.lineinfile:
path: /etc/audit/auditd.conf
regexp: '^admin_space_left_action\s*='
line: "admin_space_left_action = halt"
state: present
- name: Deploy CIS-compliant audit rules
ansible.builtin.template:
src: audit.rules.j2
dest: /etc/audit/rules.d/cis.rules
owner: root
group: root
mode: '0640'
notify: restart auditd
- name: Load audit rules
ansible.builtin.command: augenrules --load
changed_when: false
failed_when: false
- name: Ensure auditd is started and enabled (CIS 4.1.2)
ansible.builtin.systemd:
name: auditd
state: started
enabled: yes
@@ -0,0 +1,39 @@
---
# Restrict Core Dumps (CIS 1.5.1)
- name: Disable core dumps via limits.conf
ansible.builtin.lineinfile:
path: /etc/security/limits.conf
line: "* hard core 0"
create: yes
owner: root
group: root
mode: '0644'
- name: Disable core dumps via sysctl (already done in sysctl_cis.yml)
ansible.posix.sysctl:
name: fs.suid_dumpable
value: '0'
state: present
sysctl_set: yes
reload: yes
- name: Disable coredump in systemd
ansible.builtin.lineinfile:
path: /etc/systemd/coredump.conf
regexp: '^Storage='
line: "Storage=none"
create: yes
owner: root
group: root
mode: '0644'
- name: Disable coredump processing
ansible.builtin.lineinfile:
path: /etc/systemd/coredump.conf
regexp: '^ProcessSizeMax='
line: "ProcessSizeMax=0"
create: yes
owner: root
group: root
mode: '0644'
@@ -0,0 +1,49 @@
---
# Disable Uncommon Network Protocols (CIS 3.3.x)
- name: Disable DCCP protocol (CIS 3.3.1)
ansible.builtin.lineinfile:
path: /etc/modprobe.d/cis.conf
line: "install dccp /bin/true"
create: yes
owner: root
group: root
mode: '0644'
- name: Disable SCTP protocol (CIS 3.3.2)
ansible.builtin.lineinfile:
path: /etc/modprobe.d/cis.conf
line: "install sctp /bin/true"
create: yes
owner: root
group: root
mode: '0644'
- name: Disable RDS protocol (CIS 3.3.3)
ansible.builtin.lineinfile:
path: /etc/modprobe.d/cis.conf
line: "install rds /bin/true"
create: yes
owner: root
group: root
mode: '0644'
- name: Disable TIPC protocol (CIS 3.3.4)
ansible.builtin.lineinfile:
path: /etc/modprobe.d/cis.conf
line: "install tipc /bin/true"
create: yes
owner: root
group: root
mode: '0644'
- name: Unload uncommon protocols if loaded
community.general.modprobe:
name: "{{ item }}"
state: absent
loop:
- dccp
- sctp
- rds
- tipc
failed_when: false
+22
View File
@@ -0,0 +1,22 @@
---
# Fail2ban Configuration Tasks
- name: Ensure fail2ban is installed
ansible.builtin.apt:
name: fail2ban
state: present
- name: Configure fail2ban
ansible.builtin.template:
src: fail2ban.local.j2
dest: /etc/fail2ban/jail.local
owner: root
group: root
mode: '0644'
notify: restart fail2ban
- name: Ensure fail2ban is started and enabled
ansible.builtin.systemd:
name: fail2ban
state: started
enabled: yes
+121
View File
@@ -0,0 +1,121 @@
---
# System Hardening Role - Main Tasks
- name: Set timezone
community.general.timezone:
name: "{{ system_timezone }}"
when: system_timezone is defined and system_timezone != ""
- name: Set hostname
ansible.builtin.hostname:
name: "{{ system_hostname }}"
when: system_hostname is defined and system_hostname != ""
- name: Update apt cache
ansible.builtin.apt:
update_cache: yes
cache_valid_time: 3600
- name: Upgrade all packages
ansible.builtin.apt:
upgrade: dist
autoremove: yes
autoclean: yes
- name: Install security packages
ansible.builtin.apt:
name: "{{ hardening_install_packages }}"
state: present
- name: Remove insecure packages
ansible.builtin.apt:
name: "{{ hardening_remove_packages }}"
state: absent
purge: yes
- name: Configure SSH hardening
ansible.builtin.include_tasks: ssh.yml
- name: Configure sysctl parameters (basic)
ansible.builtin.include_tasks: sysctl.yml
- name: Configure CIS-compliant sysctl parameters
ansible.builtin.include_tasks: sysctl_cis.yml
- name: Configure AppArmor (CIS 1.3.x)
ansible.builtin.include_tasks: apparmor.yml
when: apparmor_enabled | default(true)
- name: Configure fail2ban
ansible.builtin.include_tasks: fail2ban.yml
when: fail2ban_enabled | bool
- name: Configure auditd (CIS 4.1.x)
ansible.builtin.include_tasks: audit.yml
when: auditd_enabled | bool
- name: Configure unattended upgrades
ansible.builtin.include_tasks: unattended_upgrades.yml
when: unattended_upgrades_enabled | bool
- name: Disable uncommon network protocols (CIS 3.3.x)
ansible.builtin.include_tasks: disable_protocols.yml
- name: Configure core dumps restriction (CIS 1.5.1)
ansible.builtin.include_tasks: core_dumps.yml
- name: Disable unnecessary services
ansible.builtin.systemd:
name: "{{ item }}"
state: stopped
enabled: no
loop:
- avahi-daemon
- cups
- isc-dhcp-server
- isc-dhcp-server6
- rpcbind
- rsync
- snmpd
failed_when: false # Don't fail if service doesn't exist
- name: Set secure file permissions (CIS 6.1.x)
ansible.builtin.file:
path: "{{ item.path }}"
mode: "{{ item.mode }}"
loop:
- { path: '/etc/passwd', mode: '0644' }
- { path: '/etc/shadow', mode: '0600' }
- { path: '/etc/group', mode: '0644' }
- { path: '/etc/gshadow', mode: '0600' }
- { path: '/etc/ssh/sshd_config', mode: '0600' }
- name: Create security banners (CIS 1.4.x)
ansible.builtin.copy:
dest: "{{ item }}"
content: |
**************************************************************************
* *
* WARNING: Unauthorized access to this system is forbidden and will *
* be prosecuted by law. By accessing this system, you agree that your *
* actions may be monitored if unauthorized usage is suspected. *
* *
**************************************************************************
mode: '0644'
loop:
- /etc/issue
- /etc/issue.net
- /etc/motd
- name: Display hardening summary
ansible.builtin.debug:
msg:
- "========================================="
- "System Hardening Complete"
- "========================================="
- "CIS Level 1 controls applied"
- "AppArmor: {{ 'ENABLED' if apparmor_enabled | default(true) else 'DISABLED' }}"
- "Auditd: {{ 'ENABLED' if auditd_enabled else 'DISABLED' }}"
- "Fail2ban: {{ 'ENABLED' if fail2ban_enabled else 'DISABLED' }}"
- "Unattended upgrades: {{ 'ENABLED' if unattended_upgrades_enabled else 'DISABLED' }}"
- "========================================="
+53
View File
@@ -0,0 +1,53 @@
---
# SSH Hardening Tasks
- name: Backup original sshd_config
ansible.builtin.copy:
src: /etc/ssh/sshd_config
dest: /etc/ssh/sshd_config.backup
remote_src: yes
force: no
- name: Configure SSH daemon
ansible.builtin.template:
src: sshd_config.j2
dest: /etc/ssh/sshd_config
owner: root
group: root
mode: '0600'
validate: '/usr/sbin/sshd -t -f %s'
notify: restart sshd
- name: Ensure SSH directory exists for root
ansible.builtin.file:
path: /root/.ssh
state: directory
owner: root
group: root
mode: '0700'
- name: Generate strong SSH host keys
ansible.builtin.command: ssh-keygen -A
args:
creates: /etc/ssh/ssh_host_ed25519_key
- name: Remove weak SSH host keys
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop:
- /etc/ssh/ssh_host_dsa_key
- /etc/ssh/ssh_host_dsa_key.pub
- /etc/ssh/ssh_host_ecdsa_key
- /etc/ssh/ssh_host_ecdsa_key.pub
- name: Set permissions on SSH host keys
ansible.builtin.file:
path: "{{ item }}"
owner: root
group: root
mode: '0600'
loop:
- /etc/ssh/ssh_host_rsa_key
- /etc/ssh/ssh_host_ed25519_key
when: ansible_facts['os_family'] == "Debian"
+12
View File
@@ -0,0 +1,12 @@
---
# Sysctl Hardening Tasks
- name: Apply sysctl hardening parameters
ansible.posix.sysctl:
name: "{{ item.key }}"
value: "{{ item.value }}"
state: present
sysctl_set: yes
reload: yes
loop: "{{ sysctl_config | dict2items }}"
when: sysctl_config is defined
+157
View File
@@ -0,0 +1,157 @@
---
# CIS-Compliant Sysctl Parameters
# CIS 3.1.1 - Disable IP forwarding (unless VPN server needs it)
- name: Disable IPv4 forwarding
ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: '1' # Enabled for VPN server
state: present
sysctl_set: yes
reload: yes
# CIS 3.1.2 - Disable packet redirect sending
- name: Disable send packet redirects
ansible.posix.sysctl:
name: "{{ item }}"
value: '0'
state: present
sysctl_set: yes
reload: yes
loop:
- net.ipv4.conf.all.send_redirects
- net.ipv4.conf.default.send_redirects
# CIS 3.2.1 - Do not accept source routed packets
- name: Disable source routed packets
ansible.posix.sysctl:
name: "{{ item }}"
value: '0'
state: present
sysctl_set: yes
reload: yes
loop:
- net.ipv4.conf.all.accept_source_route
- net.ipv4.conf.default.accept_source_route
- net.ipv6.conf.all.accept_source_route
- net.ipv6.conf.default.accept_source_route
# CIS 3.2.2 - Do not accept ICMP redirects
- name: Disable ICMP redirects
ansible.posix.sysctl:
name: "{{ item }}"
value: '0'
state: present
sysctl_set: yes
reload: yes
loop:
- net.ipv4.conf.all.accept_redirects
- net.ipv4.conf.default.accept_redirects
- net.ipv6.conf.all.accept_redirects
- net.ipv6.conf.default.accept_redirects
# CIS 3.2.3 - Do not accept secure ICMP redirects
- name: Disable secure ICMP redirects
ansible.posix.sysctl:
name: "{{ item }}"
value: '0'
state: present
sysctl_set: yes
reload: yes
loop:
- net.ipv4.conf.all.secure_redirects
- net.ipv4.conf.default.secure_redirects
# CIS 3.2.4 - Log suspicious packets
- name: Enable suspicious packet logging
ansible.posix.sysctl:
name: "{{ item }}"
value: '1'
state: present
sysctl_set: yes
reload: yes
loop:
- net.ipv4.conf.all.log_martians
- net.ipv4.conf.default.log_martians
# CIS 3.2.5 - Ignore broadcast ICMP requests
- name: Ignore ICMP broadcast requests
ansible.posix.sysctl:
name: net.ipv4.icmp_echo_ignore_broadcasts
value: '1'
state: present
sysctl_set: yes
reload: yes
# CIS 3.2.6 - Ignore bogus ICMP responses
- name: Ignore bogus ICMP error responses
ansible.posix.sysctl:
name: net.ipv4.icmp_ignore_bogus_error_responses
value: '1'
state: present
sysctl_set: yes
reload: yes
# CIS 3.2.7 - Enable reverse path filtering
- name: Enable reverse path filtering
ansible.posix.sysctl:
name: "{{ item }}"
value: '1'
state: present
sysctl_set: yes
reload: yes
loop:
- net.ipv4.conf.all.rp_filter
- net.ipv4.conf.default.rp_filter
# CIS 3.2.8 - Enable TCP SYN cookies
- name: Enable TCP SYN cookies
ansible.posix.sysctl:
name: net.ipv4.tcp_syncookies
value: '1'
state: present
sysctl_set: yes
reload: yes
# CIS 3.2.9 - Do not accept IPv6 router advertisements
- name: Disable IPv6 router advertisements
ansible.posix.sysctl:
name: "{{ item }}"
value: '0'
state: present
sysctl_set: yes
reload: yes
loop:
- net.ipv6.conf.all.accept_ra
- net.ipv6.conf.default.accept_ra
# Additional hardening
- name: Disable IPv6 (if not used)
ansible.posix.sysctl:
name: "{{ item }}"
value: '1'
state: present
sysctl_set: yes
reload: yes
loop:
- net.ipv6.conf.all.disable_ipv6
- net.ipv6.conf.default.disable_ipv6
when: disable_ipv6 | default(false)
# CIS 1.5.2 - Enable ASLR
- name: Enable address space layout randomization
ansible.posix.sysctl:
name: kernel.randomize_va_space
value: '2'
state: present
sysctl_set: yes
reload: yes
# CIS 1.5.1 - Restrict core dumps
- name: Restrict core dumps
ansible.posix.sysctl:
name: fs.suid_dumpable
value: '0'
state: present
sysctl_set: yes
reload: yes
@@ -0,0 +1,25 @@
---
# Unattended Upgrades Configuration Tasks
- name: Ensure unattended-upgrades is installed
ansible.builtin.apt:
name:
- unattended-upgrades
- apt-listchanges
state: present
- name: Configure unattended-upgrades
ansible.builtin.template:
src: 50unattended-upgrades.j2
dest: /etc/apt/apt.conf.d/50unattended-upgrades
owner: root
group: root
mode: '0644'
- name: Enable automatic updates
ansible.builtin.template:
src: 20auto-upgrades.j2
dest: /etc/apt/apt.conf.d/20auto-upgrades
owner: root
group: root
mode: '0644'