Signed-off-by: Mark Bolwell <mark.bollyuk@gmail.com>
This commit is contained in:
Mark Bolwell 2022-03-30 16:18:11 +01:00
parent 398bc5bd0c
commit c6caa90059
No known key found for this signature in database
GPG key ID: F734FDFC154B83FB
36 changed files with 2584 additions and 2078 deletions

View file

@ -11,6 +11,7 @@
![Release](https://img.shields.io/github/v/release/ansible-lockdown/RHEL9-CIS?style=plastic)
Configure RHEL 9 machine to be [CIS](https://www.cisecurity.org/cis-benchmarks/) compliant with RHEL8 settings (RHEL9 not yet released)
Based on v2.0.0 RHEL8
Based on [CIS RedHat Enterprise Linux 8 Benchmark v1.0.1 - 05-19-2021 ](https://www.cisecurity.org/cis-benchmarks/)

View file

@ -169,49 +169,55 @@ rhel9cis_rule_2_3_5: true
rhel9cis_rule_2_3_6: true
rhel9cis_rule_2_4: true
# Section 3 rules
Section 3 rules
rhel9cis_rule_3_1_1: true
rhel9cis_rule_3_1_2: true
rhel9cis_rule_3_1_3: true
rhel9cis_rule_3_1_4: true
rhel9cis_rule_3_2_1: true
rhel9cis_rule_3_2_2: true
rhel9cis_rule_3_2_3: true
rhel9cis_rule_3_2_4: true
rhel9cis_rule_3_2_5: true
rhel9cis_rule_3_2_6: true
rhel9cis_rule_3_2_7: true
rhel9cis_rule_3_2_8: true
rhel9cis_rule_3_2_9: true
rhel9cis_rule_3_3_1: true
rhel9cis_rule_3_3_2: true
rhel9cis_rule_3_3_3: true
rhel9cis_rule_3_3_4: true
rhel9cis_rule_3_3_5: true
rhel9cis_rule_3_3_6: true
rhel9cis_rule_3_3_7: true
rhel9cis_rule_3_3_8: true
rhel9cis_rule_3_3_9: true
rhel9cis_rule_3_4_1_1: true
rhel9cis_rule_3_4_1_2: true
rhel9cis_rule_3_4_1_3: true
rhel9cis_rule_3_4_1_4: true
rhel9cis_rule_3_4_1_5: true
rhel9cis_rule_3_4_1_6: true
rhel9cis_rule_3_4_1_7: true
rhel9cis_rule_3_4_2_1: true
rhel9cis_rule_3_4_2_2: true
rhel9cis_rule_3_4_2_3: true
rhel9cis_rule_3_4_2_4: true
rhel9cis_rule_3_4_2_5: true
rhel9cis_rule_3_4_2_6: true
rhel9cis_rule_3_4_3_1: true
rhel9cis_rule_3_4_3_2: true
rhel9cis_rule_3_4_3_3: true
rhel9cis_rule_3_4_3_4: true
rhel9cis_rule_3_4_3_5: true
rhel9cis_rule_3_4_3_6: true
rhel9cis_rule_3_4_3_7: true
rhel9cis_rule_3_4_3_8: true
rhel9cis_rule_3_4_4_1_1: true
rhel9cis_rule_3_4_4_1_2: true
rhel9cis_rule_3_4_4_1_3: true
rhel9cis_rule_3_4_4_1_4: true
rhel9cis_rule_3_4_4_1_5: true
rhel9cis_rule_3_4_4_2_1: true
rhel9cis_rule_3_4_4_2_2: true
rhel9cis_rule_3_4_4_2_3: true
rhel9cis_rule_3_4_4_2_4: true
rhel9cis_rule_3_4_4_2_5: true
rhel9cis_rule_3_5: true
rhel9cis_rule_3_6: true
rhel9cis_rule_3_4_2_7: true
rhel9cis_rule_3_4_2_8: true
rhel9cis_rule_3_4_2_9: true
rhel9cis_rule_3_4_2_10: true
rhel9cis_rule_3_4_2_11: true
rhel9cis_rule_3_4_3_1_1: true
rhel9cis_rule_3_4_3_1_2: true
rhel9cis_rule_3_4_3_1_3: true
rhel9cis_rule_3_4_3_2_1: true
rhel9cis_rule_3_4_3_2_2: true
rhel9cis_rule_3_4_3_2_3: true
rhel9cis_rule_3_4_3_2_4: true
rhel9cis_rule_3_4_3_2_5: true
rhel9cis_rule_3_4_3_2_6: true
rhel9cis_rule_3_4_3_3_1: true
rhel9cis_rule_3_4_3_3_2: true
rhel9cis_rule_3_4_3_3_3: true
rhel9cis_rule_3_4_3_3_4: true
rhel9cis_rule_3_4_3_3_5: true
rhel9cis_rule_3_4_3_3_6: true
# Section 4 rules
rhel9cis_rule_4_1_1_1: true
@ -221,30 +227,44 @@ rhel9cis_rule_4_1_1_4: true
rhel9cis_rule_4_1_2_1: true
rhel9cis_rule_4_1_2_2: true
rhel9cis_rule_4_1_2_3: true
rhel9cis_rule_4_1_3: true
rhel9cis_rule_4_1_4: true
rhel9cis_rule_4_1_5: true
rhel9cis_rule_4_1_6: true
rhel9cis_rule_4_1_7: true
rhel9cis_rule_4_1_8: true
rhel9cis_rule_4_1_9: true
rhel9cis_rule_4_1_10: true
rhel9cis_rule_4_1_11: true
rhel9cis_rule_4_1_12: true
rhel9cis_rule_4_1_13: true
rhel9cis_rule_4_1_14: true
rhel9cis_rule_4_1_15: true
rhel9cis_rule_4_1_16: true
rhel9cis_rule_4_1_17: true
rhel9cis_rule_4_1_3_1: true
rhel9cis_rule_4_1_3_2: true
rhel9cis_rule_4_1_3_3: true
rhel9cis_rule_4_1_3_4: true
rhel9cis_rule_4_1_3_5: true
rhel9cis_rule_4_1_3_6: true
rhel9cis_rule_4_1_3_7: true
rhel9cis_rule_4_1_3_8: true
rhel9cis_rule_4_1_3_9: true
rhel9cis_rule_4_1_3_10: true
rhel9cis_rule_4_1_3_11: true
rhel9cis_rule_4_1_3_12: true
rhel9cis_rule_4_1_3_13: true
rhel9cis_rule_4_1_3_14: true
rhel9cis_rule_4_1_3_15: true
rhel9cis_rule_4_1_3_16: true
rhel9cis_rule_4_1_3_17: true
rhel9cis_rule_4_1_3_18: true
rhel9cis_rule_4_1_3_19: true
rhel9cis_rule_4_1_3_20: true
rhel9cis_rule_4_1_3_21: true
rhel9cis_rule_4_2_1_1: true
rhel9cis_rule_4_2_1_2: true
rhel9cis_rule_4_2_1_3: true
rhel9cis_rule_4_2_1_4: true
rhel9cis_rule_4_2_1_5: true
rhel9cis_rule_4_2_1_6: true
rhel9cis_rule_4_2_2_1: true
rhel9cis_rule_4_2_1_7: true
rhel9cis_rule_4_2_2_1_1: true
rhel9cis_rule_4_2_2_1_2: true
rhel9cis_rule_4_2_2_1_3: true
rhel9cis_rule_4_2_2_1_4: true
rhel9cis_rule_4_2_2_2: true
rhel9cis_rule_4_2_2_3: true
rhel9cis_rule_4_2_2_4: true
rhel9cis_rule_4_2_2_5: true
rhel9cis_rule_4_2_2_6: true
rhel9cis_rule_4_2_2_7: true
rhel9cis_rule_4_2_3: true
rhel9cis_rule_4_3: true
@ -257,6 +277,7 @@ rhel9cis_rule_5_1_5: true
rhel9cis_rule_5_1_6: true
rhel9cis_rule_5_1_7: true
rhel9cis_rule_5_1_8: true
rhel9cis_rule_5_1_9: true
rhel9cis_rule_5_2_1: true
rhel9cis_rule_5_2_2: true
rhel9cis_rule_5_2_3: true
@ -280,21 +301,26 @@ rhel9cis_rule_5_2_20: true
rhel9cis_rule_5_3_1: true
rhel9cis_rule_5_3_2: true
rhel9cis_rule_5_3_3: true
rhel9cis_rule_5_3_4: true
rhel9cis_rule_5_3_5: true
rhel9cis_rule_5_3_6: true
rhel9cis_rule_5_3_7: true
rhel9cis_rule_5_4_1: true
rhel9cis_rule_5_4_2: true
rhel9cis_rule_5_4_3: true
rhel9cis_rule_5_4_4: true
rhel9cis_rule_5_5_1_1: true
rhel9cis_rule_5_5_1_2: true
rhel9cis_rule_5_5_1_3: true
rhel9cis_rule_5_5_1_4: true
rhel9cis_rule_5_5_1_5: true
rhel9cis_rule_5_5_1: true
rhel9cis_rule_5_5_2: true
rhel9cis_rule_5_5_3: true
rhel9cis_rule_5_5_4: true
rhel9cis_rule_5_5_5: true
rhel9cis_rule_5_6: true
rhel9cis_rule_5_7: true
rhel9cis_rule_5_6_1_1: true
rhel9cis_rule_5_6_1_2: true
rhel9cis_rule_5_6_1_3: true
rhel9cis_rule_5_6_1_4: true
rhel9cis_rule_5_6_1_5: true
rhel9cis_rule_5_6_2: true
rhel9cis_rule_5_6_3: true
rhel9cis_rule_5_6_4: true
rhel9cis_rule_5_6_5: true
# Section 6 rules
rhel9cis_rule_6_1_1: true
@ -311,6 +337,7 @@ rhel9cis_rule_6_1_11: true
rhel9cis_rule_6_1_12: true
rhel9cis_rule_6_1_13: true
rhel9cis_rule_6_1_14: true
rhel9cis_rule_6_1_15: true
rhel9cis_rule_6_2_1: true
rhel9cis_rule_6_2_2: true
rhel9cis_rule_6_2_3: true
@ -327,10 +354,6 @@ rhel9cis_rule_6_2_13: true
rhel9cis_rule_6_2_14: true
rhel9cis_rule_6_2_15: true
rhel9cis_rule_6_2_16: true
rhel9cis_rule_6_2_17: true
rhel9cis_rule_6_2_18: true
rhel9cis_rule_6_2_19: true
rhel9cis_rule_6_2_20: true
# Service configuration booleans set true to keep service
rhel9cis_avahi_server: false

View file

@ -128,16 +128,16 @@
- patch
- rule_3.3.8
- name: "3.3.9 | L2 | PATCH | Ensure IPv6 router advertisements are not accepted"
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted"
block:
- name: "3.3.9 | L2 | PATCH | Ensure IPv6 router advertisements are not accepted"
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/99-sysctl.conf"
notify:
- update sysctl
- sysctl flush ipv4 route table
- name: "3.3.9 | L2 | PATCH | Ensure IPv6 router advertisements are not accepted"
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/99-sysctl.conf"
notify:

View file

@ -1,14 +0,0 @@
---
- name: "3.4.1.1 | L1 | PATCH | Ensure a Firewall package is installed"
package:
name: "{{ rhel9cis_firewall }}"
state: present
when:
- rhel9cis_rule_3_4_1_1
- not system_is_container
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.1.1

View file

@ -0,0 +1,138 @@
---
- name: "3.4.1.1 | PATCH | Ensure firewalld is installed"
package:
name:
- firewalld
- iptables
state: present
when:
- rhel9cis_rule_3_4_1_1
- rhel9cis_firewall == "firewalld"
tags:
- level1-server
- level1-workstation
- automated
- patch
- firewalld
- rule_3.4.1.1
- name: "3.4.1.2 | PATCH | Ensure iptables-services not installed with firewalld"
block:
- name: "3.4.1.2 | PATCH | Ensure iptables-services not installed with firewalld | Stop running services"
systemd:
name: "{{ item }}"
enabled: false
masked: true
with_items:
- iptables
- ip6tables
when: item in ansible_facts.packages
- name: "3.4.1.2 | PATCH | Ensure iptables-services not installed with firewalld | Remove IPTables"
package:
name: iptables-services
state: absent
when:
- rhel9cis_rule_3_4_1_2
- rhel9cis_firewall == "firewalld"
tags:
- level1-server
- level1-workstation
- automated
- patch
- firewalld
- rule_3.4.1.2
- name: "3.4.1.3 | PATCH | Ensure nftables either not installed or masked with firewalld"
systemd:
name: nftables
state: stopped
masked: yes
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_rule_3_4_1_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- firewalld
- rule_3_4_1_3
- name: "3.4.1.4 | PATCH | Ensure firewalld service is enabled and running"
systemd:
name: firewalld
state: started
enabled: yes
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_rule_3_4_1_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- firewalld
- rule_3_4_1_4
- name: "3.4.1.5 | PATCH | Ensure firewalld default zone is set"
command: firewall-cmd --set-default-zone="{{ rhel9cis_default_zone }}"
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_rule_3_4_1_5
tags:
- level1-server
- level1-workstation
- automated
- patch
- firewalld
- rule_3.4.1.5
- name: "3.4.1.6 | AUDIT | Ensure network interfaces are assigned to appropriate zone"
block:
- name: "3.4.1.6 | AUDIT | Ensure network interfaces are assigned to appropriate zone | Get list of interfaces and polocies"
shell: "nmcli -t connection show | awk -F: '{ if($4){print $4} }' | while read INT; do firewall-cmd --get-active-zones | grep -B1 $INT; done"
changed_when: false
failed_when: false
check_mode: no
register: rhel9cis_3_4_1_6_interfacepolicy
- name: "3.4.1.6 | AUDIT | Ensure network interfaces are assigned to appropriate zone | Get list of interfaces and polocies | Show the interface to policy"
debug:
msg:
- "The items below are the policies tied to the interfaces, please correct as needed"
- "{{ rhel9cis_3_4_1_6_interfacepolicy.stdout_lines }}"
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_rule_3_4_1_6
tags:
- level1-server
- level1-workstation
- manual
- audit
- rule_3.4.1.6
- name: "3.4.1.7 | AUDIT | Ensure firewalld drops unnecessary services and ports"
block:
- name: "3.4.1.7 | AUDIT | Ensure firewalld drops unnecessary services and ports | Get list of services and ports"
shell: "firewall-cmd --get-active-zones | awk '!/:/ {print $1}' | while read ZN; do firewall-cmd --list-all --zone=$ZN; done"
changed_when: false
failed_when: false
check_mode: no
register: rhel9cis_3_4_1_7_servicesport
- name: "3.4.1.7 | AUDIT | Ensure firewalld drops unnecessary services and ports | Show services and ports"
debug:
msg:
- "The items below are the services and ports that are accepted, please correct as needed"
- "{{ rhel9cis_3_4_1_7_servicesport.stdout_lines }}"
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_rule_3_4_1_7
tags:
- level1-server
- level1-workstation
- manual
- audit
- rule_3.4.1.7

View file

@ -1,108 +1,344 @@
---
- name: "3.4.2.1 | L1 | PATCH | Ensure firewalld service is enabled and running"
service:
name: firewalld
state: started
enabled: true
- name: "3.4.2.1 | PATCH | Ensure nftables is installed"
package:
name: nftables
state: present
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_3_4_2_1
- nftables
- rule_3.4.2.1
- name: "3.4.2.2 | L1 | PATCH | Ensure iptables is not enabled with firewalld"
systemd:
name: iptables
masked: true
# The control allows the service it be masked or not installed
# We have chosen not installed
- name: "3.4.2.2 | PATCH | Ensure firewalld is either not installed or masked with nftables"
package:
name: firewalld
state: absent
when:
- rhel9cis_firewall == "firewalld"
- "'iptables' in ansible_facts.packages"
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_2
tags:
- skip_ansible_lint
- level1-server
- level1-workstation
- automated
- patch
- rule_3_4_2_2
- nftables
- rule_3.4.2.2
- name: "3.4.2.3 | L1 | PATCH | Ensure nftables is not enabled with firewalld"
- name: "3.4.2.3 | PATCH | Ensure iptables-services not installed with nftables"
block:
- name: "3.4.2.3 | PATCH | Ensure iptables-services not installed with nftables | Stop services"
systemd:
name: nftables
name: "{{ item }}"
enabled: false
masked: true
ignore_errors: true
with_items:
- iptables
- ip6tables
- name: "3.4.2.3 | PATCH | Ensure iptables-services not installed with nftables | Remove IPTables"
package:
name: iptables-service
state: absent
when:
- rhel9cis_firewall == "firewalld"
- "'nftables' in ansible_facts.packages"
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_3_4_2_3
- nftables
- rule_3.4.2.3
- name: "3.4.2.4 | L1 | PATCH | Ensure default zone is set"
shell: firewall-cmd --set-default-zone="{{ rhel9cis_default_zone }}"
args:
warn: false
- name: "3.4.2.4 | PATCH | Ensure iptables are flushed with nftables"
block:
- name: "3.4.2.4 | PATCH | Ensure iptables are flushed with nftables | IPv4"
command: iptables -F
- name: "3.4.2.4 | PATCH | Ensure iptables are flushed with nftables | IPv6"
command: ip6tables -F
when: rhel9cis_ipv6_required
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_rule_3_4_2_4
- rhel9cis_firewall != "firewalld"
tags:
- level1-server
- level1-workstation
- manual
- patch
- nftables
- rule_3.4.2.4
- name: "3.4.2.5 | L1 | AUDIT | Ensure network interfaces are assigned to appropriate zone"
- name: "3.4.2.5 | AUDIT | Ensure an nftables table exists"
block:
- name: "3.4.2.5 | L1 | AUDIT | Ensure network interfaces are assigned to appropriate zone | Get list of interfaces and polocies"
shell: "nmcli -t connection show | awk -F: '{ if($4){print $4} }' | while read INT; do firewall-cmd --get-active-zones | grep -B1 $INT; done"
args:
warn: false
- name: "3.4.2.5 | AUDIT | Ensure a table exists | Check for tables"
command: nft list tables
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_3_4_2_5_interfacepolicy
register: rhel9cis_3_4_2_5_nft_tables
- name: "3.4.2.5 | L1 | AUDIT | Ensure network interfaces are assigned to appropriate zone | Get list of interfaces and polocies | Show the interface to policy"
- name: "3.4.2.5 | AUDIT | Ensure an nftables table exists | Show existing tables"
debug:
msg:
- "The items below are the policies tied to the interfaces, please correct as needed"
- "{{ rhel9cis_3_4_2_5_interfacepolicy.stdout_lines }}"
- "Below are the current nft tables, please review"
- "{{ rhel9cis_3_4_2_5_nft_tables.stdout_lines }}"
when: rhel9cis_3_4_2_5_nft_tables.stdout | length > 0
- name: "3.4.2.5 | AUDIT | Ensure an nftables table exists | Alert on no tables"
debug:
msg:
- "Warning! You currently have no nft tables, please review your setup"
- 'Use the command "nft create table inet <table name>" to create a new table'
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_3_4_2_5_nft_tables.stdout | length == 0
- not rhel9cis_nft_tables_autonewtable
- name: "3.4.2.5 | PATCH | Ensure a table exists | Create table if needed"
command: nft create table inet "{{ rhel9cis_nft_tables_tablename }}"
failed_when: no
when: rhel9cis_nft_tables_autonewtable
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_5
tags:
- level1-server
- level1-workstation
- audit
- automated
- patch
- nftables
- rule_3.4.2.5
- name: "3.4.2.6 | L1 | AUDIT | Ensure firewalld drops unnecessary services and ports"
- name: "3.4.2.6 | PATCH | Ensure nftables base chains exist"
block:
- name: "3.4.2.6 | L1 | AUDIT | Ensure firewalld drops unnecessary services and ports | Get list of services and ports"
shell: "firewall-cmd --get-active-zones | awk '!/:/ {print $1}' | while read ZN; do firewall-cmd --list-all --zone=$ZN; done"
args:
warn: false
- name: "3.4.2.6 | AUDIT | Ensure nftables base chains exist | Get current chains for INPUT"
shell: nft list ruleset | grep 'hook input'
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_3_4_2_6_servicesport
register: rhel9cis_3_4_2_6_input_chains
- name: "3.4.2.6 | L1 | AUDIT | Ensure firewalld drops unnecessary services and ports | Show services and ports"
- name: "3.4.2.6 | AUDIT | Ensure nftables base chains exist | Get current chains for FORWARD"
shell: nft list ruleset | grep 'hook forward'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_6_forward_chains
- name: "3.4.2.6 | AUDIT | Ensure nftables base chains exist | Get current chains for OUTPUT"
shell: nft list ruleset | grep 'hook output'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_6_output_chains
- name: "3.4.2.6 | AUDIT | Ensure nftables base chains exist | Display chains for review"
debug:
msg:
- "The items below are the services and ports that are accepted, please correct as needed"
- "{{ rhel9cis_3_4_2_6_servicesport.stdout_lines }}"
- "Below are the current INPUT chains"
- "{{ rhel9cis_3_4_2_6_input_chains.stdout_lines }}"
- "Below are the current FORWARD chains"
- "{{ rhel9cis_3_4_2_6_forward_chains.stdout_lines }}"
- "Below are teh current OUTPUT chains"
- "{{ rhel9cis_3_4_2_6_output_chains.stdout_lines }}"
when: not rhel9cis_nft_tables_autochaincreate
- name: "3.4.2.6 | PATCH | Ensure nftables base chains exist | Create chains if needed"
shell: "{{ item }}"
args:
warn: no
failed_when: no
with_items:
- nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" input { type filter hook input priority 0 \; }
- nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" forward { type filter hook forward priority 0 \; }
- nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" output { type filter hook output priority 0 \; }
when: rhel9cis_nft_tables_autochaincreate
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_6
tags:
- level1-server
- level1-workstation
- audit
- automate
- patch
- nftables
- rule_3.4.2.6
- name: "3.4.2.7 | PATCH | Ensure nftables loopback traffic is configured"
block:
- name: "3.4.2.7 | AUDIT | Ensure nftables loopback traffic is configured | Gather iif lo accept existence"
shell: nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_7_iiflo
- name: "3.4.2.7 | AUDIT | Ensure nftables loopback traffic is configured | Gather ip saddr existence"
shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_7_ipsaddr
- name: "3.4.2.7 | AUDIT | Ensure nftables loopback traffic is configured | Gather ip6 saddr existence"
shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_7_ip6saddr
- name: "3.4.2.7 | PATCH | Ensure nftables loopback traffic is configured | Set iif lo accept rule"
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input iif lo accept
when: '"iif \"lo\" accept" not in rhel9cis_3_4_2_7_iiflo.stdout'
- name: "3.4.2.7 | PATCH | Ensure nftables loopback traffic is configured | Set ip sddr rule"
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip saddr 127.0.0.0/8 counter drop
when: '"ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop" not in rhel9cis_3_4_2_7_ipsaddr.stdout'
- name: "3.4.2.7 | PATCH | Ensure nftables loopback traffic is configured | Set ip6 saddr rule"
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip6 saddr ::1 counter drop
when: '"ip6 saddr ::1 counter packets 0 bytes 0 drop" not in rhel9cis_3_4_2_7_ip6saddr.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_7
tags:
- level1-server
- level1-workstation
- automated
- patch
- nftables
- rule_3.4.2.7
- name: "3.4.2.8 | PATCH | Ensure nftables outbound and established connections are configured"
block:
- name: "3.4.2.8 | AUDIT | Ensure nftables outbound and established connections are configured | Gather incoming connection rules"
shell: nft list ruleset | awk '/hook input/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_8_inconnectionrule
- name: "3.4.2.8| AUDIT | Ensure nftables outbound and established connections are configured | Gather outbound connection rules"
shell: nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_8_outconnectionrule
- name: "3.4.2.8| PATCH | Ensure nftables outbound and established connections are configured | Add input tcp established accept policy"
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip protocol tcp ct state established accept
when: '"ip protocol tcp ct state established accept" not in rhel9cis_3_4_2_8_inconnectionrule.stdout'
- name: "3.4.2.8 | PATCH | Ensure nftables outbound and established connections are configured | Add input udp established accept policy"
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip protocol udp ct state established accept
when: '"ip protocol udp ct state established accept" not in rhel9cis_3_4_2_8_inconnectionrule.stdout'
- name: "3.4.2.8 | PATCH | Ensure nftables outbound and established connections are configured | Add input icmp established accept policy"
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip protocol icmp ct state established accept
when: '"ip protocol icmp ct state established accept" not in rhel9cis_3_4_2_8_inconnectionrule.stdout'
- name: "3.4.2.8 | PATCH | Ensure nftables outbound and established connections are configured | Add output tcp new, related, established accept policy"
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" output ip protocol tcp ct state new,related,established accept
when: '"ip protocol tcp ct state established,related,new accept" not in rhel9cis_3_4_2_8_outconnectionrule.stdout'
- name: "3.4.2.8 | PATCH | Ensure nftables outbound and established connections are configured | Add output udp new, related, established accept policy"
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" output ip protocol udp ct state new,related,established accept
when: '"ip protocol udp ct state established,related,new accept" not in rhel9cis_3_4_2_8_outconnectionrule.stdout'
- name: "3.4.2.8 | PATCH | Ensure nftables outbound and established connections are configured | Add output icmp new, related, established accept policy"
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" output ip protocol icmp ct state new,related,established accept
when: '"ip protocol icmp ct state established,related,new accept" not in rhel9cis_3_4_2_8_outconnectionrule.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_8
tags:
- level1-server
- level1-workstation
- automated
- patch
- nftables
- rule_3.4.3.5
- name: "3.4.2.9 | PATCH | Ensure nftables default deny firewall policy"
block:
- name: "3.4.2.9 | AUDIT | Ensure nftables default deny firewall policy | Check for hook input deny policy"
shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook input'
failed_when: false
changed_when: false
register: rhel9cis_3_4_2_9_inputpolicy
- name: "3.4.2.9 | AUDIT | Ensure nftables default deny firewall policy | Check for hook forward deny policy"
shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook forward'
failed_when: false
changed_when: false
register: rhel9cis_3_4_2_9_forwardpolicy
- name: "3.4.2.9 | AUDIT | Ensure nftables default deny firewall policy | Check for hook output deny policy"
shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook output'
failed_when: false
changed_when: false
register: rhel9cis_3_4_2_9_outputpolicy
- name: "3.4.2.9 | AUDIT | Ensure nftables default deny firewall policy | Check for SSH allow"
shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'ssh'
failed_when: false
changed_when: false
register: rhel9cis_3_4_2_9_sshallowcheck
- name: "3.4.2.9 | PATCH | Ensure nftables default deny firewall policy | Enable SSH traffic"
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input tcp dport ssh accept
when: '"tcp dport ssh accept" not in rhel9cis_3_4_2_9_sshallowcheck.stdout'
- name: "3.4.2.9 | PATCH | Ensure nftables default deny firewall policy | Set hook input deny policy"
command: nft chain inet "{{ rhel9cis_nft_tables_tablename }}" input { policy drop \; }
when: '"type filter hook input priority 0; policy drop;" not in rhel9cis_3_4_2_9_inputpolicy.stdout'
- name: "3.4.2.9 | PATCH | Ensure nftables default deny firewall policy | Create hook forward deny policy"
command: nft chain inet "{{ rhel9cis_nft_tables_tablename }}" forward { policy drop \; }
when: '"type filter hook forward priority 0; policy drop;" not in rhel9cis_3_4_2_9_forwardpolicy.stdout'
- name: "3.4.2.9 | PATCH | Ensure nftables default deny firewall policy | Create hook output deny policy"
command: nft chain inet "{{ rhel9cis_nft_tables_tablename }}" output { policy drop \; }
when: '"type filter hook output priority 0; policy drop;" not in rhel9cis_3_4_2_9_outputpolicy.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_9
tags:
- level1-server
- level1-workstation
- automated
- patch
- nftables
- rule_3.4.2.9
- name: "3.4.2.10 | PATCH | Ensure nftables service is enabled"
service:
name: nftables
enabled: yes
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_10
tags:
- level1-server
- level1-workstation
- automated
- patch
- nftables
- rule_3.4.3.7
- name: "3.4.2.11 | PATCH | Ensure nftables rules are permanent"
lineinfile:
path: /etc/sysconfig/nftables.conf
state: present
insertafter: EOF
line: include "/etc/nftables/inet-{{ rhel9cis_nft_tables_tablename }}"
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_11
tags:
- level1-server
- level1-workstation
- automated
- patch
- nftables
- rule_3.4.2.11

View file

@ -0,0 +1,50 @@
---
- name: "3.4.3.1.1 | PATCH | Ensure iptables packages are installed"
package:
name:
- iptables
- iptables-services
state: present
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_3_1_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- iptables
- rule_3.4.3.1.1
- name: "3.4.3.1.2 | PATCH | Ensure nftables is not installed with iptables"
package:
name: nftables
state: absent
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_3_1_2
tags:
- level1-server
- level1-workstation
- automated
- patch
- iptables
- rule_3.4.3.1.2
# The control allows the service it be masked or not installed
# We have chosen not installed
- name: "3.4.3.1.3 | PATCH | Ensure firewalld is either not installed or masked with iptables"
package:
name: firewalld
state: absent
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_3_1_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- iptables
- rule_3.4.3.1.3

View file

@ -1,48 +1,22 @@
---
- name: "3.4.4.1.1 | L1 | PATCH | Ensure iptables default deny firewall policy"
- name: "3.4.3.2.1 | PATCH | Ensure iptables loopback traffic is configured"
block:
- name: "3.4.4.1.1 | L1 | PATCH | Ensure iptables default deny firewall policy | Configure ssh to be allowed"
iptables:
chain: INPUT
protocol: tcp
destination_port: "22"
jump: ACCEPT
- name: "3.4.4.1.1 | L1 | PATCH | Ensure iptables default deny firewall policy | Set drop items"
iptables:
policy: DROP
chain: "{{ item }}"
with_items:
- INPUT
- FORWARD
- OUTPUT
when:
- rhel9cis_rule_3_4_4_1_1
- rhel9cis_firewall == "iptables"
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.4.1.1
- name: "3.4.4.1.2 | L1 | PATCH | Ensure iptables loopback traffic is configured"
block:
- name: "3.4.4.1.2 | L1 | Ensure iptables loopback traffic is configured | INPUT Loopback ACCEPT"
- name: "3.4.3.2.1 | PATCH | Ensure iptables loopback traffic is configured | INPUT Loopback ACCEPT"
iptables:
action: append
chain: INPUT
in_interface: lo
jump: ACCEPT
- name: "3.4.4.1.2 | L1 | PATCH | Ensure iptables loopback traffic is configured | OUTPUT Loopback ACCEPT"
- name: "3.4.3.2.1 | PATCH | Ensure iptables loopback traffic is configured | OUTPUT Loopback ACCEPT"
iptables:
action: append
chain: OUTPUT
out_interface: lo
jump: ACCEPT
- name: "3.4.4.1.2 | L1 | PATCH | Ensure iptables loopback traffic is configured | INPUT Loopback 127.0.0.0/8"
- name: "3.4.3.2.1 | PATCH | Ensure iptables loopback traffic is configured | INPUT Loopback 127.0.0.0/8"
iptables:
action: append
chain: INPUT
@ -50,14 +24,16 @@
jump: DROP
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_4_1_2
- rhel9cis_rule_3_4_3_2_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_3.4.4.1.2
- iptables
- rule_3.4.3.2.1
- name: "3.4.4.1.3 | L1 | PATCH | Ensure iptables outbound and established connections are configured"
- name: "3.4.3.2.2 | PATCH | Ensure iptables outbound and established connections are configured"
iptables:
action: append
chain: '{{ item.chain }}'
@ -74,32 +50,30 @@
- { chain: INPUT, protocol: icmp, ctstate: ESTABLISHED }
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_4_1_3
- rhel9cis_rule_3_4_3_2_2
tags:
- level1-server
- level1-workstation
- manual
- patch
- rule_3.4.4.1.3
- iptables
- rule_3.4.3.2.2
- name: "3.4.4.1.4 | L1 | PATCH | Ensure iptables firewall rules exist for all open ports"
- name: "3.4.3.2.3 | PATCH | Ensure iptables rules exist for all open ports"
block:
- name: "3.4.4.1.4 | L1 | AUDIT | Ensure iptables firewall rules exist for all open ports | Get list of TCP open ports"
- name: "3.4.3.2.3 | AUDIT | Ensure iptables rules exist for all open ports | Get list of TCP open ports"
shell: netstat -ant |grep "tcp.*LISTEN" | awk '{ print $4 }'| sed 's/.*://'
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_4_1_4_otcp
register: rhel9cis_3_4_3_2_3_otcp
- name: "3.4.4.1.4 | L1 | AUDIT | Ensure iptables firewall rules exist for all open ports | Get the list of udp open ports"
- name: "3.4.3.2.3 | AUDIT | Ensure iptables rules exist for all open ports | Get the list of udp open ports"
shell: netstat -ant |grep "udp.*LISTEN" | awk '{ print $4 }'| sed 's/.*://'
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_4_1_4_oudp
register: rhel9cis_3_4_3_2_3_oudp
- name: "3.4.4.1.4 | L1 | PATCH | Ensure iptables firewall rules exist for all open ports | Adjust open tcp ports"
- name: "3.4.3.2.3 | PATCH | Ensure iptables rules exist for all open ports | Adjust open tcp ports"
iptables:
action: append
chain: INPUT
@ -109,10 +83,10 @@
ctstate: NEW
jump: ACCEPT
with_items:
- "{{ rhel9cis_3_4_4_1_4_otcp.stdout_lines }}"
when: rhel9cis_3_4_4_1_4_otcp.stdout is defined
- "{{ rhel9cis_3_4_3_2_3_otcp.stdout_lines }}"
when: rhel9cis_3_4_3_2_3_otcp.stdout is defined
- name: "3.4.4.1.4 | L1 | PATCH | Ensure iptables firewall rules exist for all open ports | Adjust open udp ports"
- name: "3.4.3.2.3 | PATCH | Ensure iptables rules exist for all open ports | Adjust open udp ports"
iptables:
action: append
chain: INPUT
@ -122,27 +96,74 @@
ctstate: NEW
jump: ACCEPT
with_items:
- "{{ rhel9cis_3_4_4_1_4_oudp.stdout_lines }}"
when: rhel9cis_3_4_4_1_4_otcp.stdout is defined
- "{{ rhel9cis_3_4_3_2_3_oudp.stdout_lines }}"
when: rhel9cis_3_4_3_2_3_otcp.stdout is defined
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_4_1_4
- rhel9cis_rule_3_4_3_2_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_3.4.4.1.4
- iptables
- rule_3.4.3.2.3
- name: "3.4.4.1.5 | L1 | PATCH | Ensure iptables service is enabled and active | Check if iptables is enabled"
- name: "3.4.3.2.4 | PATCH | Ensure iptables default deny firewall policy"
block:
- name: "3.4.3.2.4 | PATCH | Ensure iptables default deny firewall policy | Configure ssh to be allowed"
iptables:
chain: INPUT
protocol: tcp
destination_port: "22"
jump: ACCEPT
- name: "3.4.3.2.4 | PATCH | Ensure iptables default deny firewall policy | Set drop items"
iptables:
policy: DROP
chain: "{{ item }}"
with_items:
- INPUT
- FORWARD
- OUTPUT
when:
- rhel9cis_rule_3_4_3_2_4
- rhel9cis_firewall == "iptables"
tags:
- level1-server
- level1-workstation
- automated
- patch
- iptables
- rule_3.4.3.2.4
- name: "3.4.3.2.5 | PATCH | Ensure iptables rules are saved"
iptables_state:
state: saved
path: /etc/sysconfig/iptables
when:
- rhel9cis_rule_3_4_3_2_5
- rhel9cis_firewall == "iptables"
tags:
- level1-server
- level1-workstation
- automated
- patch
- iptables
- rule_3.4.3.2.5
- name: "3.4.3.2.6 | PATCH | Ensure iptables service is enabled and active"
service:
name: iptables
enabled: true
enabled: yes
state: started
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_4_1_5
- rhel9cis_rule_3_4_3_2_6
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_3.4.4.1.5
- iptables
- rule_3.4.3.2.6

View file

@ -1,37 +1,8 @@
---
- name: "3.4.4.2.1 | L1 | PATCH | Ensure ip6tables default deny firewall policy"
- name: "3.4.3.3.1 | PATCH | Ensure ip6tables loopback traffic is configured"
block:
- name: "3.4.4.2.1 | L1 | Ensure ip6tables default deny firewall policy | Configure ssh to be allowed"
iptables:
chain: INPUT
protocol: tcp
destination_port: "22"
jump: ACCEPT
ip_version: ipv6
- name: "3.4.4.2.1 | L1 | PATCH | Ensure ip6tables default deny firewall policy | Set drop items"
iptables:
policy: DROP
chain: "{{ item }}"
ip_version: ipv6
with_items:
- INPUT
- FORWARD
- OUTPUT
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_4_2_1
- rhel9cis_ipv6_required
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.4.2.1
- name: "3.4.4.2.2 | L1 | PATCH | Ensure ip6tables loopback traffic is configured"
block:
- name: "3.4.4.2.2 | L1 | PATCH | Ensure ip6tables loopback traffic is configured | INPUT Loopback ACCEPT"
- name: "3.4.3.3.1 | PATCH | Ensure ip6tables loopback traffic is configured | INPUT Loopback ACCEPT"
iptables:
action: append
chain: INPUT
@ -39,7 +10,7 @@
jump: ACCEPT
ip_version: ipv6
- name: "3.4.4.2.2 | L1 | PATCH | Ensure ip6tables loopback traffic is configured | OUTPUT Loopback ACCEPT"
- name: "3.4.3.3.1 | PATCH | Ensure ip6tables loopback traffic is configured | OUTPUT Loopback ACCEPT"
iptables:
action: append
chain: OUTPUT
@ -47,7 +18,7 @@
jump: ACCEPT
ip_version: ipv6
- name: "3.4.4.2.2 | L1 | PATCH | Ensure ip6tables loopback traffic is configured | INPUT Loopback 127.0.0.0/8"
- name: "3.4.3.3.1 | PATCH | Ensure ip6tables loopback traffic is configured | INPUT Loopback 127.0.0.0/8"
iptables:
action: append
chain: INPUT
@ -56,15 +27,17 @@
ip_version: ipv6
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_4_2_2
- rhel9cis_rule_3_4_3_3_1
- rhel9cis_ipv6_required
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_3.4.4.2.2
- ip6tables
- rule_3.4.3.3.1
- name: "3.4.4.2.3 | L1 | PATCH | Ensure ip6tables outbound and established connections are configured"
- name: "3.4.3.3.2 | PATCH | Ensure ip6tables outbound and established connections are configured"
iptables:
action: append
chain: '{{ item.chain }}'
@ -82,23 +55,25 @@
- { chain: INPUT, protocol: icmp, ctstate: ESTABLISHED }
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_4_2_3
- rhel9cis_rule_3_4_3_3_2
- rhel9cis_ipv6_required
tags:
- level1-server
- level1-workstation
- manual
- patch
- rule_3.4.4.2.3
- ip6tables
- rule_3.4.3.3.2
- name: "3.4.4.2.4 | L1 | PATCH | Ensure ip6tables firewall rules exist for all open ports"
- name: "3.4.3.3.3 | PATCH | Ensure ip6tables firewall rules exist for all open ports"
block:
- name: "3.4.4.2.4 | L1 | AUDIT | Ensure ip6tables firewall rules exist for all open ports | Get list of TCP6 open ports"
- name: "3.4.3.3.3 | AUDIT | Ensure ip6tables firewall rules exist for all open ports | Get list of TCP6 open ports"
shell: netstat -ant |grep "tcp6.*LISTEN" | awk '{ print $4 }'| sed 's/.*://'
changed_when: false
failed_when: false
register: rhel9cis_3_4_4_2_4_otcp
register: rhel9cis_3_4_3_3_3_otcp
- name: "3.4.4.2.4 | L1 | PATCH |Ensure ip6tables firewall rules exist for all open ports| Adjust open tcp6 ports"
- name: "3.4.3.3.3 | PATCH |Ensure ip6tables firewall rules exist for all open ports| Adjust open tcp6 ports"
iptables:
action: append
chain: INPUT
@ -109,28 +84,80 @@
jump: ACCEPT
ip_version: ipv6
with_items:
- "{{ rhel9cis_3_4_4_2_4_otcp.stdout_lines }}"
when: rhel9cis_3_4_4_2_4_otcp.stdout is defined
- "{{ rhel9cis_3_4_3_3_3_otcp.stdout_lines }}"
when: rhel9cis_3_4_3_3_3_otcp.stdout is defined
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_4_2_4
- rhel9cis_rule_3_4_3_3_3
- rhel9cis_ipv6_required
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_3.4.4.2.4
- ip6tables
- rule_3.4.3.3.3
- name: "3.4.4.2.5 | L1 | PATCH | Ensure ip6tables service is enabled and active | Check if ip6tables is enabled"
service:
name: ip6tables
enabled: true
state: started
- name: "3.4.3.3.4 | PATCH | Ensure ip6tables default deny firewall policy"
block:
- name: "3.4.3.3.4 | PATCH | Ensure ip6tables default deny firewall policy | Configure ssh to be allowed"
iptables:
chain: INPUT
protocol: tcp
destination_port: "22"
jump: ACCEPT
ip_version: ipv6
- name: "3.4.3.3.4 | PATCH | Ensure ip6tables default deny firewall policy | Set drop items"
iptables:
policy: DROP
chain: "{{ item }}"
ip_version: ipv6
with_items:
- INPUT
- FORWARD
- OUTPUT
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_4_2_5
- rhel9cis_rule_3_4_3_3_4
- rhel9cis_ipv6_required
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_3.4.4.2.5
- ip6tables
- rule_3.4.3.3.4
- name: "3.4.3.3.5 | PATCH | Ensure ip6tables rules are saved"
iptables_state:
state: saved
path: /etc/sysconfig/ip6tables
ip_version: ipv6
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_ipv6_required
- rhel9cis_rule_3_4_3_3_5
tags:
- level1-server
- level1-workstation
- automated
- patch
- ip6tables
- rule_3.4.3.3.5
- name: "3.4.3.3.6 | PATCH | Ensure ip6tables service is enabled and active"
service:
name: ip6tables
enabled: yes
state: started
when:
- rhel9cis_firewall == "iptables"
- rhel9cis_rule_3_4_3_3_6
tags:
- level1-server
- level1-workstation
- automated
- patch
- ip6tables
- rule_3.4.3.3.6

View file

@ -1,320 +0,0 @@
---
- name: "3.4.3.1 | L1 | PATCH | Ensure iptables are flushed with nftables"
shell: ip6tables -F
args:
warn: false
when:
- rhel9cis_rule_3_4_3_1
- rhel9cis_firewall != "iptables"
- rhel9cis_ipv6_required
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.3.1
- name: "3.4.3.2 | L1 | AUDIT | Ensure an nftables table exists"
block:
- name: "3.4.3.2 | L1 | AUDIT | Ensure a table exists | Check for tables"
shell: nft list tables
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_3_2_nft_tables
- name: "3.4.3.2 | L1 | AUDIT | Ensure an nftables table exists | Show existing tables"
debug:
msg:
- "Below are the current nft tables, please review"
- "{{ rhel9cis_3_4_3_2_nft_tables.stdout_lines }}"
when: rhel9cis_3_4_3_2_nft_tables.stdout | length > 0
- name: "3.4.3.2 | L1 | AUDIT | Ensure an nftables table exists | Alert on no tables"
debug:
msg:
- "Warning! You currently have no nft tables, please review your setup"
- 'Use the shell "nft create table inet <table name>" to create a new table'
when:
- rhel9cis_3_4_3_2_nft_tables.stdout | length == 0
- not rhel9cis_nft_tables_autonewtable
- name: "3.4.3.2 | L1 | PATCH | Ensure a table exists | Create table if needed"
shell: nft create table inet "{{ rhel9cis_nft_tables_tablename }}"
args:
warn: false
failed_when: false
when: rhel9cis_nft_tables_autonewtable
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_3_2
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.3.2
- name: "3.4.3.3 | L1 | PATCH | Ensure nftables base chains exist"
block:
- name: "3.4.3.3 | L1 | Ensure nftables base chains exist | Get current chains for INPUT"
shell: nft list ruleset | grep 'hook input'
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_3_3_input_chains
- name: "3.4.3.3 | L1 | AUDIT | Ensure nftables base chains exist | Get current chains for FORWARD"
shell: nft list ruleset | grep 'hook forward'
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_3_3_forward_chains
- name: "3.4.3.3 | L1 | AUDIT | Ensure nftables base chains exist | Get current chains for OUTPUT"
shell: nft list ruleset | grep 'hook output'
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_3_3_output_chains
- name: "3.4.3.3 | L1 | AUDIT | Ensure nftables base chains exist | Display chains for review"
debug:
msg:
- "Below are the current INPUT chains"
- "{{ rhel9cis_3_4_3_3_input_chains.stdout_lines }}"
- "Below are the current FORWARD chains"
- "{{ rhel9cis_3_4_3_3_forward_chains.stdout_lines }}"
- "Below are teh current OUTPUT chains"
- "{{ rhel9cis_3_4_3_3_output_chains.stdout_lines }}"
when: not rhel9cis_nft_tables_autochaincreate
- name: "3.4.3.3 | L1 | PATCH | Ensure nftables base chains exist | Create chains if needed"
shell: "{{ item }}"
args:
warn: false
failed_when: false
with_items:
- nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" input { type filter hook input priority 0 \; }
- nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" forward { type filter hook forward priority 0 \; }
- nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" output { type filter hook output priority 0 \; }
when: rhel9cis_nft_tables_autochaincreate
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_3_3
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.3.3
- name: "3.4.3.4 | L1 | PATCH | Ensure nftables loopback traffic is configured"
block:
- name: "3.4.3.4 | L1 | AUDIT | Ensure nftables loopback traffic is configured | Gather iif lo accept existence"
shell: nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept'
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_3_4_iiflo
- name: "3.4.3.4 | L1 | AUDIT | Ensure nftables loopback traffic is configured | Gather ip saddr existence"
shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr'
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_3_4_ipsaddr
- name: "3.4.3.4 | L1 | AUDIT | Ensure nftables loopback traffic is configured | Gather ip6 saddr existence"
shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr'
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_3_4_ip6saddr
- name: "3.4.3.4 | L1 | PATCH | Ensure nftables loopback traffic is configured | Set iif lo accept rule"
shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input iif lo accept
args:
warn: false
when: '"iif \"lo\" accept" not in rhel9cis_3_4_3_4_iiflo.stdout'
- name: "3.4.3.4 | L1 | PATCH | Ensure nftables loopback traffic is configured | Set ip sddr rule"
shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip saddr 127.0.0.0/8 counter drop
args:
warn: false
when: '"ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop" not in rhel9cis_3_4_3_4_ipsaddr.stdout'
- name: "3.4.3.4 | L1 | PATCH | Ensure nftables loopback traffic is configured | Set ip6 saddr rule"
shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip6 saddr ::1 counter drop
args:
warn: false
when: '"ip6 saddr ::1 counter packets 0 bytes 0 drop" not in rhel9cis_3_4_3_4_ip6saddr.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_3_4
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.3.4
- name: "3.4.3.5 | L1 | PATCH | Ensure nftables outbound and established connections are configured"
block:
- name: "3.4.3.5 | L1 | AUDIT | Ensure nftables outbound and established connections are configured | Gather incoming connection rules"
shell: nft list ruleset | awk '/hook input/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state'
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_3_5_inconnectionrule
- name: "3.4.3.5 | L1 | AUDIT | Ensure nftables outbound and established connections are configured | Gather outbound connection rules"
shell: nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state'
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_3_4_3_5_outconnectionrule
- name: "3.4.3.5 | L1 | PATCH | Ensure nftables outbound and established connections are configured | Add input tcp established accept policy"
shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip protocol tcp ct state established accept
args:
warn: false
when: '"ip protocol tcp ct state established accept" not in rhel9cis_3_4_3_5_inconnectionrule.stdout'
- name: "3.4.3.5 | L1 | PATCH | Ensure nftables outbound and established connections are configured | Add input udp established accept policy"
shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip protocol udp ct state established accept
args:
warn: false
when: '"ip protocol udp ct state established accept" not in rhel9cis_3_4_3_5_inconnectionrule.stdout'
- name: "3.4.3.5 | L1 | PATCH | Ensure nftables outbound and established connections are configured | Add input icmp established accept policy"
shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip protocol icmp ct state established accept
args:
warn: false
when: '"ip protocol icmp ct state established accept" not in rhel9cis_3_4_3_5_inconnectionrule.stdout'
- name: "3.4.3.5 | L1 | PATCH | Ensure nftables outbound and established connections are configured | Add output tcp new, related, established accept policy"
shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" output ip protocol tcp ct state new,related,established accept
args:
warn: false
when: '"ip protocol tcp ct state established,related,new accept" not in rhel9cis_3_4_3_5_outconnectionrule.stdout'
- name: "3.4.3.5 | L1 | PATCH | Ensure nftables outbound and established connections are configured | Add output udp new, related, established accept policy"
shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" output ip protocol udp ct state new,related,established accept
args:
warn: false
when: '"ip protocol udp ct state established,related,new accept" not in rhel9cis_3_4_3_5_outconnectionrule.stdout'
- name: "3.4.3.5 | L1 | PATCH | Ensure nftables outbound and established connections are configured | Add output icmp new, related, established accept policy"
shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" output ip protocol icmp ct state new,related,established accept
args:
warn: false
when: '"ip protocol icmp ct state established,related,new accept" not in rhel9cis_3_4_3_5_outconnectionrule.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_3_5
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.3.5
- name: "3.4.3.6 | L1 | PATCH | Ensure nftables default deny firewall policy"
block:
- name: "3.4.3.6 | L1 | AUDIT | Ensure nftables default deny firewall policy | Check for hook input deny policy"
shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook input'
args:
warn: false
failed_when: false
changed_when: false
register: rhel9cis_3_4_3_6_inputpolicy
- name: "3.4.3.6 | L1 | AUDIT | Ensure nftables default deny firewall policy | Check for hook forward deny policy"
shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook forward'
args:
warn: false
failed_when: false
changed_when: false
register: rhel9cis_3_4_3_6_forwardpolicy
- name: "3.4.3.6 | L1 | AUDIT | Ensure nftables default deny firewall policy | Check for hook output deny policy"
shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook output'
args:
warn: false
failed_when: false
changed_when: false
register: rhel9cis_3_4_3_6_outputpolicy
- name: "3.4.3.6 | L1 | AUDIT | Ensure nftables default deny firewall policy | Check for SSH allow"
shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'ssh'
args:
warn: false
failed_when: false
changed_when: false
register: rhel9cis_3_4_3_6_sshallowcheck
- name: "3.4.3.6 | L1 | PATCH | Ensure nftables default deny firewall policy | Enable SSH traffic"
shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input tcp dport ssh accept
args:
warn: false
when: '"tcp dport ssh accept" not in rhel9cis_3_4_3_6_sshallowcheck.stdout'
- name: "3.4.3.6 | L1 | PATCH | Ensure nftables default deny firewall policy | Set hook input deny policy"
shell: nft chain inet "{{ rhel9cis_nft_tables_tablename }}" input { policy drop \; }
args:
warn: false
when: '"type filter hook input priority 0; policy drop;" not in rhel9cis_3_4_3_6_inputpolicy.stdout'
- name: "3.4.3.6 | L1 | PATCH | Ensure nftables default deny firewall policy | Create hook forward deny policy"
shell: nft chain inet "{{ rhel9cis_nft_tables_tablename }}" forward { policy drop \; }
args:
warn: false
when: '"type filter hook forward priority 0; policy drop;" not in rhel9cis_3_4_3_6_forwardpolicy.stdout'
- name: "3.4.3.6 | L1 | PATCH | Ensure nftables default deny firewall policy | Create hook output deny policy"
shell: nft chain inet "{{ rhel9cis_nft_tables_tablename }}" output { policy drop \; }
args:
warn: false
when: '"type filter hook output priority 0; policy drop;" not in rhel9cis_3_4_3_6_outputpolicy.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_3_6
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.3.6
- name: "3.4.3.7 | L1 | PATCH | Ensure nftables service is enabled | Check if nftables is enabled"
service:
name: nftables
enabled: true
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_3_7
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.3.7
- name: "3.4.3.8 | L1 | PATCH | Ensure nftables rules are permanent"
lineinfile:
path: /etc/sysconfig/nftables.conf
state: present
insertafter: EOF
line: include "/etc/nftables/inet-{{ rhel9cis_nft_tables_tablename }}"
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_3_8
tags:
- level1-server
- level1-workstation
- patch
- rule_3.4.3.8

View file

@ -1,27 +0,0 @@
---
- name: "3.5 | L1 | PATCH | Ensure wireless interfaces are disabled"
block:
- name: "3.5 | L1 | AUDIT | Ensure wireless interfaces are disabled | Check if wifi is enabled"
shell: nmcli radio wifi
args:
warn: false
register: rhel_09_wifi_enabled
changed_when: rhel_09_wifi_enabled.stdout != "disabled"
failed_when: false
- name: "3.5 | L1 | PATCH | Ensure wireless interfaces are disabled | Disable wifi if enabled"
shell: nmcli radio all off
args:
warn: false
changed_when: false
failed_when: false
when: rhel_09_wifi_enabled is changed
when:
- '"NetworkManager" in ansible_facts.packages'
- rhel9cis_rule_3_5
tags:
- level1-server
- level2-workstation
- patch
- rule_3.5

View file

@ -1,17 +0,0 @@
---
- name: "3.6 | L2 | PATCH | Disable IPv6"
replace:
dest: /etc/default/grub
regexp: '(^GRUB_CMDLINE_LINUX\s*\=\s*)(?:")(.+)(?<!ipv6.disable=1)(?:")'
replace: '\1"\2 ipv6.disable=1"'
follow: true
notify: grub2cfg
when:
- not rhel9cis_ipv6_required
- rhel9cis_rule_3_6
tags:
- level2-server
- level2-workstation
- patch
- rule_3.6

View file

@ -1,14 +1,14 @@
---
- name: "4.1.1.1 | L2 | PATCH | Ensure auditd is installed"
- name: "4.1.1.1 | PATCH | Ensure auditd is installed"
block:
- name: "4.1.1.1 | L2 | PATCH | Ensure auditd is installed | Install auditd packages"
- name: "4.1.1.1 | PATCH | Ensure auditd is installed | Install auditd packages"
package:
name: audit
state: present
when: '"auditd" not in ansible_facts.packages'
- name: "4.1.1.1 | L2 | PATCH | Ensure auditd is installed | Install auditd-lib packages"
- name: "4.1.1.1 | PATCH | Ensure auditd is installed | Install auditd-lib packages"
package:
name: audit-libs
state: present
@ -18,38 +18,38 @@
tags:
- level2-server
- level2-workstation
- automated
- patch
- rule_4.1.1.1
- auditd
- rule_4.1.1.1
- name: "4.1.1.2 | L2 | PATCH | Ensure auditd service is enabled"
- name: "4.1.1.2 | PATCH | Ensure auditd service is enabled"
service:
name: auditd
state: started
enabled: true
enabled: yes
when:
- not rhel9cis_skip_for_travis
- rhel9cis_rule_4_1_1_2
- not system_is_container
- ansible_connection != 'docker'
tags:
- level2-server
- level2-workstation
- auditd
- automated
- patch
- auditd
- rule_4.1.1.2
- name: "4.1.1.3 | L2 | PATCH | Ensure auditing for processes that start prior to auditd is enabled"
- name: "4.1.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled"
block:
- name: "4.1.1.3 | L2 | AUDIT | Ensure auditing for processes that start prior to auditd is enabled | Get GRUB_CMDLINE_LINUX"
- name: "4.1.1.3 | AUDIT | Ensure auditing for processes that start prior to auditd is enabled | Get GRUB_CMDLINE_LINUX"
shell: grep 'GRUB_CMDLINE_LINUX=' /etc/default/grub | sed 's/.$//'
args:
warn: false
changed_when: false
failed_when: false
check_mode: false
check_mode: no
register: rhel9cis_4_1_1_3_grub_cmdline_linux
- name: "4.1.1.3 | L2 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Replace existing setting"
- name: "4.1.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Replace existing setting"
replace:
dest: /etc/default/grub
regexp: 'audit=.'
@ -57,7 +57,7 @@
notify: grub2cfg
when: "'audit=' in rhel9cis_4_1_1_3_grub_cmdline_linux.stdout"
- name: "4.1.1.3 | L2 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Add audit setting if missing"
- name: "4.1.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Add audit setting if missing"
lineinfile:
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX='
@ -69,22 +69,22 @@
tags:
- level2-server
- level2-workstation
- auditd
- automated
- patch
- auditd
- grub
- rule_4.1.1.3
- name: "4.1.1.4 | L2 | PATCH | Ensure audit_backlog_limit is sufficient"
- name: "4.1.1.4 | PATCH | Ensure audit_backlog_limit is sufficient"
block:
- name: "4.1.1.4 | L2 | AUDIT | Ensure audit_backlog_limit is sufficient | Get GRUB_CMDLINE_LINUX"
- name: "4.1.1.4 | AUDIT | Ensure audit_backlog_limit is sufficient | Get GRUB_CMDLINE_LINUX"
shell: grep 'GRUB_CMDLINE_LINUX=' /etc/default/grub | sed 's/.$//'
args:
warn: false
changed_when: false
failed_when: false
check_mode: false
check_mode: no
register: rhel9cis_4_1_1_4_grub_cmdline_linux
- name: "4.1.1.4 | L2 | PATCH | Ensure audit_backlog_limit is sufficient | Replace existing setting"
- name: "4.1.1.4 | PATCH | Ensure audit_backlog_limit is sufficient | Replace existing setting"
replace:
dest: /etc/default/grub
regexp: 'audit_backlog_limit=\d+'
@ -92,7 +92,7 @@
notify: grub2cfg
when: "'audit_backlog_limit=' in rhel9cis_4_1_1_4_grub_cmdline_linux.stdout"
- name: "4.1.1.4 | L2 | PATCH | Ensure audit_backlog_limit is sufficient | Add audit_backlog_limit setting if missing"
- name: "4.1.1.4 | PATCH | Ensure audit_backlog_limit is sufficient | Add audit_backlog_limit setting if missing"
lineinfile:
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX='
@ -104,6 +104,8 @@
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- grub
- rule_4.1.1.4

View file

@ -1,6 +1,6 @@
---
- name: "4.1.2.1 | L2 | PATCH | Ensure audit log storage size is configured"
- name: "4.1.2.1 | PATCH | Ensure audit log storage size is configured"
lineinfile:
dest: /etc/audit/auditd.conf
regexp: "^max_log_file( |=)"
@ -12,11 +12,12 @@
tags:
- level2-server
- level2-workstation
- auditd
- automated
- patch
- auditd
- rule_4.1.2.1
- name: "4.1.2.2 | L2 | PATCH | Ensure audit logs are not automatically deleted"
- name: "4.1.2.2 | PATCH | Ensure audit logs are not automatically deleted"
lineinfile:
dest: /etc/audit/auditd.conf
regexp: "^max_log_file_action"
@ -28,11 +29,12 @@
tags:
- level2-server
- level2-workstation
- auditd
- automated
- patch
- auditd
- rule_4.1.2.2
- name: "4.1.2.3 | L2 | PATCH | Ensure system is disabled when audit logs are full"
- name: "4.1.2.3 | PATCH | Ensure system is disabled when audit logs are full"
lineinfile:
dest: /etc/audit/auditd.conf
regexp: "{{ item.regexp }}"
@ -48,6 +50,7 @@
tags:
- level2-server
- level2-workstation
- auditd
- automated
- patch
- auditd
- rule_4.1.2.3

View file

@ -0,0 +1,322 @@
- name: "4.1.3.1 | PATCH | Ensure changes to system administration scope (sudoers) is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_1
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.1
- name: "4.1.3.2 | PATCH | Ensure actions as another user are always logged"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_2
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.2
- name: "4.1.3.3 | PATCH | Ensure events that modify the sudo log file are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_3
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.3
- name: "4.1.3.4 | PATCH | Ensure events that modify date and time information are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_4
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.4
- name: "4.1.3.5 | PATCH | Ensure events that modify the system's network environment are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_5
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.5
- name: "4.1.3.6 | PATCH | Ensure use of privileged commands is collected"
block:
- name: "4.1.3.6 | PATCH | Ensure use of privileged commands is collected"
shell: for i in $(df | grep '^/dev' | awk '{ print $NF }'); do find $i -xdev -type f -perm -4000 -o -type f -perm -2000 2>/dev/null; done
changed_when: false
failed_when: false
check_mode: no
register: priv_procs
- name: "4.1.3.6 | PATCH | Ensure use of privileged commands is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_6
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.6
- name: "4.1.3.7 | PATCH | Ensure unsuccessful unauthorized file access attempts are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_7
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3_7
- name: "4.1.3.8 | PATCH | Ensure events that modify user/group information are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_8
tags:
- level2-server
- level2-workstation
- autoamted
- patch
- auditd
- rule_4.1.3.8
- name: "4.1.3.9 | PATCH | Ensure discretionary access control permission modification events are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_9
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.9
- name: "4.1.3.10 | PATCH | Ensure successful file system mounts are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_10
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.10
- name: "4.1.3.11 | PATCH | Ensure session initiation information is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_11
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.11
- name: "4.1.3.12 | PATCH | Ensure login and logout events are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_12
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.12
- name: "4.1.3.13 | PATCH | Ensure file deletion events by users are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_13
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.3.13
- name: "4.1.3.14 | PATCH | Ensure events that modify the system's Mandatory Access Controls are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_14
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.14
- name: "4.1.3.15 | PATCH | Ensure successful and unsuccessful attempts to use the chcon command are recorded"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_15
tags:
- level2-server
- level2- workstation
- automated
- patch
- auditd
- rule_4.1.3.15
- name: "4.1.3.16 | PATCH | Ensure successful and unsuccessful attempts to use the setfacl command are recorded"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_16
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.16
- name: "4.1.3.17 | PATCH | Ensure successful and unsuccessful attempts to use the chacl command are recorded"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_17
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.17
- name: "4.1.3.18 | PATCH | Ensure successful and unsuccessful attempts to use the usermod command are recorded"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_18
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.18
- name: "4.1.3.19 | PATCH | Ensure kernel module loading and unloading is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_19
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.19
- name: "4.1.3.20 | PATCH | Ensure the audit configuration is immutable"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_20
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.20
- name: "4.1.3.21 | AUDIT | Ensure the running and on disk configuration is the same"
debug:
msg:
- "Please run augenrules --load if you suspect there is a configuration that is not active"
when:
- rhel9cis_rule_4_1_3_21
tags:
- level2-server
- level2-workstation
- manual
- patch
- auditd
- rule_4.1.3.21

View file

@ -1,207 +0,0 @@
---
- name: "4.1.3 | L2 | PATCH | Ensure changes to system administration scope (sudoers) is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_3
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.3
- name: "4.1.4 | L2 | PATCH | Ensure login and logout events are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_4
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.4
- name: "4.1.5 | L2 | PATCH | Ensure session initiation information is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_5
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.5
- name: "4.1.6 | L2 | PATCH | Ensure events that modify date and time information are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_6
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.6
- name: "4.1.7 | L2 | PATCH | Ensure events that modify the system's Mandatory Access Controls are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_7
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.7
- name: "4.1.8 | L2 | PATCH | Ensure events that modify the system's network environment are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_8
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.8
- name: "4.1.9 | L2 | PATCH | Ensure discretionary access control permission modification events are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_9
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.9
- name: "4.1.10 | L2 | PATCH | Ensure unsuccessful unauthorized file access attempts are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_10
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.10
- name: "4.1.11 | L2 | PATCH | Ensure events that modify user/group information are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_11
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.11
- name: "4.1.12 | L2 | PATCH | Ensure successful file system mounts are collected"
block:
- name: "4.1.12 | L2 | AUDIT | Ensure successful file system mounts are collected"
shell: for i in $(df | grep '^/dev' | awk '{ print $NF }'); do find $i -xdev -type f -perm -4000 -o -type f -perm -2000 2>/dev/null; done
args:
warn: false
changed_when: false
failed_when: false
check_mode: false
register: priv_procs
- name: "4.1.12 | L2 | PATCH | Ensure successful file system mounts are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_12
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.12
- name: "4.1.13 | L2 | PATCH | Ensure use of privileged commands is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_13
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.13
- name: "4.1.14 | L2 | PATCH | Ensure file deletion events by users are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_14
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.14
- name: "4.1.15 | L2 | PATCH | Ensure kernel module loading and unloading is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_15
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.15
- name: "4.1.16 | L2 | PATCH | Ensure system administrator actions (sudolog) are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_16
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.16
- name: "4.1.17 | L2 | PATCH | Ensure the audit configuration is immutable"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
notify: update auditd
when:
- rhel9cis_rule_4_1_17
tags:
- level2-server
- level2-workstation
- auditd
- patch
- rule_4.1.17

View file

@ -1,6 +1,6 @@
---
- name: "4.2.1.1 | L1 | PATCH | Ensure rsyslog installed"
- name: "4.2.1.1 | PATCH | Ensure rsyslog installed"
package:
name: rsyslog
state: present
@ -10,55 +10,74 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- rsyslog
- rule_4.2.1.1
- name: "4.2.1.2 | L1 | PATCH | Ensure rsyslog Service is enabled"
- name: "4.2.1.2 | PATCH | Ensure rsyslog Service is enabled"
service:
name: rsyslog
enabled: true
enabled: yes
when:
- rhel9cis_rule_4_2_1_2
tags:
- level1-server
- level1-workstation
- autoamted
- patch
- rsyslog
- rule_4.2.1.2
- name: "4.2.1.3 | L1 | PATCH | Ensure rsyslog default file permissions configured"
# This is counter to control 4.2.1.5??
- name: "4.2.1.3 | PATCH | Ensure journald is configured to send logs to rsyslog"
lineinfile:
dest: /etc/systemd/journald.conf
regexp: "^#ForwardToSyslog=|^ForwardToSyslog="
line: ForwardToSyslog=yes
state: present
when:
- rhel9cis_rule_4_2_1_3
tags:
- level1-server
- level1-workstation
- manual
- patch
- rule_4.2.1.3
- name: "4.2.1.4 | PATCH | Ensure rsyslog default file permissions configured"
lineinfile:
dest: /etc/rsyslog.conf
regexp: '^\$FileCreateMode'
line: '$FileCreateMode 0640'
notify: restart rsyslog
when:
- rhel9cis_rule_4_2_1_3
- rhel9cis_rule_4_2_1_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_4.2.1.3
- rsyslog
- rule_4.2.1.4
- name: "4.2.1.4 | L1 | PATCH | Ensure logging is configured"
- name: "4.2.1.5 | PATCH | Ensure logging is configured"
block:
- name: "4.2.1.4 | L1 | AUDIT | Ensure logging is configured | rsyslog current config message out"
shell: cat /etc/rsyslog.conf
args:
warn: false
become: true
- name: "4.2.1.5 | AUDIT | Ensure logging is configured | rsyslog current config message out"
command: cat /etc/rsyslog.conf
become: yes
changed_when: false
failed_when: false
check_mode: false
register: rhel_09_4_2_1_4_audit
failed_when: no
check_mode: no
register: rhel_08_4_2_1_5_audit
- name: "4.2.1.4 | L1 | AUDIT | Ensure logging is configured | rsyslog current config message out"
- name: "4.2.1.5 | AUDIT | Ensure logging is configured | rsyslog current config message out"
debug:
msg:
- "These are the current logging configurations for rsyslog, please review:"
- "{{ rhel_09_4_2_1_4_audit.stdout_lines }}"
- "{{ rhel_08_4_2_1_5_audit.stdout_lines }}"
- name: "4.2.1.4 | L1 | PATCH | Ensure logging is configured | mail.* log setting"
- name: "4.2.1.5 | PATCH | Ensure logging is configured | mail.* log setting"
blockinfile:
path: /etc/rsyslog.conf
state: present
@ -73,7 +92,7 @@
notify: restart rsyslog
when: rhel9cis_rsyslog_ansiblemanaged
- name: "4.2.1.4 | L1 | PATCH | Ensure logging is configured | news.crit log setting"
- name: "4.2.1.5 | PATCH | Ensure logging is configured | news.crit log setting"
blockinfile:
path: /etc/rsyslog.conf
state: present
@ -86,7 +105,7 @@
notify: restart rsyslog
when: rhel9cis_rsyslog_ansiblemanaged
- name: "4.2.1.4 | L1 | PATCH | Ensure logging is configured | Misc. log setting"
- name: "4.2.1.5 | PATCH | Ensure logging is configured | Misc. log setting"
blockinfile:
path: /etc/rsyslog.conf
state: present
@ -100,13 +119,13 @@
notify: restart rsyslog
when: rhel9cis_rsyslog_ansiblemanaged
- name: "4.2.1.4 | L1 | PATCH | Ensure logging is configured | Local log settings"
- name: "4.2.1.5 | PATCH | Ensure logging is configured | Local log settings"
blockinfile:
path: /etc/rsyslog.conf
state: present
marker: "#{mark} LOCAL LOG SETTINGS (ANSIBLE MANAGED)"
block: |
# local log settings
# local log settings to meet CIS standards
local0,local1.* -/var/log/localmessages
local2,local3.* -/var/log/localmessages
local4,local5.* -/var/log/localmessages
@ -114,16 +133,39 @@
*.emrg :omusrmsg:*
insertafter: '#### RULES ####'
notify: restart rsyslog
- name: "4.2.1.5 | PATCH | Ensure logging is configured | Auth Settings"
blockinfile:
path: /etc/rsyslog.conf
state: present
marker: "#{mark} Auth SETTINGS (ANSIBLE MANAGED)"
block: |
# Private settings to meet CIS standards
auth,authpriv.* -/var/log/secure
insertafter: '#### RULES ####'
notify: restart rsyslog
- name: "4.2.1.5 | PATCH | Ensure logging is configured | Cron Settings"
blockinfile:
path: /etc/rsyslog.conf
state: present
marker: "#{mark} Auth SETTINGS (ANSIBLE MANAGED)"
block: |
# Cron settings to meet CIS standards
cron.* /var/log/cron
insertafter: '#### RULES ####'
notify: restart rsyslog
when:
- rhel9cis_rule_4_2_1_4
- rhel9cis_rule_4_2_1_5
tags:
- level1-server
- level1-workstation
- manual
- patch
- rsyslog
- rule_4.2.1.4
- rule_4.2.1.5
- name: "4.2.1.5 | L1 | PATCH | Ensure rsyslog is configured to send logs to a remote log host"
- name: "4.2.1.6 | PATCH | Ensure rsyslog is configured to send logs to a remote log host"
blockinfile:
path: /etc/rsyslog.conf
state: present
@ -137,18 +179,19 @@
- result.rc != 257
notify: restart rsyslog
when:
- rhel9cis_rule_4_2_1_5
- rhel9cis_rule_4_2_1_6
- rhel9cis_remote_log_server is defined
tags:
- level1-server
- level1-workstation
- manual
- patch
- rule_4.2.1.5
- rsyslog
- rule_4.2.1.6
- name: "4.2.1.6 | L1 | PATCH | Ensure remote rsyslog messages are only accepted on designated log hosts."
- name: "4.2.1.7 | PATCH | Ensure rsyslog is not configured to recieve logs from a remote client"
block:
- name: "4.2.1.6 | L1 | PATCH | Ensure remote rsyslog messages are only accepted on designated log hosts. | When not log host"
- name: "4.2.1.7 | PATCH | Ensure rsyslog is not configured to recieve logs from a remote client. | When not log host"
replace:
path: /etc/rsyslog.conf
regexp: '({{ item }})'
@ -157,9 +200,11 @@
with_items:
- '^(\$ModLoad imtcp)'
- '^(\$InputTCPServerRun)'
- '^(module\(load="imtcp"\))'
- '^(input\(type="imtcp")'
when: not rhel9cis_system_is_log_server
- name: "4.2.1.6 | L1 | PATCH | Ensure remote rsyslog messages are only accepted on designated log hosts. | When log host"
- name: "4.2.1.7 | PATCH | Ensure rsyslog is not configured to recieve logs from a remote clients. | When log host"
replace:
path: /etc/rsyslog.conf
regexp: '^#(.*{{ item }}.*)'
@ -168,12 +213,15 @@
with_items:
- 'ModLoad imtcp'
- 'InputTCPServerRun'
- 'module\(load="imtcp"\)'
- 'input\(type="imtcp"'
when: rhel9cis_system_is_log_server
when:
- rhel9cis_rule_4_2_1_6
- rhel9cis_rule_4_2_1_7
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_4.2.1.6
- rsyslog
- rule_4.2.1.7

View file

@ -1,43 +1,206 @@
---
- name: "4.2.2.1 | L1 | PATCH | Ensure journald is configured to send logs to rsyslog"
lineinfile:
dest: /etc/systemd/journald.conf
regexp: "^#ForwardToSyslog=|^ForwardToSyslog="
line: ForwardToSyslog=yes
- name: "4.2.2.1.1 | PATCH | Ensure systemd-journal-remote is installed"
package:
name: systemd-journal-remote
state: present
when:
- rhel9cis_rule_4_2_2_1
- rhel9cis_rule_4_2_2_1_1
tags:
- level1-server
- level1-workstation
- manual
- patch
- rule_4.2.2.1
- journald
- rule_4.2.2.1.1
- name: "4.2.2.2 | L1 | PATCH | Ensure journald is configured to compress large log files"
- name: "4.2.2.1.2 | PATCH | Ensure systemd-journal-remote is configured"
lineinfile:
path: /etc/systemd/journal-upload.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
notify: restart systemd_journal_upload
with_items:
- { regexp: 'URL=', line: 'URL={{ rhel9cis_journal_upload_url }}'}
- { regexp: 'ServerKeyFile=', line: 'ServerKeyFile={{ rhel9cis_journal_upload_serverkeyfile }}'}
- { regexp: 'ServerCertificateFile=', line: 'ServerCertificateFile={{ rhel9cis_journal_servercertificatefile }}'}
- { regexp: 'TrustedCertificateFile=', line: 'TrustedCertificateFile={{ rhel9cis_journal_trustedcertificatefile }}'}
when:
- rhel9cis_rule_4_2_2_1_2
tags:
- level1-server
- level1-workstation
- manual
- patch
- journald
- rule_4.2.2.1.2
- name: "4.2.2.1.3 | PATCH | Ensure systemd-journal-remote is enabled"
systemd:
name: systemd-journal-upload
state: started
enabled: yes
when:
- rhel9cis_rule_4_2_2_1_3
tags:
- level1-server
- level1-workstation
- manual
- patch
- journald
- rule_4.2.2.1.3
- name: "4.2.2.1.4 | PATCH | Ensure journald is not configured to recieve logs from a remote client"
systemd:
name: systemd-journal-remote
state: stopped
enabled: no
masked: yes
when:
- rhel9cis_rule_4_2_2_1_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- journald
- rule_4.2.2.1.4
- name: "4.2.2.2 | PATCH | Ensure journald service is enabled"
block:
- name: "4.2.2.2 | PATCH | Ensure journald service is enabled | Enable service"
systemd:
name: systemd-journald
state: started
enabled: yes
- name: "4.2.2.2 | AUDIT | Ensure journald service is enabled | Capture status"
shell: systemctl is-enabled systemd-journald.service
changed_when: false
failed_when: false
register: rhel9cis_4_2_2_2_status
- name: "4.2.2.2 | AUDIT | Ensure journald service is enabled | Alert on bad status"
debug:
msg:
- "ALERT! The status of systemd-journald should be static and it is not. Please investigate"
when: "'static' not in rhel9cis_4_2_2_2_status.stdout"
when:
- rhel9cis_rule_4_2_2_2
tags:
- level1-server
- level1-workstation
- automated
- audit
- journald
- rule_4.2.2.2
- name: "4.2.2.3 | PATCH | Ensure journald is configured to compress large log files"
lineinfile:
dest: /etc/systemd/journald.conf
regexp: "^#Compress=|^Compress="
line: Compress=yes
state: present
when:
- rhel9cis_rule_4_2_2_2
- rhel9cis_rule_4_2_2_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_4.2.2.2
- journald
- rule_4.2.2.3
- name: "4.2.2.3 | L1 | PATCH | Ensure journald is configured to write logfiles to persistent disk"
- name: "4.2.2.4 | PATCH | Ensure journald is configured to write logfiles to persistent disk"
lineinfile:
dest: /etc/systemd/journald.conf
regexp: "^#Storage=|^Storage="
line: Storage=persistent
state: present
when:
- rhel9cis_rule_4_2_2_3
- rhel9cis_rule_4_2_2_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_4.2.2.3
- journald
- rule_4.2.2.4
# This is counter to control 4.2.1.3??
- name: "4.2.2.5 | PATCH | Ensure journald is not configured to send logs to rsyslog"
lineinfile:
dest: /etc/systemd/journald.conf
regexp: "^ForwardToSyslog="
line: "#ForwardToSyslog=yes"
state: present
notify: restart systemd_journal_upload
when:
- rhel9cis_rule_4_2_2_5
tags:
- level1-server
- level2-workstation
- manual
- patch
- journald
- rule_4.2.2.5
- name: "4.2.2.6 | PATCH | Ensure journald log rotation is configured per site policy"
lineinfile:
path: /etc/systemd/journald.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
notify: restart journald
with_items:
- { regexp: '^#SystemMaxUse=|^SystemMaxUse=', line: 'SystemMaxUse={{ rhel9cis_journald_systemmaxuse }}'}
- { regexp: '^#SystemKeepFree=|^SystemKeepFree=', line: 'SystemKeepFree={{ rhel9cis_journald_systemkeepfree }}' }
- { regexp: '^#RuntimeMaxUse=|^RuntimeMaxUse=', line: 'RuntimeMaxUse={{ rhel9cis_journald_runtimemaxuse }}'}
- { regexp: '^#RuntimeKeepFree=|^RuntimeKeepFree=', line: 'RuntimeKeepFree={{ rhel9cis_journald_runtimekeepfree }}'}
- { regexp: '^#MaxFileSec=|^MaxFileSec=', line: 'MaxFileSec={{ rhel9cis_journald_maxfilesec }}'}
when:
- rhel9cis_rule_4_2_2_6
tags:
- level1-server
- level1-workstation
- manual
- patch
- journald
- rule_4.2.2.6
- name: "4.2.2.7 | AUDIT | Ensure journald default file permissions configured"
block:
- name: "4.2.2.7 | AUDIT | Ensure journald default file permissions configured | Check for override file"
find:
paths: /etc/tmpfiles.d
patterns: systemd.conf
register: rhel9cis_4_2_2_7_override_status
- name: "4.2.2.7 | AUDIT | Ensure journald default file permissions configured | Get override file settings"
shell: cat /etc/tmpfiles.d/systemd.conf
changed_when: false
failed_when: false
register: rhel9cis_4_2_2_7_override_settings
when: rhel9cis_4_2_2_7_override_status.matched >= 1
- name: "4.2.2.7 | AUDIT | Ensure journald default file permissions configured | Get non-override file settings"
shell: cat /usr/lib/tmpfiles.d/systemd.conf
changed_when: false
failed_when: false
register: rhel9cis_4_2_2_7_notoverride_settings
when: rhel9cis_4_2_2_7_override_status.matched == 0
- name: "4.2.2.7 | AUDIT | Ensure journald default file permissions configured | Display file settings"
debug:
msg:
- "Alert! Below are the current default settings for journald, please confirm they align with your site policies"
# - "{{ rhel9cis_4_2_2_7_override_settings.stdout_lines }}"
- "{{ (rhel9cis_4_2_2_7_override_status.matched >= 1) | ternary(rhel9cis_4_2_2_7_override_settings.stdout_lines, rhel9cis_4_2_2_7_notoverride_settings.stdout_lines) }}"
when:
- rhel9cis_rule_4_2_2_7
tags:
- level1-server
- level1-workstation
- manual
- patch
- journald
- rule_4.2.2.7

View file

@ -1,9 +1,7 @@
---
- name: "4.2.3 | L1 | PATCH | Ensure permissions on all logfiles are configured"
shell: find /var/log -type f -exec chmod g-wx,o-rwx "{}" +
args:
warn: false
- name: "4.2.3 | PATCH | Ensure permissions on all logfiles are configured"
command: find /var/log -type f -exec chmod g-wx,o-rwx "{}" +
changed_when: false
failed_when: false
when:
@ -11,5 +9,7 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- logfiles
- rule_4.2.3

View file

@ -1,13 +1,13 @@
---
- name: "4.3 | L1 | PATCH | Ensure logrotate is configured"
- name: "4.3 | PATCH | Ensure logrotate is configured"
block:
- name: "4.3 | L1 | AUDIT | Ensure logrotate is configured | Get logrotate settings"
- name: "4.3 | AUDIT | Ensure logrotate is configured | Get logrotate settings"
find:
paths: /etc/logrotate.d/
register: log_rotates
- name: "4.3 | L1 | PATCH | Ensure logrotate is configured"
- name: "4.3 | PATCH | Ensure logrotate is configured"
replace:
path: "{{ item.path }}"
regexp: '^(\s*)(daily|weekly|monthly|yearly)$'
@ -15,11 +15,14 @@
with_items:
- "{{ log_rotates.files }}"
- { path: "/etc/logrotate.conf" }
loop_control:
label: "{{ item.path }}"
when:
- rhel9cis_rule_4_3
- "'logrotate' in ansible_facts.packages"
tags:
- level1-server
- level1-workstation
- manual
- patch
- logrotate
- rule_4.3

View file

@ -5,17 +5,17 @@
when:
- not system_is_container
- name: "SECTION | 4.1.2.x| Configure Data Retention"
- name: "SECTION | 4.1.2 | Configure Data Retention"
import_tasks: cis_4.1.2.x.yml
- name: "SECTION | 4.1.x| Auditd rules"
- name: "SECTION | 4.1.3 | Configure Auditd rules"
import_tasks: cis_4.1.x.yml
- name: "SECTION | 4.2.x| Configure Logging"
- name: "SECTION | 4.2 | Configure Logging"
import_tasks: cis_4.2.1.x.yml
when: rhel9cis_syslog == 'rsyslog'
- name: "SECTION | 4.2.2.x| Configure journald"
- name: "SECTION | 4.2.2 Configure journald"
import_tasks: cis_4.2.2.x.yml
- name: "SECTION | 4.2.3 | Configure logile perms"

View file

@ -1,18 +1,20 @@
---
- name: "5.1.1 | L1 | PATCH | Ensure cron daemon is enabled"
- name: "5.1.1 | PATCH | Ensure cron daemon is enabled"
service:
name: crond
enabled: true
enabled: yes
when:
- rhel9cis_rule_5_1_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.1
- name: "5.1.2 | L1 | PATCH | Ensure permissions on /etc/crontab are configured"
- name: "5.1.2 | PATCH | Ensure permissions on /etc/crontab are configured"
file:
dest: /etc/crontab
owner: root
@ -23,10 +25,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.2
- name: "5.1.3 | L1 | PATCH | Ensure permissions on /etc/cron.hourly are configured"
- name: "5.1.3 | PATCH | Ensure permissions on /etc/cron.hourly are configured"
file:
dest: /etc/cron.hourly
state: directory
@ -38,10 +42,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.3
- name: "5.1.4 | L1 | PATCH | Ensure permissions on /etc/cron.daily are configured"
- name: "5.1.4 | PATCH | Ensure permissions on /etc/cron.daily are configured"
file:
dest: /etc/cron.daily
state: directory
@ -53,10 +59,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.4
- name: "5.1.5 | L1 | PATCH | Ensure permissions on /etc/cron.weekly are configured"
- name: "5.1.5 | PATCH | Ensure permissions on /etc/cron.weekly are configured"
file:
dest: /etc/cron.weekly
state: directory
@ -71,7 +79,7 @@
- patch
- rule_5.1.5
- name: "5.1.6 | L1 | PATCH | Ensure permissions on /etc/cron.monthly are configured"
- name: "5.1.6 | PATCH | Ensure permissions on /etc/cron.monthly are configured"
file:
dest: /etc/cron.monthly
state: directory
@ -83,10 +91,11 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_5.1.6
- name: "5.1.7 | L1 | PATCH | Ensure permissions on /etc/cron.d are configured"
- name: "5.1.7 | PATCH | Ensure permissions on /etc/cron.d are configured"
file:
dest: /etc/cron.d
state: directory
@ -98,43 +107,27 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.7
- name: "5.1.8 | L1 | PATCH | Ensure at/cron is restricted to authorized users"
- name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users"
block:
- name: "5.1.8 | L1 | PATCH | Ensure at/cron is restricted to authorized users | Remove at.deny"
file:
dest: /etc/at.deny
state: absent
- name: "5.1.8 | L1 | PATCH | Ensure at/cron is restricted to authorized users | Check if at.allow exists"
stat:
path: "/etc/at.allow"
register: p
- name: "5.1.8 | L1 | PATCH | Ensure at/cron is restricted to authorized users | Ensure at.allow is restricted to authorized users"
file:
dest: /etc/at.allow
state: '{{ "file" if p.stat.exists else "touch" }}'
owner: root
group: root
mode: 0600
- name: "5.1.8 | L1 | PATCH | Ensure at/cron is restricted to authorized users | Remove cron.deny"
- name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users | Remove cron.deny"
file:
dest: /etc/cron.deny
state: absent
- name: "5.1.8 | L1 | PATCH | Ensure at/cron is restricted to authorized users | Check if cron.allow exists"
- name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users | Check if cron.allow exists"
stat:
path: "/etc/cron.allow"
register: p
register: rhel9cis_5_1_8_cron_allow_state
- name: "5.1.8 | L1 | PATCH | Ensure at/cron is restricted to authorized users | Ensure cron.allow is restricted to authorized users"
- name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users | Ensure cron.allow is restricted to authorized users"
file:
dest: /etc/cron.allow
state: '{{ "file" if p.stat.exists else "touch" }}'
state: '{{ "file" if rhel9cis_5_1_8_cron_allow_state.stat.exists else "touch" }}'
owner: root
group: root
mode: 0600
@ -143,5 +136,36 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.8
- name: "5.1.9 | PATCH | Ensure at is restricted to authorized users"
block:
- name: "5.1.9 | PATCH | Ensure at is restricted to authorized users | Remove at.deny"
file:
dest: /etc/at.deny
state: absent
- name: "5.1.9 | PATCH | Ensure at is restricted to authorized users | Check if at.allow exists"
stat:
path: "/etc/at.allow"
register: rhel9cis_5_1_9_at_allow_state
- name: "5.1.9 | PATCH | Ensure at is restricted to authorized users | Ensure at.allow is restricted to authorized users"
file:
dest: /etc/at.allow
state: '{{ "file" if rhel9cis_5_1_9_at_allow_state.stat.exists else "touch" }}'
owner: root
group: root
mode: 0600
when:
- rhel9cis_rule_5_1_9
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.9

View file

@ -1,6 +1,6 @@
---
- name: "5.2.1 | L1 | PATCH | Ensure permissions on /etc/ssh/sshd_config are configured"
- name: "5.2.1 | Ensure permissions on /etc/ssh/sshd_config are configured"
file:
dest: /etc/ssh/sshd_config
state: file
@ -12,12 +12,76 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- permissions
- rule_5.2.1
- name: "5.2.2 | L1 | PATCH | Ensure SSH access is limited"
- name: "5.2.2 | PATCH | Ensure permissions on SSH private host key files are configured"
block:
- name: "5.2.2 | L1 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowusers"
- name: "5.2.2 | AUDIT | Ensure permissions on SSH private host key files are configured | Find the SSH private host keys"
find:
paths: /etc/ssh
patterns: 'ssh_host_*_key'
recurse: true
file_type: any
register: rhel9cis_5_2_2_ssh_private_host_key
- name: "5.2.2 | PATCH | Ensure permissions on SSH private host key files are configured | Set permissions on SSH private host keys"
file:
path: "{{ item.path }}"
owner: root
group: root
mode: 0600
with_items:
- "{{ rhel9cis_5_2_2_ssh_private_host_key.files }}"
loop_control:
label: "{{ item.path }}"
when:
- rhel9cis_rule_5_2_2
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- permissions
- rule_5.2.2
- name: "5.2.3 | PATCH | Ensure permissions on SSH public host key files are configured"
block:
- name: "5.2.3 | AUDIT | Ensure permissions on SSH public host key files are configured | Find the SSH public host keys"
find:
paths: /etc/ssh
patterns: 'ssh_host_*_key.pub'
recurse: true
file_type: any
register: rhel9cis_5_2_3_ssh_public_host_key
- name: "5.2.3 | PATCH | Ensure permissions on SSH public host key files are configured | Set permissions on SSH public host keys"
file:
path: "{{ item.path }}"
owner: root
group: root
mode: 0644
with_items:
- "{{ rhel9cis_5_2_3_ssh_public_host_key.files }}"
loop_control:
label: "{{ item.path }}"
when:
- rhel9cis_rule_5_2_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.3
- name: "5.2.4 | PATCH | Ensure SSH access is limited"
block:
- name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowusers"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
@ -26,7 +90,7 @@
notify: restart sshd
when: "rhel9cis_sshd['allowusers']|default('') | length > 0"
- name: "5.2.2 | L1 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowgroups"
- name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowgroups"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
@ -35,7 +99,7 @@
notify: restart sshd
when: "rhel9cis_sshd['allowgroups']|default('') | length > 0"
- name: "5.2.2 | L1 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denyusers"
- name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denyusers"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
@ -44,7 +108,7 @@
notify: restart sshd
when: "rhel9cis_sshd['denyusers']|default('') | length > 0"
- name: "5.2.2 | L1 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denygroups"
- name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denygroups"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
@ -52,67 +116,17 @@
line: DenyGroups {{ rhel9cis_sshd['denygroups'] }}
notify: restart sshd
when: "rhel9cis_sshd['denygroups']|default('') | length > 0"
when:
- rhel9cis_rule_5_2_2
tags:
- level1-server
- level1-workstation
- patch
- rule_5.2.2
- name: "5.2.3 | L1 | PATCH | Ensure permissions on SSH private host key files are configured"
block:
- name: "5.2.3 | L1 | AUDIT | Ensure permissions on SSH private host key files are configured | Find the SSH private host keys"
find:
paths: /etc/ssh
patterns: 'ssh_host_*_key'
recurse: true
file_type: any
register: rhel9cis_5_2_3_ssh_private_host_key
- name: "5.2.3 | L1 | PATCH | Ensure permissions on SSH private host key files are configured | Set permissions on SSH private host keys"
file:
path: "{{ item.path }}"
owner: root
group: root
mode: 0600
with_items:
- "{{ rhel9cis_5_2_3_ssh_private_host_key.files }}"
when:
- rhel9cis_rule_5_2_3
tags:
- level1-server
- level1-workstation
- patch
- rule_5.2.3
- name: "5.2.4 | L1 | PATCH | Ensure permissions on SSH public host key files are configured"
block:
- name: "5.2.4 | L1 | AUDIT | Ensure permissions on SSH public host key files are configured | Find the SSH public host keys"
find:
paths: /etc/ssh
patterns: 'ssh_host_*_key.pub'
recurse: true
file_type: any
register: rhel9cis_5_2_4_ssh_public_host_key
- name: "5.2.4 | L1 | PATCH | Ensure permissions on SSH public host key files are configured | Set permissions on SSH public host keys"
file:
path: "{{ item.path }}"
owner: root
group: root
mode: 0644
with_items:
- "{{ rhel9cis_5_2_4_ssh_public_host_key.files }}"
when:
- rhel9cis_rule_5_2_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.4
- name: "5.2.5 | L1 | PATCH | Ensure SSH LogLevel is appropriate"
- name: "5.2.5 | PATCH | Ensure SSH LogLevel is appropriate"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
@ -123,145 +137,155 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- sshs
- rule_5.2.5
- name: "5.2.6 | L2 | PATCH | Ensure SSH X11 forwarding is disabled"
- name: "5.2.6 | PATCH | Ensure SSH PAM is enabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#X11Forwarding|^X11Forwarding"
line: 'X11Forwarding no'
regexp: "^#UsePAM|^UsePAM"
line: 'UsePAM yes'
when:
- rhel9cis_rule_5_2_6
tags:
- level2-server
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.6
- name: "5.2.7 | L1 | PATCH | Ensure SSH MaxAuthTries is set to 4 or less"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: '^(#)?MaxAuthTries \d'
line: 'MaxAuthTries 4'
when:
- rhel9cis_rule_5_2_7
tags:
- level1-server
- level1-workstation
- patch
- rule_5.2.7
- name: "5.2.8 | L1 | PATCH | Ensure SSH IgnoreRhosts is enabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#IgnoreRhosts|^IgnoreRhosts"
line: 'IgnoreRhosts yes'
when:
- rhel9cis_rule_5_2_8
tags:
- level1-server
- level1-workstation
- patch
- rule_5.2.8
- name: "5.2.9 | L1 | PATCH | Ensure SSH HostbasedAuthentication is disabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: ^#HostbasedAuthentication|^HostbasedAuthentication"
line: 'HostbasedAuthentication no'
when:
- rhel9cis_rule_5_2_9
tags:
- level1-server
- level1-workstation
- patch
- rule_5.2.9
- name: "5.2.10 | L1 | PATCH | Ensure SSH root login is disabled"
- name: "5.2.7 | PATCH | Ensure SSH root login is disabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#PermitRootLogin|^PermitRootLogin"
line: 'PermitRootLogin no'
when:
- rhel9cis_rule_5_2_10
- rhel9cis_rule_5_2_7
tags:
- level1-server
- level1-workstation
- autoamted
- patch
- rule_5.2.10
- ssh
- rule_5.2.7
- name: "5.2.11 | L1 | PATCH | Ensure SSH PermitEmptyPasswords is disabled"
- name: "5.2.8 | PATCH | Ensure SSH HostbasedAuthentication is disabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: ^#HostbasedAuthentication|^HostbasedAuthentication"
line: 'HostbasedAuthentication no'
when:
- rhel9cis_rule_5_2_8
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.8
- name: "5.2.9 | PATCH | Ensure SSH PermitEmptyPasswords is disabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#PermitEmptyPasswords|^PermitEmptyPasswords"
line: 'PermitEmptyPasswords no'
when:
- rhel9cis_rule_5_2_11
- rhel9cis_rule_5_2_9
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_5.2.11
- ssh
- rule_5.2.9
- name: "5.2.12 | L1 | PATCH | Ensure SSH PermitUserEnvironment is disabled"
- name: "5.2.10 | PATCH | Ensure SSH PermitUserEnvironment is disabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#PermitUserEnvironment|^PermitUserEnvironment"
line: 'PermitUserEnvironment no'
when:
- rhel9cis_rule_5_2_12
- rhel9cis_rule_5_2_10
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.10
- name: "5.2.11 | PATCH | Ensure SSH IgnoreRhosts is enabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#IgnoreRhosts|^IgnoreRhosts"
line: 'IgnoreRhosts yes'
when:
- rhel9cis_rule_5_2_11
tags:
- level1-server
- level1-workstation
- autoamted
- patch
- ssh
- rule_5.2.11
- name: "5.2.12 | PATCH | Ensure SSH X11 forwarding is disabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#X11Forwarding|^X11Forwarding"
line: 'X11Forwarding no'
when:
- rhel9cis_rule_5_2_12
tags:
- level2-server
- level1-workstation
- autoamted
- patch
- ssh
- rule_5.2.12
- name: "5.2.13 | L1 | PATCH | Ensure SSH Idle Timeout Interval is configured"
block:
- name: "5.2.13 | L1 | PATCH | Ensure SSH Idle Timeout Interval is configured | Add line in sshd_config for ClientAliveInterval"
- name: "5.2.13 | PATCH | Ensure SSH AllowTcpForwarding is disabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: '^ClientAliveInterval'
line: "ClientAliveInterval {{ rhel9cis_sshd['clientaliveinterval'] }}"
- name: "5.2.13 | L1 | PATCH | Ensure SSH Idle Timeout Interval is configured | Ensure SSH ClientAliveCountMax set to <= 3"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: '^ClientAliveCountMax'
line: "ClientAliveCountMax {{ rhel9cis_sshd['clientalivecountmax'] }}"
regexp: "^#AllowTcpForwarding|^AllowTcpForwarding"
line: 'AllowTcpForwarding no'
when:
- rhel9cis_rule_5_2_13
tags:
- level1-server
- level1-workstation
- level2-server
- level2-workstation
- autoamted
- patch
- ssh
- rule_5.2.13
- name: "5.2.14 | L1 | PATCH | Ensure SSH LoginGraceTime is set to one minute or less"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#LoginGraceTime|^LoginGraceTime"
line: "LoginGraceTime {{ rhel9cis_sshd['logingracetime'] }}"
- name: "5.2.14 | PATCH | Ensure system-wide crypto policy is not over-ridden"
shell: sed -ri "s/^\s*(CRYPTO_POLICY\s*=.*)$/# \1/" /etc/sysconfig/sshd
args:
warn: no
notify: restart sshd
when:
- rhel9cis_rule_5_2_14
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.14
- name: "5.2.15 | L1 | PATCH | Ensure SSH warning banner is configured"
- name: "5.2.15 | PATCH | Ensure SSH warning banner is configured"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
@ -272,74 +296,96 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.15
- name: "5.2.16 | L1 | PATCH | Ensure SSH PAM is enabled"
- name: "5.2.16 | PATCH | Ensure SSH MaxAuthTries is set to 4 or less"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#UsePAM|^UsePAM"
line: 'UsePAM yes'
regexp: '^(#)?MaxAuthTries \d'
line: 'MaxAuthTries 4'
when:
- rhel9cis_rule_5_2_16
tags:
- level1-server
- level1-workstation
- autoamted
- patch
- ssh
- rule_5.2.16
- name: "5.2.17 | L2 | PATCH | Ensure SSH AllowTcpForwarding is disabled"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#AllowTcpForwarding|^AllowTcpForwarding"
line: 'AllowTcpForwarding no'
when:
- rhel9cis_rule_5_2_17
tags:
- level2-server
- level2-workstation
- patch
- rule_5.2.17
- name: "5.2.18 | L1 | PATCH | Ensure SSH MaxStartups is configured"
- name: "5.2.17 | PATCH | Ensure SSH MaxStartups is configured"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#MaxStartups|^MaxStartups"
line: 'MaxStartups 10:30:60'
when:
- rhel9cis_rule_5_2_18
- rhel9cis_rule_5_2_17
tags:
- level1-server
- level1-workstation
- autoamted
- patch
- rule_5.2.18
- ssh
- rule_5.2.17
- name: "5.2.19 | L1 | PATCH | Ensure SSH MaxSessions is set to 4 or less"
- name: "5.2.18 | PATCH | Ensure SSH MaxSessions is set to 10 or less"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#MaxSessions|^MaxSessions"
line: 'MaxSessions {{ rhel9cis_ssh_maxsessions }}'
when:
- rhel9cis_rule_5_2_18
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.18
- name: "5.2.19 | PATCH | Ensure SSH LoginGraceTime is set to one minute or less"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: "^#LoginGraceTime|^LoginGraceTime"
line: "LoginGraceTime {{ rhel9cis_sshd['logingracetime'] }}"
when:
- rhel9cis_rule_5_2_19
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.19
- name: "5.2.20 | L1 | PATCH | Ensure system-wide crypto policy is not over-ridden"
shell: sed -ri "s/^\s*(CRYPTO_POLICY\s*=.*)$/# \1/" /etc/sysconfig/sshd
args:
warn: false
notify: restart sshd
- name: "5.2.20 | PATCH | Ensure SSH Idle Timeout Interval is configured"
block:
- name: "5.2.20 | PATCH | Ensure SSH Idle Timeout Interval is configured | Add line in sshd_config for ClientAliveInterval"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: '^ClientAliveInterval'
line: "ClientAliveInterval {{ rhel9cis_sshd['clientaliveinterval'] }}"
- name: "5.2.20 | PATCH | Ensure SSH Idle Timeout Interval is configured | Ensure SSH ClientAliveCountMax set to <= 3"
lineinfile:
state: present
dest: /etc/ssh/sshd_config
regexp: '^ClientAliveCountMax'
line: "ClientAliveCountMax {{ rhel9cis_sshd['clientalivecountmax'] }}"
when:
- rhel9cis_rule_5_2_20
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.20

View file

@ -1,94 +1,138 @@
---
- name: "5.3.1 | L1 | PATCH | Create custom authselect profile"
block:
- name: "5.3.1 | L1 | PATCH | Create custom authselect profile | Gather profiles"
shell: 'authselect current | grep "Profile ID: custom/"'
args:
warn: false
failed_when: false
changed_when: false
check_mode: false
register: rhel9cis_5_3_1_profiles
- name: "5.3.1 | L1 | AUDIT | Create custom authselect profile | Show profiles"
debug:
msg:
- "Below are the current custom profiles"
- "{{ rhel9cis_5_3_1_profiles.stdout_lines }}"
- name: "5.3.1 | L1 | PATCH | Create custom authselect profile | Create custom profiles"
shell: authselect create-profile {{ rhel9cis_authselect['custom_profile_name'] }} -b {{ rhel9cis_authselect['default_file_to_copy'] }}
args:
warn: false
when: rhel9cis_authselect_custom_profile_create
- name: "5.3.1 | PATCH | Ensure sudo is installed"
package:
name: sudo
state: present
when:
- rhel9cis_rule_5_3_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- authselect
- sudo
- rule_5.3.1
- name: "5.3.2 | L1 | PATCH | Select authselect profile"
block:
- name: "5.3.2 | L1 | AUDIT | Select authselect profile | Gather profiles and enabled features"
shell: "authselect current"
args:
warn: false
failed_when: false
changed_when: false
check_mode: false
register: rhel9cis_5_3_2_profiles
- name: "5.3.2 | L1 | AUDIT | Select authselect profile | Show profiles"
debug:
msg:
- "Below are the current custom profiles"
- "{{ rhel9cis_5_3_2_profiles.stdout_lines }}"
- name: "5.3.2 | L1 | PATCH | Select authselect profile | Create custom profiles"
shell: "authselect select custom/{{ rhel9cis_authselect['custom_profile_name'] }} {{ rhel9cis_authselect['options'] }}"
args:
warn: false
when: rhel9cis_authselect_custom_profile_select
- name: "5.3.2 | PATCH | Ensure sudo commands use pty"
lineinfile:
dest: /etc/sudoers
line: "Defaults use_pty"
state: present
when:
- rhel9cis_rule_5_3_2
tags:
- level1-server
- level1-workstation
- automated
- patch
- authselect
- sudo
- rule_5.3.2
- name: "5.3.3 | L1 | PATCH | Ensure authselect includes with-faillock"
block:
- name: "5.3.3 | L1 | AUDIT | Ensure authselect includes with-faillock | Gather profiles and enabled features"
shell: "authselect current | grep with-faillock"
args:
warn: false
failed_when: false
changed_when: false
check_mode: false
register: rhel9cis_5_3_3_profiles_faillock
- name: "5.3.3 | L1 | AUDIT | Ensure authselect includes with-faillock| Show profiles"
debug:
msg:
- "Below are the current custom profiles"
- "{{ rhel9cis_5_3_3_profiles_faillock.stdout_lines }}"
- name: "5.3.3 | L1 | PATCH | Ensure authselect includes with-faillock | Create custom profiles"
shell: "authselect select custom/{{ rhel9cis_authselect['custom_profile_name'] }} with-faillock"
args:
warn: false
when: rhel9cis_authselect_custom_profile_select
- name: "5.3.3 | PATCH | Ensure sudo log file exists"
lineinfile:
dest: /etc/sudoers
regexp: '^Defaults logfile='
line: 'Defaults logfile="{{ rhel9cis_varlog_location }}"'
state: present
when:
- rhel9cis_rule_5_3_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- authselect
- sudo
- rule_5.3.3
- name: "5.3.4 | PATCH | Ensure users must provide password for escalation"
replace:
path: "{{ item }}"
regexp: '^([^#|{% if system_is_ec2 %}ec2-user{% endif %}].*)NOPASSWD(.*)'
replace: '\1PASSWD\2'
with_items:
- "{{ rhel9cis_sudoers_files.stdout_lines }}"
when:
- rhel9cis_rule_5_3_4
tags:
- level2-server
- level2-workstation
- automated
- patch
- sudo
- rule_5.3.4
- name: "5.3.5 | PATCH | Ensure re-authentication for privilege escalation is not disabled globally"
replace:
path: "{{ item }}"
regexp: '^([^#].*)!authenticate(.*)'
replace: '\1authenticate\2'
with_items:
- "{{ rhel9cis_sudoers_files.stdout_lines }}"
when:
- rhel9cis_rule_5_3_5
tags:
- level1-server
- level1-workstation
- automated
- patch
- sudo
- rule_5.3.5
- name: "5.3.6 | PATCH | Ensure sudo authentication timeout is configured correctly"
block:
- name: "5.3.6 | AUDIT | Ensure sudo authentication timeout is configured correctly | Get files with timeout set"
shell: grep -is 'timestamp_timeout' /etc/sudoers /etc/sudoers.d/* | cut -d":" -f1 | uniq | sort
changed_when: false
failed_when: false
register: rhel9cis_5_3_6_timeout_files
- name: "5.3.6 | PATCH | Ensure sudo authentication timeout is configured correctly | Set value if no results"
lineinfile:
path: /etc/sudoers
regexp: 'Defaults timestamp_timeout='
line: "Defaults timestamp_timeout={{ rhel9cis_sudo_timestamp_timeout }}"
validate: '/usr/sbin/visudo -cf %s'
when: rhel9cis_5_3_6_timeout_files.stdout | length == 0
- name: "5.3.6 | PATCH | Ensure sudo authentication timeout is configured correctly | Set value if has results"
replace:
path: "{{ item }}"
regexp: 'timestamp_timeout=(\d+)'
replace: "timestamp_timeout={{ rhel9cis_sudo_timestamp_timeout }}"
validate: '/usr/sbin/visudo -cf %s'
with_items:
- "{{ rhel9cis_5_3_6_timeout_files.stdout_lines }}"
when: rhel9cis_5_3_6_timeout_files.stdout | length > 0
when:
- rhel9cis_rule_5_3_6
tags:
- level1-server
- level1-workstation
- automated
- patch
- sudo
- rule_5.3.6
- name: "5.3.7 | PATCH | Ensure access to the su command is restricted"
block:
- name: "5.3.7 | PATCH | Ensure access to the su command is restricted | Setting pam_wheel to use_uid"
lineinfile:
state: present
dest: /etc/pam.d/su
regexp: '^(#)?auth\s+required\s+pam_wheel\.so'
line: 'auth required pam_wheel.so use_uid {% if rhel9cis_sugroup is defined %}group={{ rhel9cis_sugroup }}{% endif %}'
- name: "5.3.7 | PATCH | Ensure access to the su command is restricted | wheel group contains root"
user:
name: "{{ rhel9cis_sugroup_users }}"
groups: "{{ rhel9cis_sugroup | default('wheel') }}"
when:
- rhel9cis_rule_5_3_7
tags:
- level1-server
- level1-workstation
- automated
- patch
- sudo
- rule_5.3.7

View file

@ -1,131 +1,61 @@
---
- name: |
"5.4.1 | L1 | PATCH | Ensure password creation requirements are configured
5.4.2 | L1 | PATCH | Ensure lockout for failed password attempts is configured
5.4.3 | L1 | PATCH | Ensure password reuse is limited
5.4.4 | L1 | PATCH | Ensure password hashing algorithm is SHA-512"
- name: "5.4.1 | PATCH | Ensure custom authselect profile is used"
block:
- name: "5.4.1 | L1 | PATCH | Ensure password creation requirements are configured | Set pwquality config settings"
lineinfile:
state: present
dest: /etc/security/pwquality.conf
regexp: ^{{ item.name }}
line: "{{ item.name }} = {{ item.value }}"
with_items:
- { name: minlen, value: "{{ rhel9cis_pam_password.minlen }}" }
- { name: minclass, value: "{{ rhel9cis_pam_password.minclass }}" }
when: rhel9cis_rule_5_4_1
- name: "5.4.1 | AUDIT | Ensure custom authselect profile is used | Gather profiles"
shell: 'authselect current | grep "Profile ID: custom/"'
failed_when: false
changed_when: false
check_mode: no
register: rhel9cis_5_4_1_profiles
- name: |
"5.4.1 | L1 | PATCH | Ensure password creation requirements are configured | Set system-auth retry settings
5.4.3| L1 | PATCH | Ensure password reuse is limited | Set system-auth remember settings"
lineinfile:
dest: /etc/pam.d/system-auth
state: present
regexp: '^password requisite pam_pwquality.so'
line: "password requisite pam_pwquality.so try_first_pass local_users_only enforce_for_root retry=3 remember={{ rhel9cis_pam_faillock.remember }}"
insertbefore: '^#?password ?'
- name: "5.4.1 | AUDIT | Ensure custom authselect profile is used | Show profiles"
debug:
msg:
- "Below are the current custom profiles"
- "{{ rhel9cis_5_4_1_profiles.stdout_lines }}"
- name: "5.4.1 | PATCH | Ensure custom authselect profile is used | Create custom profiles"
shell: authselect create-profile {{ rhel9cis_authselect['custom_profile_name'] }} -b {{ rhel9cis_authselect['default_file_to_copy'] }}
args:
warn: no
when: rhel9cis_authselect_custom_profile_create
when:
- rhel9cis_rule_5_4_1 or
rhel9cis_rule_5_4_3
- name: "5.4.1 | L1 | PATCH | Ensure password creation requirements are configured | Set system-auth retry settings"
lineinfile:
dest: /etc/pam.d/password-auth
state: present
regexp: '^password requisite pam_pwquality.so'
line: "password requisite pam_pwquality.so try_first_pass local_users_only enforce_for_root retry=3"
insertbefore: '^#?password ?'
when: rhel9cis_rule_5_4_1
- name: "5.4.2 | L1 | PATCH | Ensure lockout for failed password attempts is configured | Add deny count and unlock time for preauth"
lineinfile:
dest: /etc/pam.d/{{ item }}
state: present
regexp: '^auth required pam_faillock.so preauth'
line: "auth required pam_faillock.so preauth silent deny={{ rhel9cis_pam_faillock.attempts }}{{ (rhel9cis_pam_faillock.fail_for_root) | ternary(' even_deny_root ',' ') }}unlock_time={{ rhel9cis_pam_faillock.unlock_time }}"
insertafter: '^#?auth ?'
with_items:
- "system-auth"
- "password-auth"
when: rhel9cis_rule_5_4_2
- name: "5.4.2 | L1 | PATCH | Ensure lockout for failed password attempts is configured | Add deny count and unlock times for authfail"
lineinfile:
dest: /etc/pam.d/{{ item }}
state: present
regexp: '^auth required pam_faillock.so authfail'
line: "auth required pam_faillock.so authfail deny={{ rhel9cis_pam_faillock.attempts }}{{ (rhel9cis_pam_faillock.fail_for_root) | ternary(' even_deny_root ',' ') }}unlock_time={{ rhel9cis_pam_faillock.unlock_time }}"
insertafter: '^#?auth ?'
with_items:
- "system-auth"
- "password-auth"
when: rhel9cis_rule_5_4_2
- name: |
"5.4.3 | L1 | PATCH | Ensure password reuse is limited | Set system-auth remember remember settings
5.4.4 | L1 | PATCH | Ensure password hashing algorithm is SHA-512 | Set system-auth pwhash settings"
lineinfile:
dest: /etc/pam.d/system-auth
state: present
regexp: '^password sufficient pam_unix.so'
line: "password sufficient pam_unix.so {{ rhel9cis_pam_faillock.pwhash }} shadow try_first_pass use_authtok remember={{ rhel9cis_pam_faillock.remember }}"
insertafter: '^#?password ?'
when:
- rhel9cis_rule_5_4_3 or
rhel9cis_rule_5_4_4
- name: "5.4.4 | L1 | PATCH | Ensure password hashing algorithm is SHA-512 | Set system-auth pwhash settings"
lineinfile:
dest: /etc/pam.d/password-auth
state: present
regexp: '^password sufficient pam_unix.so'
line: "password sufficient pam_unix.so {{ rhel9cis_pam_faillock.pwhash }} shadow try_first_pass use_authtok"
insertafter: '^#?password ?'
when: rhel9cis_rule_5_4_4
# The two steps below were added to keep authconfig from overwritting the above configs. This follows steps from here: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/chap-hardening_your_system_with_tools_and_services
# With the steps below you will score five (5) points lower due to false positive results
- name: |
"5.4.1 | L1 | PATCH | Ensure password creation requirements are configured
5.4.2 | L1 | PATCH | Ensure lockout for failed password attempts is configured
5.4.3 | L1 | PATCH | Ensure password reuse is limited
5.4.4 | L1 | PATCH | Ensure password hashing algorithm is SHA-512"
copy:
src: /etc/pam.d/{{ item }}
dest: /etc/pam.d/{{ item }}-local
remote_src: true
owner: root
group: root
mode: '0644'
with_items:
- "system-auth"
- "password-auth"
- name: |
"5.4.1 | L1 | PATCH | Ensure password creation requirements are configured
5.4.2 | L1 | PATCH | Ensure lockout for failed password attempts is configured
5.4.3 | L1 | PATCH | Ensure password reuse is limited
5.4.4 | L1 | PATCH | Ensure password hashing algorithm is SHA-512"
file:
src: /etc/pam.d/{{ item }}-local
dest: /etc/pam.d/{{ item }}
state: link
force: true
with_items:
- "system-auth"
- "password-auth"
when:
- rhel9cis_rule_5_4_1 or
rhel9cis_rule_5_4_2 or
rhel9cis_rule_5_4_3 or
rhel9cis_rule_5_4_4
- rhel9cis_rule_5_4_1
tags:
- level1-server
- level1-workstation
- manual
- patch
- authselect
- rule_5.4.1
- name: "5.4.2 | PATCH | Ensure authselect includes with-faillock"
block:
- name: "5.4.2 | AUDIT | Ensure authselect includes with-faillock | Gather profiles and enabled features"
shell: "authselect current | grep with-faillock"
failed_when: false
changed_when: false
check_mode: no
register: rhel9cis_5_4_2_profiles_faillock
- name: "5.4.2 | AUDIT | Ensure authselect includes with-faillock| Show profiles"
debug:
msg:
- "Below are the current custom profiles"
- "{{ rhel9cis_5_4_2_profiles_faillock.stdout_lines }}"
- name: "5.4.2 | PATCH | Ensure authselect includes with-faillock | Create custom profiles"
shell: "authselect select custom/{{ rhel9cis_authselect['custom_profile_name'] }} with-faillock"
args:
warn: no
when: rhel9cis_authselect_custom_profile_select
when:
- rhel9cis_rule_5_4_2
tags:
- level1-server
- level1-workstation
- automated
- patch
- authselect
- rule_5.4.2
- rule_5.4.3
- rule_5.4.4

View file

@ -1,131 +0,0 @@
---
- name: "5.5.1.1 | L1 | PATCH | Ensure password expiration is 365 days or less"
lineinfile:
state: present
dest: /etc/login.defs
regexp: '^PASS_MAX_DAYS'
line: "PASS_MAX_DAYS {{ rhel9cis_pass['max_days'] }}"
when:
- rhel9cis_rule_5_5_1_1
tags:
- level1-server
- level1-workstation
- patch
- rule_5.5.1.1
- name: "5.5.1.2 | L1 | PATCH | Ensure minimum days between password changes is 7 or more"
lineinfile:
state: present
dest: /etc/login.defs
regexp: '^PASS_MIN_DAYS'
line: "PASS_MIN_DAYS {{ rhel9cis_pass['min_days'] }}"
when:
- rhel9cis_rule_5_5_1_2
tags:
- level1-server
- level1-workstation
- patch
- rule_5.5.1.2
- name: "5.5.1.3 | L1 | PATCH | Ensure password expiration warning days is 7 or more"
lineinfile:
state: present
dest: /etc/login.defs
regexp: '^PASS_WARN_AGE'
line: "PASS_WARN_AGE {{ rhel9cis_pass['warn_age'] }}"
when:
- rhel9cis_rule_5_5_1_3
tags:
- level1-server
- level1-workstation
- patch
- rule_5.5.1.3
- name: "5.5.1.4 | L1 | PATCH | Ensure inactive password lock is 30 days or less"
block:
- name: "5.5.1.4 | L1 | AUDIT | Ensure inactive password lock is 30 days or less | Check current settings"
shell: useradd -D | grep INACTIVE={{ rhel9cis_inactivelock.lock_days }} | cut -f2 -d=
args:
warn: false
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_5_5_1_4_inactive_settings
- name: "5.5.1.4 | L1 | PATCH | Ensure inactive password lock is 30 days or less | Set default inactive setting"
shell: useradd -D -f {{ rhel9cis_inactivelock.lock_days }}
args:
warn: false
when: rhel9cis_5_5_1_4_inactive_settings.stdout | length == 0
- name: "5.5.1.4 | L1 | AUDIT | Ensure inactive password lock is 30 days or less | Getting user list"
shell: 'egrep ^[^:]+:[^\!*] /etc/shadow | cut -d: -f1'
args:
warn: false
check_mode: false
register: rhel_09_5_5_1_4_audit
changed_when: false
- name: "5.5.1.4 | L1 | PATCH | Ensure inactive password lock is 30 days or less | Apply Inactive setting to existing accounts"
shell: chage --inactive {{ rhel9cis_inactivelock.lock_days }} "{{ item }}"
args:
warn: false
with_items:
- "{{ rhel_09_5_5_1_4_audit.stdout_lines }}"
when:
- rhel9cis_rule_5_5_1_4
tags:
- level1-server
- level1-workstation
- patch
- rule_5.5.1.4
- name: "5.5.1.5 | L1 | PATCH | Ensure all users last password change date is in the past"
block:
- name: "5.5.1.5 | L1 | AUDIT | Ensure all users last password change date is in the past | Get current date in Unix Time"
shell: echo $(($(date --utc --date "$1" +%s)/86400))
args:
warn: false
failed_when: false
changed_when: false
check_mode: false
register: rhel9cis_5_5_1_5_currentut
- name: "5.5.1.5 | L1 | AUDIT | Ensure all users last password change date is in the past | Get list of users with last changed pw date in the future"
shell: "cat /etc/shadow | awk -F: '{if($3>{{ rhel9cis_5_5_1_5_currentut.stdout }})print$1}'"
args:
warn: false
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_5_5_1_5_user_list
- name: "5.5.1.5 | L1 | AUDIT | Ensure all users last password change date is in the past | Alert no pw change in the future exist"
debug:
msg: "Good News! All accounts have PW change dates that are in the past"
when: rhel9cis_5_5_1_5_user_list.stdout | length == 0
- name: "5.5.1.5 | L1 | AUDIT | Ensure all users last password change date is in the past | Alert on accounts with pw change in the future"
debug:
msg: "Warning! The following accounts have the last PW change date in the future: {{ rhel9cis_5_5_1_5_user_list.stdout_lines }}"
when:
- rhel9cis_5_5_1_5_user_list.stdout | length > 0
- not rhel9cis_futurepwchgdate_autofix
- name: "5.5.1.5 | L1 | PATCH | Ensure all users last password change date is in the past | Fix accounts with pw change in the future"
shell: passwd --expire {{ item }}
args:
warn: false
when:
- rhel9cis_5_5_1_5_user_list | length > 0
- rhel9cis_futurepwchgdate_autofix
with_items:
- "{{ rhel9cis_5_5_1_5_user_list.stdout_lines }}"
when:
- rhel9cis_rule_5_5_1_5
tags:
- level1-server
- level1-workstation
- patch
- rule_5.5.1.5

View file

@ -1,8 +1,8 @@
---
- name: "5.5.2 | L1 | PATCH | Ensure system accounts are secured"
- name: "5.5.2 | PATCH | Ensure system accounts are secured"
block:
- name: "5.5.2 | L1 | Ensure system accounts are secured | Set nologin"
- name: "5.5.2 | Ensure system accounts are secured | Set nologin"
user:
name: "{{ item.id }}"
shell: /usr/sbin/nologin
@ -13,11 +13,11 @@
- item.id != "sync"
- item.id != "shutdown"
- item.id != "halt"
- item.uid < 1000
- rhel9cis_int_gid | int > item.gid
- item.shell != " /bin/false"
- item.shell != " /usr/sbin/nologin"
- name: "5.5.2 | L1 | PATCH | Ensure system accounts are secured | Lock accounts"
- name: "5.5.2 | PATCH | Ensure system accounts are secured | Lock accounts"
user:
name: "{{ item.id }}"
password_lock: true
@ -28,7 +28,7 @@
- item.id != "shutdown"
- item.id != "sync"
- item.id != "root"
- min_int_uid | int >= item.uid
- rhel9cis_int_gid | int > item.gid
- item.shell != " /bin/false"
- item.shell != " /usr/sbin/nologin"
when:
@ -39,15 +39,15 @@
- patch
- rule_5.5.2
- name: "5.5.3 | L1 | PATCH | Ensure default user shell timeout is 900 seconds or less"
- name: "5.5.3 | PATCH | Ensure default user shell timeout is 900 seconds or less"
blockinfile:
create: true
create: yes
mode: 0644
dest: "{{ item.dest }}"
state: "{{ item.state }}"
marker: "# {mark} ANSIBLE MANAGED"
block: |
# Set session timeout - CIS ID RHEL-09-5.4.5
# Set session timeout - CIS ID RHEL-08-5.4.5
TMOUT={{ rhel9cis_shell_session_timeout.timeout }}
export TMOUT
readonly TMOUT
@ -62,10 +62,8 @@
- patch
- rule_5.5.3
- name: "5.5.4 | L1 | PATCH | Ensure default group for the root account is GID 0"
shell: usermod -g 0 root
args:
warn: false
- name: "5.5.4 | PATCH | Ensure default group for the root account is GID 0"
command: usermod -g 0 root
changed_when: false
failed_when: false
when:
@ -76,15 +74,15 @@
- patch
- rule_5.5.4
- name: "5.5.5 | L1 | PATCH | Ensure default user umask is 027 or more restrictive"
- name: "5.5.5 | PATCH | Ensure default user umask is 027 or more restrictive"
block:
- name: "5.5.5 | L1 | PATCH | Ensure default user umask is 027 or more restrictive | Set umask for /etc/bashrc"
- name: "5.5.5 | PATCH | Ensure default user umask is 027 or more restrictive | Set umask for /etc/bashrc"
replace:
path: /etc/bashrc
regexp: '(^\s+umask) 0[012][0-6]'
replace: '\1 027'
- name: "5.5.5 | L1 | PATCH | Ensure default user umask is 027 or more restrictive | Set umask for /etc/profile"
- name: "5.5.5 | PATCH | Ensure default user umask is 027 or more restrictive | Set umask for /etc/profile"
replace:
path: /etc/profile
regexp: '(^\s+umask) 0[012][0-6]'

View file

@ -0,0 +1,125 @@
---
- name: "5.6.1.1 | PATCH | Ensure password expiration is 365 days or less"
lineinfile:
state: present
dest: /etc/login.defs
regexp: '^PASS_MAX_DAYS'
line: "PASS_MAX_DAYS {{ rhel9cis_pass['max_days'] }}"
when:
- rhel9cis_rule_5_6_1_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- password
- rule_5.5.1.1
- name: "5.6.1.2 | PATCH | Ensure minimum days between password changes is 7 or more"
lineinfile:
state: present
dest: /etc/login.defs
regexp: '^PASS_MIN_DAYS'
line: "PASS_MIN_DAYS {{ rhel9cis_pass['min_days'] }}"
when:
- rhel9cis_rule_5_6_1_2
tags:
- level1-server
- level1-workstation
- automated
- patch
- password
- rule_5.6.1.2
- name: "5.6.1.3 | PATCH | Ensure password expiration warning days is 7 or more"
lineinfile:
state: present
dest: /etc/login.defs
regexp: '^PASS_WARN_AGE'
line: "PASS_WARN_AGE {{ rhel9cis_pass['warn_age'] }}"
when:
- rhel9cis_rule_5_6_1_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- password
- rule_5.5.1.3
- name: "5.6.1.4 | PATCH | Ensure inactive password lock is 30 days or less"
block:
- name: "5.6.1.4 | AUDIT | Ensure inactive password lock is 30 days or less | Check current settings"
shell: useradd -D | grep INACTIVE={{ rhel9cis_inactivelock.lock_days }} | cut -f2 -d=
changed_when: false
failed_when: false
check_mode: no
register: rhel9cis_5_6_1_4_inactive_settings
- name: "5.6.1.4 | PATCH | Ensure inactive password lock is 30 days or less | Set default inactive setting"
command: useradd -D -f {{ rhel9cis_inactivelock.lock_days }}
when: rhel9cis_5_6_1_4_inactive_settings.stdout | length == 0
- name: "5.6.1.4 | AUDIT | Ensure inactive password lock is 30 days or less | Getting user list"
shell: 'egrep ^[^:]+:[^\!*] /etc/shadow | cut -d: -f1'
changed_when: false
check_mode: no
register: rhel_8_5_6_1_4_user_list
- name: "5.6.1.4 | PATCH | Ensure inactive password lock is 30 days or less | Apply Inactive setting to existing accounts"
command: chage --inactive {{ rhel9cis_inactivelock.lock_days }} "{{ item }}"
with_items:
- "{{ rhel_8_5_6_1_4_user_list.stdout_lines }}"
when:
- rhel9cis_rule_5_6_1_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- password
- rule_5.6.1.4
- name: "5.6.1.5 | PATCH | Ensure all users last password change date is in the past"
block:
- name: "5.6.1.5 | AUDIT | Ensure all users last password change date is in the past | Get current date in Unix Time"
shell: echo $(($(date --utc --date "$1" +%s)/86400))
changed_when: false
failed_when: false
check_mode: no
register: rhel9cis_5_6_1_5_currentut
- name: "5.6.1.5 | AUDIT | Ensure all users last password change date is in the past | Get list of users with last changed pw date in the future"
shell: "cat /etc/shadow | awk -F: '{if($3>{{ rhel9cis_5_6_1_5_currentut.stdout }})print$1}'"
changed_when: false
failed_when: false
check_mode: no
register: rhel9cis_5_6_1_5_user_list
- name: "5.6.1.5 | AUDIT | Ensure all users last password change date is in the past | Alert no pw change in the future exist"
debug:
msg: "Good News! All accounts have PW change dates that are in the past"
when: rhel9cis_5_6_1_5_user_list.stdout | length == 0
- name: "5.6.1.5 | AUDIT | Ensure all users last password change date is in the past | Alert on accounts with pw change in the future"
debug:
msg: "Warning! The following accounts have the last PW change date in the future: {{ rhel9cis_5_6_1_5_user_list.stdout_lines }}"
when:
- rhel9cis_5_6_1_5_user_list.stdout | length > 0
- not rhel9cis_futurepwchgdate_autofix
- name: "5.6.1.5 | PATCH | Ensure all users last password change date is in the past | Fix accounts with pw change in the future"
command: passwd --expire {{ item }}
when:
- rhel9cis_5_6_1_5_user_list | length > 0
- rhel9cis_futurepwchgdate_autofix
with_items:
- "{{ rhel9cis_5_6_1_5_user_list.stdout_lines }}"
when:
- rhel9cis_rule_5_6_1_5
tags:
- level1-server
- level1-workstation
- patch
- rule_5.5.1.5

View file

@ -0,0 +1,108 @@
---
- name: "5.6.2 | PATCH | Ensure system accounts are secured"
block:
- name: "5.6.2 | Ensure system accounts are secured | Set nologin"
user:
name: "{{ item.id }}"
shell: /usr/sbin/nologin
with_items:
- "{{ rhel9cis_passwd }}"
when:
- item.id != "root"
- item.id != "sync"
- item.id != "shutdown"
- item.id != "halt"
- rhel9cis_int_gid | int < item.gid
- item.shell != " /bin/false"
- item.shell != " /usr/sbin/nologin"
loop_control:
label: "{{ item.id }}"
- name: "5.6.2 | PATCH | Ensure system accounts are secured | Lock accounts"
user:
name: "{{ item.id }}"
password_lock: true
with_items:
- "{{ rhel9cis_passwd }}"
when:
- item.id != "halt"
- item.id != "shutdown"
- item.id != "sync"
- item.id != "root"
- rhel9cis_int_gid | int < item.gid
- item.shell != " /bin/false"
- item.shell != " /usr/sbin/nologin"
loop_control:
label: "{{ item.id }}"
when:
- rhel9cis_rule_5_6_2
tags:
- level1-server
- level1-workstation
- automated
- patch
- accounts
- rule_5.6.2
- name: "5.6.3 | PATCH | Ensure default user shell timeout is 900 seconds or less"
blockinfile:
create: yes
mode: 0644
dest: "{{ item.dest }}"
state: "{{ item.state }}"
marker: "# {mark} ANSIBLE MANAGED"
block: |
# Set session timeout - CIS ID RHEL-08-5.4.5
TMOUT={{ rhel9cis_shell_session_timeout.timeout }}
export TMOUT
readonly TMOUT
with_items:
- { dest: "{{ rhel9cis_shell_session_timeout.file }}", state: present }
- { dest: /etc/profile, state: "{{ (rhel9cis_shell_session_timeout.file == '/etc/profile') | ternary('present', 'absent') }}" }
when:
- rhel9cis_rule_5_6_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- accounts
- rule_5.6.3
- name: "5.6.4 | PATCH | Ensure default group for the root account is GID 0"
command: usermod -g 0 root
changed_when: false
failed_when: false
when:
- rhel9cis_rule_5_6_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- accounts
- rule_5.6.4
- name: "5.6.5 | PATCH | Ensure default user umask is 027 or more restrictive"
block:
- name: "5.6.5 | PATCH | Ensure default user umask is 027 or more restrictive | Set umask for /etc/bashrc"
replace:
path: /etc/bashrc
regexp: '(^\s+umask) 0[012][0-6]'
replace: '\1 027'
- name: "5.6.5 | PATCH | Ensure default user umask is 027 or more restrictive | Set umask for /etc/profile"
replace:
path: /etc/profile
regexp: '(^\s+umask) 0[012][0-6]'
replace: '\1 027'
when:
- rhel9cis_rule_5_6_5
tags:
- level1-server
- level1-workstation
- automated
- patch
- accounts
- rule_5.6.5

View file

@ -1,37 +0,0 @@
---
# this will just display the list of consoles. The site will need to confirm the allowed consoles are correct and change manually if needed.
- name: "5.6 | L1 | AUDIT | Ensure root login is restricted to system console"
block:
- name: "5.6 | L1 | AUDIT | Ensure root login is restricted to system console | Check if securetty file exists"
stat:
path: /etc/securetty
register: rhel9cis_securetty_check
- name: "5.6 | L1 | AUDIT | Ensure root login is restricted to system console | Capture consoles"
shell: cat /etc/securetty
args:
warn: false
changed_when: false
register: rhel_09_5_6_audit
when: rhel9cis_securetty_check.stat.exists
- name: "5.6 | L1 | AUDIT |Ensure root login is restricted to system console | Display Console"
debug:
msg:
- "These are the consoles with root login access, please review:"
- "{{ rhel_09_5_6_audit.stdout_lines }}"
when: rhel9cis_securetty_check.stat.exists
- name: "5.6 | L1 | AUDIT | Ensure root login is restricted to system console | Display that no securetty file exists"
debug:
msg:
- "There is no /etc/securetty file, this has been removed by default in RHEL9"
when: not rhel9cis_securetty_check.stat.exists
when:
- rhel9cis_rule_5_6
tags:
- level1-server
- level1-workstation
- audit
- rule_5.6

View file

@ -1,22 +0,0 @@
---
- name: "5.7 | L1 | PATCH | Ensure access to the su command is restricted"
block:
- name: "5.7 | L1 | PATCH | Ensure access to the su command is restricted | Setting pam_wheel to use_uid"
lineinfile:
state: present
dest: /etc/pam.d/su
regexp: '^(#)?auth\s+required\s+pam_wheel\.so'
line: 'auth required pam_wheel.so use_uid {% if rhel9cis_sugroup is defined %}group={{ rhel9cis_sugroup }}{% endif %}'
- name: "5.7 | L1 | PATCH | Ensure access to the su command is restricted | wheel group contains root"
user:
name: "{{ rhel9cis_sugroup_users }}"
groups: "{{ rhel9cis_sugroup | default('wheel') }}"
when:
- rhel9cis_rule_5_7
tags:
- level1-server
- level1-workstation
- patch
- rule_5.7

View file

@ -1,5 +1,7 @@
---
# Access, Authentication, and Authorization
- name: "SECTION | 5.1 | Configure time-based job schedulers"
import_tasks: cis_5.1.x.yml
@ -8,22 +10,17 @@
when:
- "'openssh-server' in ansible_facts.packages"
- name: "SECTION | 5.3 | Configure Profiles"
- name: "SECTION | 5.3 | Configure privilege escalation"
include_tasks: cis_5.3.x.yml
when:
- rhel9cis_use_authconfig
- name: "SECTION | 5.4 | Configure PAM "
- name: "SECTION | 5.4 | Configure authselect"
import_tasks: cis_5.4.x.yml
- name: "SECTION | 5.5.1.x | Passwords and Accounts"
import_tasks: cis_5.5.1.x.yml
- name: "SECTION | 5.5.x | System Accounts and User Settings"
- name: "SECTION | 5.5 | Configure PAM "
import_tasks: cis_5.5.x.yml
- name: "SECTION | 5.6 | Root Login"
import_tasks: cis_5.6.yml
- name: "SECTION | 5.6.1.x | Shadow Password Suite Parameters"
import_tasks: cis_5.6.1.x.yml
- name: Section | 5.7 | su Command Restriction
import_tasks: cis_5.7.yml
- name: "SECTION | 5.6.x | Misc. User Account Settings"
import_tasks: cis_5.6.x.yml

View file

@ -1,30 +1,30 @@
---
- name: "6.1.1 | L2 | AUDIT | Audit system file permissions"
- name: "6.1.1 | AUDIT | Audit system file permissions"
block:
- name: "6.1.1 | L2 | AUDIT | Audit system file permissions | Audit the packages"
- name: "6.1.1 | AUDIT | Audit system file permissions | Audit the packages"
shell: rpm -Va --nomtime --nosize --nomd5 --nolinkto
args:
warn: false
warn: no
changed_when: false
failed_when: false
register: rhel9cis_6_1_1_packages_rpm
- name: "6.1.1 | L2 | AUDIT | Audit system file permissions | Create list and warning"
- name: "6.1.1 | AUDIT | Audit system file permissions | Create list and warning"
block:
- name: "6.1.1 | L2 | Audit system file permissions | Add file discrepancy list to system"
- name: "6.1.1 | Audit system file permissions | Add file discrepancy list to system"
copy:
dest: "{{ rhel9cis_rpm_audit_file }}"
content: "{{ rhel9cis_6_1_1_packages_rpm.stdout }}"
- name: "6.1.1 | L2 | AUDIT | Audit system file permissions | Message out alert for package descrepancies"
- name: "6.1.1 | AUDIT | Audit system file permissions | Message out alert for package descrepancies"
debug:
msg: |
"Warning! You have some package descrepancies issues.
The file list can be found in {{ rhel9cis_rpm_audit_file }}"
when: rhel9cis_6_1_1_packages_rpm.stdout|length > 0
- name: "6.1.1 | L2 | AUDIT | Audit system file permissions | Message out no package descrepancies"
- name: "6.1.1 | AUDIT | Audit system file permissions | Message out no package descrepancies"
debug:
msg: "Good News! There are no package descrepancies"
when: rhel9cis_6_1_1_packages_rpm.stdout|length == 0
@ -33,26 +33,32 @@
tags:
- level2-server
- level2-workstation
- manual
- audit
- permissions
- rule_6.1.1
- name: "6.1.2 | L1 | PATCH | Ensure permissions on /etc/passwd are configured"
file:
dest: /etc/passwd
owner: root
group: root
mode: 0644
- name: "6.1.2 | PATCH | Ensure sticky bit is set on all world-writable directories"
shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type d -perm -0002 2>/dev/null | xargs chmod a+t
args:
warn: no
changed_when: false
failed_when: false
when:
- rhel9cis_rule_6_1_2
tags:
- skip_ansible_lint
- level1-server
- level1-workstation
- automated
- patch
- rule_6.1.2
- stickybits
- permissons
- rule_1.1.21
- name: "6.1.3 | L1 | PATCH | Ensure permissions on /etc/passwd- are configured"
- name: "6.1.3 | PATCH | Ensure permissions on /etc/passwd are configured"
file:
dest: /etc/passwd-
dest: /etc/passwd
owner: root
group: root
mode: 0644
@ -61,10 +67,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- rule_6.1.3
- name: "6.1.4 | L1 | PATCH | Ensure permissions on /etc/shadow are configured"
- name: "6.1.4 | PATCH | Ensure permissions on /etc/shadow are configured"
file:
dest: /etc/shadow
owner: root
@ -75,24 +83,28 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- rule_6.1.4
- name: "6.1.5 | L1 | PATCH | Ensure permissions on /etc/shadow- are configured"
- name: "6.1.5 | PATCH | Ensure permissions on /etc/group are configured"
file:
dest: /etc/shadow-
dest: /etc/group-
owner: root
group: root
mode: 0000
mode: 0644
when:
- rhel9cis_rule_6_1_5
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- rule_6.1.5
- name: "6.1.6 | L1 | PATCH | Ensure permissions on /etc/gshadow are configured"
- name: "6.1.6 | PATCH | Ensure permissions on /etc/gshadow are configured"
file:
dest: /etc/gshadow
owner: root
@ -103,38 +115,44 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- rule_6.1.6
- name: "6.1.7 | L1 | PATCH | Ensure permissions on /etc/gshadow- are configured"
- name: "6.1.7 | PATCH | Ensure permissions on /etc/passwd- are configured"
file:
dest: /etc/gshadow-
dest: /etc/passwd-
owner: root
group: root
mode: 0000
mode: 0644
when:
- rhel9cis_rule_6_1_7
tags:
- level1-server
- level1-workstation
- autoamted
- patch
- permissions
- rule_6.1.7
- name: "6.1.8 | L1 | PATCH | Ensure permissions on /etc/group are configured"
- name: "6.1.6 | PATCH | Ensure permissions on /etc/shadow- are configured"
file:
dest: /etc/group-
dest: /etc/shadow-
owner: root
group: root
mode: 0644
mode: 0000
when:
- rhel9cis_rule_6_1_8
- rhel9cis_rule_6_1_6
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_6.1.8
- permissions
- rule_6.1.6
- name: "6.1.9 | L1 | PATCH | Ensure permissions on /etc/group- are configured"
- name: "6.1.9 | PATCH | Ensure permissions on /etc/group- are configured"
file:
dest: /etc/group-
owner: root
@ -145,87 +163,78 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissionss
- rule_6.1.9
- name: "6.1.10 | L1 | PATCH | Ensure no world writable files exist"
block:
- name: "6.1.10 | L1 | AUDIT | Ensure no world writable files exist | Get list of world-writable files"
shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -0002
args:
warn: false
failed_when: false
changed_when: false
register: rhel_09_6_1_10_perms_results
- name: "6.1.10 | L1 | AUDIT | Ensure no world writable files exist | Alert no world-writable files exist"
debug:
msg: "Good news! We have not found any world-writable files on your system"
when:
- rhel_09_6_1_10_perms_results.stdout is not defined
- name: "6.1.10 | L1 | PATCH | Ensure no world writable files exist | Adjust world-writable files if they exist (Configurable)"
- name: "6.1.10 | PATCH | Ensure permissions on /etc/gshadow- are configured"
file:
path: '{{ item }}'
mode: o-w
state: touch
with_items: "{{ rhel_09_6_1_10_perms_results.stdout_lines }}"
when:
- rhel_09_6_1_10_perms_results.stdout_lines is defined
- rhel9cis_no_world_write_adjust
dest: /etc/gshadow-
owner: root
group: root
mode: 0000
when:
- rhel9cis_rule_6_1_10
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- rule_6.1.10
- name: "6.1.11 | L1 | AUDIT | Ensure no unowned files or directories exist"
- name: "6.1.11 | PATCH | Ensure no world writable files exist"
block:
- name: "6.1.11 | L1 | AUDIT | Ensure no unowned files or directories exist | Finding all unowned files or directories"
shell: find "{{ item.mount }}" -xdev -nouser
args:
warn: false
check_mode: false
- name: "6.1.11 | AUDIT | Ensure no world writable files exist | Get list of world-writable files"
shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -0002
failed_when: false
changed_when: false
with_items: "{{ ansible_mounts }}"
register: rhel_09_6_1_11_audit
when: item['device'].startswith('/dev') and not 'bind' in item['options']
register: rhel_08_6_1_11_perms_results
- name: "6.1.11 | L1 | AUDIT | Ensure no unowned files or directories exist | Displaying any unowned files or directories"
- name: "6.1.11 | AUDIT | Ensure no world writable files exist | Alert no world-writable files exist"
debug:
msg: "Manual intervention is required -- missing owner on items in {{ item.item.mount }}: {{ item.stdout_lines | join(', ') }}"
with_items: "{{ rhel_09_6_1_11_audit.results }}"
msg: "Good news! We have not found any world-writable files on your system"
when:
- item.stdout_lines is defined
- item.stdout_lines | length > 0
- rhel_08_6_1_11_perms_results.stdout is not defined
- name: "6.1.11 | PATCH | Ensure no world writable files exist | Adjust world-writable files if they exist (Configurable)"
file:
path: '{{ item }}'
mode: o-w
state: touch
with_items: "{{ rhel_08_6_1_11_perms_results.stdout_lines }}"
when:
- rhel_08_6_1_11_perms_results.stdout_lines is defined
- rhel9cis_no_world_write_adjust
when:
- rhel9cis_rule_6_1_11
tags:
- level1-server
- level1-workstation
- audit
- automated
- patch
- files
- permissions
- rule_6.1.11
- name: "6.1.12 | L1 | AUDIT | Ensure no ungrouped files or directories exist"
- name: "6.1.12 | AUDIT | Ensure no unowned files or directories exist"
block:
- name: "6.1.12 | L1 | AUDIT | Ensure no ungrouped files or directories exist | Finding all ungrouped files or directories"
shell: find "{{ item.mount }}" -xdev -nogroup
args:
warn: false
check_mode: false
failed_when: false
- name: "6.1.12 | AUDIT | Ensure no unowned files or directories exist | Finding all unowned files or directories"
command: find "{{ item.mount }}" -xdev -nouser
changed_when: false
register: rhel_09_6_1_12_audit
failed_when: false
check_mode: false
register: rhel_08_6_1_12_audit
with_items: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.mount }}"
when: item['device'].startswith('/dev') and not 'bind' in item['options']
- name: "6.1.12 | L1 | AUDIT | Ensure no ungrouped files or directories exist | Displaying all ungrouped files or directories"
- name: "6.1.12 | AUDIT | Ensure no unowned files or directories exist | Displaying any unowned files or directories"
debug:
msg: "Manual intervention is required -- missing group on items in {{ item.item.mount }}: {{ item.stdout_lines | join(', ') }}"
with_items: "{{ rhel_09_6_1_12_audit.results }}"
msg: "Manual intervention is required -- missing owner on items in {{ item.item.mount }}: {{ item.stdout_lines | join(', ') }}"
with_items: "{{ rhel_08_6_1_12_audit.results }}"
when:
- item.stdout_lines is defined
- item.stdout_lines | length > 0
@ -234,71 +243,109 @@
tags:
- level1-server
- level1-workstation
- patch
- automated
- audit
- files
- permissions
- rule_6.1.12
- name: "6.1.13 | L1 | AUDIT | Audit SUID executables"
- name: "6.1.13 | AUDIT | Ensure no ungrouped files or directories exist"
block:
- name: "6.1.13 | L1 | AUDIT | Audit SUID executables | Find all SUID executables"
shell: df {{ item.mount }} -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -4000
args:
warn: false
- name: "6.1.13 | AUDIT | Ensure no ungrouped files or directories exist | Finding all ungrouped files or directories"
command: find "{{ item.mount }}" -xdev -nogroup
check_mode: false
failed_when: false
changed_when: false
register: rhel_09_6_1_13_perms_results
register: rhel_08_6_1_13_audit
with_items: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.mount }}"
when: item['device'].startswith('/dev') and not 'bind' in item['options']
- name: "6.1.13 | L1 | AUDIT | Audit SUID executables | Alert no SUID executables exist"
- name: "6.1.13 | AUDIT | Ensure no ungrouped files or directories exist | Displaying all ungrouped files or directories"
debug:
msg: "Good news! We have not found any SUID executable files on your system"
failed_when: false
changed_when: false
msg: "Manual intervention is required -- missing group on items in {{ item.item.mount }}: {{ item.stdout_lines | join(', ') }}"
with_items: "{{ rhel_08_6_1_13_audit.results }}"
when:
- rhel_09_6_1_13_perms_results.stdout is not defined
- name: "6.1.13 | L1 | AUDIT | Audit SUID executables | Alert SUID executables exist"
debug:
msg: "Manual intervention is required -- SUID set on items in {{ item.item.mount }}: {{ item.stout_lines | join(', ') }}"
with_items: "{{ rhel_09_6_1_13_perms_results.stdout_lines }}"
when:
- rhel_09_6_1_13_perms_results.stdout is defined
- item.stdout_lines is defined
- item.stdout_lines | length > 0
when:
- rhel9cis_rule_6_1_13
tags:
- level1-server
- level1-workstation
- automated
- audit
- files
- permissions
- rule_6.1.13
- name: "6.1.14 | L1 | AUDIT | Audit SGID executables"
- name: "6.1.14 | AUDIT | Audit SUID executables"
block:
- name: "6.1.14 | L1 | AUDIT | Audit SGID executables | Find all SGID executables"
shell: df {{ item.mount }} -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -2000
args:
warn: false
- name: "6.1.14 | AUDIT | Audit SUID executables | Find all SUID executables"
shell: df {{ item.mount }} -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -4000
failed_when: false
changed_when: false
register: rhel_09_6_1_14_perms_results
register: rhel_08_6_1_14_perms_results
with_items: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.mount }}"
- name: "6.1.14 | L1 | AUDIT | Audit SGID executables | Alert no SGID executables exist"
- name: "6.1.14 | AUDIT | Audit SUID executables | Alert no SUID executables exist"
debug:
msg: "Good news! We have not found any SGID executable files on your system"
msg: "Good news! We have not found any SUID executable files on your system"
failed_when: false
changed_when: false
when:
- rhel_09_6_1_14_perms_results.stdout is not defined
- rhel_08_6_1_14_perms_results.stdout is not defined
- name: "6.1.14 | L1 | AUDIT | Audit SGID executables | Alert SGID executables exist"
- name: "6.1.14 | AUDIT | Audit SUID executables | Alert SUID executables exist"
debug:
msg: "Manual intervention is required -- SGID set on items in {{ item.item.mount }}: {{ item.stout_lines | join(', ') }}"
with_items: "{{ rhel_09_6_1_14_perms_results.stdout_lines }}"
msg: "Manual intervention is required -- SUID set on items in {{ item.item.mount }}: {{ item.stout_lines | join(', ') }}"
with_items: "{{ rhel_08_6_1_14_perms_results.stdout_lines }}"
when:
- rhel_09_6_1_14_perms_results.stdout is defined
- rhel_08_6_1_14_perms_results.stdout is defined
when:
- rhel9cis_rule_6_1_14
tags:
- level1-server
- level1-workstation
- patch
- manual
- audit
- files
- rule_6.1.14
- name: "6.1.15 | AUDIT | Audit SGID executables"
block:
- name: "6.1.15 | AUDIT | Audit SGID executables | Find all SGID executables"
shell: df {{ item.mount }} -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -2000
failed_when: false
changed_when: false
register: rhel_08_6_1_15_perms_results
with_items: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.mount }}"
- name: "6.1.15 | AUDIT | Audit SGID executables | Alert no SGID executables exist"
debug:
msg: "Good news! We have not found any SGID executable files on your system"
failed_when: false
changed_when: false
when:
- rhel_08_6_1_15_perms_results.stdout is not defined
- name: "6.1.15 | AUDIT | Audit SGID executables | Alert SGID executables exist"
debug:
msg: "Manual intervention is required -- SGID set on items in {{ item.item.mount }}: {{ item.stout_lines | join(', ') }}"
with_items: "{{ rhel_08_6_1_15_perms_results.stdout_lines }}"
when:
- rhel_08_6_1_15_perms_results.stdout is defined
when:
- rhel9cis_rule_6_1_15
tags:
- level1-server
- level1-workstation
- manual
- audit
- files
- rule_6.1.15

View file

@ -1,9 +1,7 @@
---
- name: "6.2.1 | L1 | AUDIT | Ensure password fields are not empty"
shell: passwd -l {{ item }}
args:
warn: false
- name: "6.2.1 | PATCH | Ensure password fields are not empty"
command: passwd -l {{ item }}
changed_when: false
failed_when: false
with_items: "{{ empty_password_accounts.stdout_lines }}"
@ -13,177 +11,268 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- accounts
- rule_6.2.1
- name: "6.2.2 | L1 | PATCH | Ensure no legacy '+' entries exist in /etc/passwd"
shell: sed -i '/^+/ d' /etc/passwd
args:
warn: false
- name: "6.2.2 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group"
block:
- name: "6.2.2 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Check /etc/passwd entries"
shell: pwck -r | grep 'no group' | awk '{ gsub("[:\47]",""); print $2}'
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_6_2_2_passwd_gid_check
- name: "6.2.2 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Print message that all groups match between passwd and group files"
debug:
msg: "Good News! There are no users that have non-existent GUIDs (Groups)"
when: rhel9cis_6_2_2_passwd_gid_check.stdout is not defined
- name: "6.2.2 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Print warning about users with invalid GIDs missing GID entries in /etc/group"
debug:
msg: "WARNING: The following users have non-existent GIDs (Groups): {{ rhel9cis_6_2_2_passwd_gid_check.stdout_lines | join (', ') }}"
when: rhel9cis_6_2_2_passwd_gid_check.stdout is defined
when:
- rhel9cis_rule_6_2_2
tags:
- level1-server
- level1-workstation
- patch
- automated
- audit
- accounts
- groups
- rule_6.2.2
- skip_ansible_lint
- name: "6.2.3 | L1 | PATCH | Ensure root PATH Integrity"
- name: "6.2.3 | AUDIT Ensure no duplicate UIDs exist"
block:
- name: "6.2.3 | L1 | AUDIT | Ensure root PATH Integrity | Determine empty value"
- name: "6.2.3 | AUDIT | Ensure no duplicate UIDs exist | Check for duplicate UIDs"
shell: "pwck -r | awk -F: '{if ($3 in uid) print $1 ; else uid[$3]}' /etc/passwd"
changed_when: false
failed_when: false
register: rhel9cis_6_2_3_user_uid_check
- name: "6.2.3 | AUDIT | Ensure no duplicate UIDs exist | Print message that no duplicate UIDs exist"
debug:
msg: "Good News! There are no duplicate UID's in the system"
when: rhel9cis_6_2_3_user_uid_check.stdout is not defined
- name: "6.2.3 | AUDIT| Ensure no duplicate UIDs exist | Print warning about users with duplicate UIDs"
debug:
msg: "Warning: The following users have UIDs that are duplicates: {{ rhel9cis_6_2_3_user_uid_check.stdout_lines }}"
when: rhel9cis_6_2_3_user_uid_check.stdout is defined
when:
- rhel9cis_rule_6_2_3
tags:
- level1-server
- level1-workstation
- automated
- audit
- accounts
- users
- rule_6.2.3
- name: "6.2.4 | AUDIT | Ensure no duplicate GIDs exist"
block:
- name: "6.2.4 | AUDIT | Ensure no duplicate GIDs exist | Check for duplicate GIDs"
shell: "pwck -r | awk -F: '{if ($3 in users) print $1 ; else users[$3]}' /etc/group"
changed_when: false
failed_when: false
register: rhel9cis_6_2_4_user_user_check
- name: "6.2.4 | AUDIT | Ensure no duplicate GIDs exist | Print message that no duplicate GID's exist"
debug:
msg: "Good News! There are no duplicate GIDs in the system"
when: rhel9cis_6_2_4_user_user_check.stdout is not defined
- name: "6.2.4 | AUDIT | Ensure no duplicate GIDs exist | Print warning about users with duplicate GIDs"
debug:
msg: "Warning: The following groups have duplicate GIDs: {{ rhel9cis_6_2_4_user_user_check.stdout_lines }}"
when: rhel9cis_6_2_4_user_user_check.stdout is defined
when:
- rhel9cis_rule_6_2_4
tags:
- level1-server
- level1-workstation
- automated
- audit
- accounts
- groups
- rule_6.2.4
- name: "6.2.5 | AUDIT | Ensure no duplicate user names exist"
block:
- name: "6.2.5 | AUDIT | Ensure no duplicate user names exist | Check for duplicate User Names"
shell: "pwck -r | awk -F: '{if ($1 in users) print $1 ; else users[$1]}' /etc/passwd"
changed_when: false
failed_when: false
register: rhel9cis_6_2_5_user_username_check
- name: "6.2.5 | AUDIT | Ensure no duplicate user names exist | Print message that no duplicate user names exist"
debug:
msg: "Good News! There are no duplicate user names in the system"
when: rhel9cis_6_2_5_user_username_check.stdout is not defined
- name: "6.2.5 | AUDIT | Ensure no duplicate user names exist | Print warning about users with duplicate User Names"
debug:
msg: "Warning: The following user names are duplicates: {{ rhel9cis_6_2_5_user_username_check.stdout_lines }}"
when: rhel9cis_6_2_5_user_username_check.stdout is defined
when:
- rhel9cis_rule_6_2_5
tags:
- level1-server
- level1-workstation
- automated
- audit
- accounts
- users
- rule_6.2.5
- name: "6.2.6 | AUDIT |Ensure no duplicate group names exist"
block:
- name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | Check for duplicate group names"
shell: 'getent passwd | cut -d: -f1 | sort -n | uniq -d'
changed_when: false
failed_when: false
check_mode: no
register: rhel9cis_6_2_6_group_group_check
- name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | Print message that no duplicate groups exist"
debug:
msg: "Good News! There are no duplicate group names in the system"
when: rhel9cis_6_2_6_group_group_check.stdout is defined
- name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names"
debug:
msg: "Warning: The following group names are duplicates: {{ rhel9cis_6_2_6_group_group_check.stdout_lines }}"
when: rhel9cis_6_2_6_group_group_check.stdout is not defined
when:
- rhel9cis_rule_6_2_6
tags:
- level1-server
- level1-workstation
- automated
- audit
- accounts
- groups
- rule_6.2.6
- name: "6.2.7 | PATCH | Ensure root PATH Integrity"
block:
- name: "6.2.7 | AUDIT | Ensure root PATH Integrity | Determine empty value"
shell: 'echo $PATH | grep ::'
args:
warn: false
check_mode: false
register: path_colon
changed_when: False
failed_when: path_colon.rc == 0
failed_when: rhel9cis_6_2_7_path_colon.rc == 0
check_mode: no
register: rhel9cis_6_2_7_path_colon
- name: "6.2.3 | L1 | AUDIT | Ensure root PATH Integrity | Determin colon end"
- name: "6.2.7 | AUDIT | Ensure root PATH Integrity | Determin colon end"
shell: 'echo $PATH | grep :$'
args:
warn: false
check_mode: false
register: path_colon_end
changed_when: False
failed_when: path_colon_end.rc == 0
failed_when: rhel9cis_6_2_7_path_colon_end.rc == 0
check_mode: no
register: rhel9cis_6_2_7_path_colon_end
- name: "6.2.3 | L1 | AUDIT | Ensure root PATH Integrity | Determine dot in path"
- name: "6.2.7 | AUDIT | Ensure root PATH Integrity | Determine dot in path"
shell: "/bin/bash --login -c 'env | grep ^PATH=' | sed -e 's/PATH=//' -e 's/::/:/' -e 's/:$//' -e 's/:/\\n/g'"
args:
warn: false
check_mode: false
register: dot_in_path
changed_when: False
failed_when: '"." in dot_in_path.stdout_lines'
failed_when: '"." in rhel9cis_6_2_7_dot_in_path.stdout_lines'
check_mode: no
register: rhel9cis_6_2_7_dot_in_path
- name: "6.2.3 | L1 | AUDIT | Ensure root PATH Integrity | Alert on empty value, colon end, and dot in path"
- name: "6.2.7 | AUDIT | Ensure root PATH Integrity | Alert on empty value, colon end, and dot in path"
debug:
msg:
- "The following paths have an empty value: {{ path_colon.stdout_lines }}"
- "The following paths have colon end: {{ path_colon_end.stdout_lines }}"
- "The following paths have a dot in the path: {{ dot_in_path.stdout_lines }}"
- "The following paths have an empty value: {{ rhel9cis_6_2_7_path_colon.stdout_lines }}"
- "The following paths have colon end: {{ rhel9cis_6_2_7_path_colon_end.stdout_lines }}"
- "The following paths have a dot in the path: {{ rhel9cis_6_2_7_dot_in_path.stdout_lines }}"
- name: "6.2.3 | L1 | PATCH | Ensure root PATH Integrity (Scored) | Determine rights and owner"
- name: "6.2.7 | PATCH | Ensure root PATH Integrity (Scored) | Determine rights and owner"
file: >
path='{{ item }}'
follow=yes
state=directory
owner=root
mode='o-w,g-w'
with_items: "{{ dot_in_path.stdout_lines }}"
with_items: "{{ rhel9cis_6_2_7_dot_in_path.stdout_lines }}"
when:
- rhel9cis_rule_6_2_3
- rhel9cis_rule_6_2_7
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_6.2.3
- paths
- rule_6.2.7
- name: "6.2.4 | L1 | PATCH | Ensure no legacy '+' entries exist in /etc/shadow"
shell: sed -i '/^+/ d' /etc/shadow
args:
warn: false
- name: "6.2.8 | PATCH | Ensure root is the only UID 0 account"
command: passwd -l {{ item }}
changed_when: false
failed_when: false
with_items: "{{ rhel9cis_uid_zero_accounts_except_root.stdout_lines }}"
when:
- rhel9cis_rule_6_2_4
- rhel9cis_uid_zero_accounts_except_root.rc
- rhel9cis_rule_6_2_8
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_6.2.4
- skip_ansible_lint
- accounts
- users
- rule_6.2.8
- name: "6.2.5 | L1 | PATCH | Ensure no legacy '+' entries exist in /etc/group"
shell: sed -i '/^+/ d' /etc/group
args:
warn: false
changed_when: false
failed_when: false
when:
- rhel9cis_rule_6_2_5
tags:
- level1-server
- level1-workstation
- patch
- rule_6.2.5
- skip_ansible_lint
- name: "6.2.6 | L1 | PATCH | Ensure root is the only UID 0 account"
shell: passwd -l {{ item }}
args:
warn: false
changed_when: false
failed_when: false
with_items: "{{ uid_zero_accounts_except_root.stdout_lines }}"
when:
- uid_zero_accounts_except_root.rc
- rhel9cis_rule_6_2_6
tags:
- level1-server
- level1-workstation
- patch
- rule_6.2.6
- name: "6.2.7 | L1 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
- name: "6.2.9 | PATCH | Ensure all users' home directories exist"
block:
- name: "6.2.7 | L1 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive"
- name: "6.2.9 | AUDIT | Ensure all users' home directories exist"
stat:
path: "{{ item }}"
with_items: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int) | selectattr('uid', '<', max_int_uid | int) | selectattr('dir', '!=', '/') | map(attribute='dir') | list }}"
register: rhel_09_6_2_7_audit
register: rhel_08_6_2_9_audit
with_items: "{{ rhel9cis_passwd | selectattr('uid', '>=', rhel9cis_int_gid) | selectattr('uid', '!=', 65534) | map(attribute='dir') | list }}"
- debug:
var: rhel_09_6_2_7_audit
- name: "6.2.7 | L1 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive"
shell: find -H {{ item.0 | quote }} -not -type l -perm /027
args:
warn: false
- name: "6.2.9 | AUDIT | Ensure all users' home directories exist"
command: find -H {{ item.0 | quote }} -not -type l -perm /027
check_mode: false
changed_when: rhel_09_6_2_7_patch_audit.stdout | length > 0
register: rhel_09_6_2_7_patch_audit
changed_when: rhel_08_6_2_9_patch_audit.stdout | length > 0
register: rhel_08_6_2_9_patch_audit
when:
- ansible_check_mode
- item.1.exists
with_together:
- "{{ rhel_09_6_2_7_audit.results | map(attribute='item') | list }}"
- "{{ rhel_09_6_2_7_audit.results | map(attribute='stat') | list }}"
- "{{ rhel_08_6_2_9_audit.results | map(attribute='item') | list }}"
- "{{ rhel_08_6_2_9_audit.results | map(attribute='stat') | list }}"
loop_control:
label: "{{ item.0 }}"
- name: "6.2.7 | L1 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
- name: "6.2.9 | PATCH | Ensure all users' home directories exist"
file:
path: "{{ item.0 }}"
recurse: true
recurse: yes
mode: a-st,g-w,o-rwx
register: rhel_09_6_2_7_patch
register: rhel_08_6_2_9_patch
when:
- not ansible_check_mode
- item.1.exists
with_together:
- "{{ rhel_09_6_2_7_audit.results | map(attribute='item') | list }}"
- "{{ rhel_09_6_2_7_audit.results | map(attribute='stat') | list }}"
- "{{ rhel_08_6_2_9_audit.results | map(attribute='item') | list }}"
- "{{ rhel_08_6_2_9_audit.results | map(attribute='stat') | list }}"
loop_control:
label: "{{ item.0 }}"
# set default ACLs so the homedir has an effective umask of 0027
- name: "6.2.7 | L1 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
- name: "6.2.9 | PATCH | Ensure all users' home directories exist"
acl:
path: "{{ item.0 }}"
default: true
default: yes
state: present
recursive: true
recursive: yes
etype: "{{ item.1.etype }}"
permissions: "{{ item.1.mode }}"
when:
- not system_is_container
when: not rhel9cis_system_is_container
with_nested:
- "{{ (ansible_check_mode | ternary(rhel_09_6_2_7_patch_audit, rhel_09_6_2_7_patch)).results |
- "{{ (ansible_check_mode | ternary(rhel_08_6_2_9_patch_audit, rhel_08_6_2_9_patch)).results |
rejectattr('skipped', 'defined') | map(attribute='item') | map('first') | list }}"
-
- etype: group
@ -191,14 +280,17 @@
- etype: other
mode: '0'
when:
- rhel9cis_rule_6_2_7
- rhel9cis_rule_6_2_9
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_6.2.7
- users
- rule_6.2.9
- name: "6.2.8 | L1 | PATCH | Ensure users own their home directories"
- name: "6.2.10 | PATCH | Ensure users own their home directories"
file:
path: "{{ item.dir }}"
owner: "{{ item.id }}"
@ -207,348 +299,66 @@
loop_control:
label: "{{ rhel9cis_passwd_label }}"
when:
- min_int_uid | int >= item.uid
- rhel9cis_rule_6_2_8
- item.uid >= rhel9cis_int_gid
- rhel9cis_rule_6_2_10
tags:
- skip_ansible_lint # settings found on 6_2_7
- level1-server
- level1-workstation
- autoamted
- patch
- rule_6.2.8
- name: "6.2.9 | L1 | PATCH | Ensure users' dot files are not group or world-writable"
block:
- name: "6.2.9 | L1 | AUDIT | Ensure users' dot files are not group or world-writable | Check for files"
shell: find /home/ -name "\.*" -perm /g+w,o+w
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_6_2_9_audit
- name: "6.2.9 | L1 | AUDIT | Ensure users' dot files are not group or world-writable | Alert on files found"
debug:
msg: "Good news! We have not found any group or world-writable dot files on your sytem"
when:
- rhel9cis_6_2_9_audit.stdout is not defined
- name: "6.2.9 | L1 | PATCH | Ensure users' dot files are not group or world-writable | Changes files if configured"
file:
path: '{{ item }}'
mode: go-w
with_items: "{{ rhel9cis_6_2_9_audit.stdout_lines }}"
when:
- rhel9cis_6_2_9_audit.stdout is defined
- rhel9cis_dotperm_ansiblemanaged
when:
- rhel9cis_rule_6_2_9
tags:
- level1-server
- level1-workstation
- patch
- rule_6.2.9
- name: "6.2.10 | L1 | PATCH | Ensure no users have .forward files"
file:
state: absent
dest: "~{{ item }}/.forward"
with_items: "{{ users.stdout_lines }}"
when:
- rhel9cis_rule_6_2_10
tags:
- level1-server
- level1-workstation
- patch
- users
- rule_6.2.10
- name: "6.2.11 | L1 | PATCH | Ensure no users have .netrc files"
file:
state: absent
dest: "~{{ item }}/.netrc"
with_items: "{{ users.stdout_lines }}"
when:
- rhel9cis_rule_6_2_11
tags:
- level1-server
- level1-workstation
- patch
- rule_6.2.11
- name: "6.2.12 | L1 | PATCH | Ensure users' .netrc Files are not group or world accessible"
shell: /bin/true
args:
warn: false
changed_when: false
failed_when: false
when:
- rhel9cis_rule_6_2_12
tags:
- level1-server
- level1-workstation
- patch
- rule_6.2.12
- name: "6.2.13 | L1 | PATCH | Ensure no users have .rhosts files"
file:
state: absent
dest: "~{{ item }}/.rhosts"
with_items: "{{ users.stdout_lines }}"
when:
- rhel9cis_rule_6_2_13
tags:
- level1-server
- level1-workstation
- patch
- rule_6.2.13
- name: "6.2.14 | L1 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group"
- name: "6.2.11 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
block:
- name: "6.2.14 | L1 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Check /etc/passwd entries"
shell: pwck -r | grep 'no group' | awk '{ gsub("[:\47]",""); print $2}'
args:
warn: false
changed_when: false
failed_when: false
check_mode: false
register: passwd_gid_check
- name: "6.2.14 | L1 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Print message that all groups match between passwd and group files"
debug:
msg: "Good News! There are no users that have non-existent GUIDs (Groups)"
when: passwd_gid_check.stdout is not defined
- name: "6.2.14 | L1 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Print warning about users with invalid GIDs missing GID entries in /etc/group"
debug:
msg: "WARNING: The following users have non-existent GIDs (Groups): {{ passwd_gid_check.stdout_lines | join (', ') }}"
when: passwd_gid_check.stdout is defined
when:
- rhel9cis_rule_6_2_14
tags:
- level1-server
- level1-workstation
- audit
- rule_6.2.14
- name: "6.2.15 | L1 | AUDIT Ensure no duplicate UIDs exist"
block:
- name: "6.2.15 | L1 | AUDIT | Ensure no duplicate UIDs exist | Check for duplicate UIDs"
shell: "pwck -r | awk -F: '{if ($3 in uid) print $1 ; else uid[$3]}' /etc/passwd"
args:
warn: false
changed_when: false
failed_when: false
register: user_uid_check
- name: "6.2.15 | L1 | AUDIT | Ensure no duplicate UIDs exist | Print message that no duplicate UIDs exist"
debug:
msg: "Good News! There are no duplicate UID's in the system"
when: user_uid_check.stdout is not defined
- name: "6.2.15 | L1 | AUDIT| Ensure no duplicate UIDs exist | Print warning about users with duplicate UIDs"
debug:
msg: "Warning: The following users have UIDs that are duplicates: {{ user_uid_check.stdout_lines }}"
when: user_uid_check.stdout is defined
when:
- rhel9cis_rule_6_2_15
tags:
- level1-server
- level1-workstation
- patch
- rule_6.2.15
- name: "6.2.16 | L1 | AUDIT | Ensure no duplicate GIDs exist"
block:
- name: "6.2.16 | L1 | AUDIT | Ensure no duplicate GIDs exist | Check for duplicate GIDs"
shell: "pwck -r | awk -F: '{if ($3 in users) print $1 ; else users[$3]}' /etc/group"
args:
warn: false
changed_when: false
failed_when: false
register: user_user_check
- name: "6.2.16 | L1 | AUDIT | Ensure no duplicate GIDs exist | Print message that no duplicate GID's exist"
debug:
msg: "Good News! There are no duplicate GIDs in the system"
when: user_user_check.stdout is not defined
- name: "6.2.16 | L1 | AUDIT | Ensure no duplicate GIDs exist | Print warning about users with duplicate GIDs"
debug:
msg: "Warning: The following groups have duplicate GIDs: {{ user_user_check.stdout_lines }}"
when: user_user_check.stdout is defined
when:
- rhel9cis_rule_6_2_16
tags:
- level1-server
- level1-workstation
- audit
- rule_6.2.16
- name: "6.2.17 | L1 | AUDIT | Ensure no duplicate user names exist"
block:
- name: "6.2.17 | L1 | AUDIT | Ensure no duplicate user names exist | Check for duplicate User Names"
shell: "pwck -r | awk -F: '{if ($1 in users) print $1 ; else users[$1]}' /etc/passwd"
args:
warn: false
changed_when: false
failed_when: false
register: user_username_check
- name: "6.2.17 | L1 | AUDIT | Ensure no duplicate user names exist | Print message that no duplicate user names exist"
debug:
msg: "Good News! There are no duplicate user names in the system"
when: user_username_check.stdout is not defined
- name: "6.2.17 | L1 | AUDIT | Ensure no duplicate user names exist | Print warning about users with duplicate User Names"
debug:
msg: "Warning: The following user names are duplicates: {{ user_username_check.stdout_lines }}"
when: user_username_check.stdout is defined
when:
- rhel9cis_rule_6_2_17
tags:
- level1-server
- level1-workstation
- audit
- rule_6.2.17
- name: "6.2.18 | L1 | AUDIT |Ensure no duplicate group names exist"
block:
- name: "6.2.18 | L1 | AUDIT | Ensure no duplicate group names exist | Check for duplicate group names"
shell: 'getent passwd | cut -d: -f1 | sort -n | uniq -d'
args:
warn: false
changed_when: false
failed_when: false
check_mode: false
register: group_group_check
- name: "6.2.18 | L1 | AUDIT | Ensure no duplicate group names exist | Print message that no duplicate groups exist"
debug:
msg: "Good News! There are no duplicate group names in the system"
when: group_group_check.stdout is defined
- name: "6.2.18 | L1 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names"
debug:
msg: "Warning: The following group names are duplicates: {{ group_group_check.stdout_lines }}"
when: group_group_check.stdout is not defined
when:
- rhel9cis_rule_6_2_18
tags:
- level1-server
- level1-workstation
- audit
- rule_6.2.18
- name: "6.2.19 | L1 | AUDIT | Ensure shadow group is empty"
block:
- name: "6.2.19 | L1 | AUDIT | Ensure shadow group is empty | Check for shadow group and pull group id"
shell: "getent group shadow | cut -d: -f3"
args:
warn: false
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_shadow_gid
- name: "6.2.19 | L1 | AUDIT | Ensure shadow group is empty | Check /etc/group for empty shadow group"
shell: grep ^shadow:[^:]*:[^:]*:[^:]+ /etc/group
args:
warn: false
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_empty_shadow
- name: "6.2.19 | L1 | AUDIT | Ensure shadow group is empty | Check for users assigned to shadow"
shell: "getent passwd | awk -F: '$4 == '{{ rhel9cis_shadow_gid.stdout }}' {print $1}'"
args:
warn: false
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_shadow_passwd
- name: "6.2.19 | L1 | AUDIT | Ensure shadow group is empty | Alert shadow group is empty and no users assigned"
debug:
msg:
- " Good News! The shadow group is empty and there are no users assigned to shadow"
when:
- rhel9cis_empty_shadow.stdout | length == 0
- rhel9cis_shadow_passwd.stdout | length == 0
- name: "6.2.19 | L1 | AUDIT | Ensure shadow group is empty | Alert shadow group is not empty"
debug:
msg:
- "Alert! The shadow group is not empty"
when:
- rhel9cis_empty_shadow.stdout | length > 0
- name: "6.2.19 | L1 | AUDIT | Ensure shadow group is empty | Alert users are using shadow group"
debug:
msg:
- "Alert! The following users are assigned to the shadow group, please assing them to the appropriate group"
- "{{ rhel9cis_shadow_passwd.stdout_lines }}"
when:
- rhel9cis_shadow_passwd.stdout | length > 0
when:
- rhel9cis_rule_6_2_19
tags:
- level1-server
- level1-workstation
- audit
- rule_6.2.19
- name: "6.2.20 | L1 | PATCH | Ensure all users' home directories exist"
block:
- name: "6.2.20 | L1 | AUDIT | Ensure all users' home directories exist"
- name: "6.2.11 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive"
stat:
path: "{{ item }}"
register: rhel_09_6_2_20_audit
with_items: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int) | selectattr('uid', '<', max_int_uid | int) | selectattr('dir', '!=', '/') | map(attribute='dir') | list }}"
with_items: "{{ rhel9cis_passwd | selectattr('uid', '>=', rhel9cis_int_gid) | selectattr('uid', '!=', 65534) | map(attribute='dir') | list }}"
register: rhel_08_6_2_11_audit
- name: "6.2.20 | L1 | AUDIT | Ensure all users' home directories exist"
shell: find -H {{ item.0 | quote }} -not -type l -perm /027
args:
warn: false
- name: "6.2.11 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive"
command: find -H {{ item.0 | quote }} -not -type l -perm /027
check_mode: false
changed_when: rhel_09_6_2_20_patch_audit.stdout | length > 0
register: rhel_09_6_2_20_patch_audit
changed_when: rhel_08_6_2_11_patch_audit.stdout | length > 0
register: rhel_08_6_2_11_patch_audit
when:
- ansible_check_mode
- item.1.exists
with_together:
- "{{ rhel_09_6_2_20_audit.results | map(attribute='item') | list }}"
- "{{ rhel_09_6_2_20_audit.results | map(attribute='stat') | list }}"
- "{{ rhel_08_6_2_11_audit.results | map(attribute='item') | list }}"
- "{{ rhel_08_6_2_11_audit.results | map(attribute='stat') | list }}"
loop_control:
label: "{{ item.0 }}"
- name: "6.2.20 | L1 | PATCH | Ensure all users' home directories exist"
- name: "6.2.11 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
file:
path: "{{ item.0 }}"
recurse: true
recurse: yes
mode: a-st,g-w,o-rwx
register: rhel_09_6_2_20_patch
register: rhel_08_6_2_11_patch
when:
- not ansible_check_mode
- item.1.exists
with_together:
- "{{ rhel_09_6_2_20_audit.results | map(attribute='item') | list }}"
- "{{ rhel_09_6_2_20_audit.results | map(attribute='stat') | list }}"
- "{{ rhel_08_6_2_11_audit.results | map(attribute='item') | list }}"
- "{{ rhel_08_6_2_11_audit.results | map(attribute='stat') | list }}"
loop_control:
label: "{{ item.0 }}"
# set default ACLs so the homedir has an effective umask of 0027
- name: "6.2.20 | L1 | PATCH | Ensure all users' home directories exist"
- name: "6.2.11 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
acl:
path: "{{ item.0 }}"
default: true
default: yes
state: present
recursive: true
recursive: yes
etype: "{{ item.1.etype }}"
permissions: "{{ item.1.mode }}"
when:
- not system_is_container
when: not rhel9cis_system_is_container
with_nested:
- "{{ (ansible_check_mode | ternary(rhel_09_6_2_20_patch_audit, rhel_09_6_2_20_patch)).results |
- "{{ (ansible_check_mode | ternary(rhel_08_6_2_11_patch_audit, rhel_08_6_2_11_patch)).results |
rejectattr('skipped', 'defined') | map(attribute='item') | map('first') | list }}"
-
- etype: group
@ -556,9 +366,111 @@
- etype: other
mode: '0'
when:
- rhel9cis_rule_6_2_20
- rhel9cis_rule_6_2_11
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_6.2.20
- users
- permissions
- rule_6.2.11
- name: "6.2.12 | PATCH | Ensure users' dot files are not group or world-writable"
block:
- name: "6.2.12 | AUDIT | Ensure users' dot files are not group or world-writable | Check for files"
shell: find /home/ -maxdepth 2 -name "\.*" -perm /g+w,o+w
changed_when: false
failed_when: false
register: rhel9cis_6_2_12_audit
- name: "6.2.12 | AUDIT | Ensure users' dot files are not group or world-writable | Alert on files found"
debug:
msg: "Good news! We have not found any group or world-writable dot files on your sytem"
when:
- rhel9cis_6_2_12_audit.stdout is not defined
- name: "6.2.12 | PATCH | Ensure users' dot files are not group or world-writable | Changes files if configured"
file:
path: '{{ item }}'
mode: go-w
with_items: "{{ rhel9cis_6_2_12_audit.stdout_lines }}"
when:
- rhel9cis_6_2_12_audit.stdout is defined
- rhel9cis_dotperm_ansiblemanaged
when:
- rhel9cis_rule_6_2_12
tags:
- level1-server
- level1-workstation
- automated
- patch
- users
- permissions
- rule_6.2.12
- name: "6.2.13 | PATCH | Ensure users' .netrc Files are not group or world accessible"
command: /bin/true
changed_when: false
failed_when: false
when:
- rhel9cis_rule_6_2_13
tags:
- level1-server
- level1-workstation
- automated
- patch
- users
- permissions
- notimplemented
- rule_6.2.13
- name: "6.2.14 | PATCH | Ensure no users have .forward files"
file:
state: absent
dest: "~{{ item }}/.forward"
with_items:
- "{{ users.stdout_lines }}"
when:
- rhel9cis_rule_6_2_14
tags:
- level1-server
- level1-workstation
- automated
- patch
- users
- files
- rule_6.2.14
- name: "6.2.15 | PATCH | Ensure no users have .netrc files"
file:
state: absent
dest: "~{{ item }}/.netrc"
with_items:
- "{{ users.stdout_lines }}"
when:
- rhel9cis_rule_6_2_15
tags:
- level1-server
- level1-workstation
- automated
- patch
- users
- files
- rule_6.2.15
- name: "6.2.16 | PATCH | Ensure no users have .rhosts files"
file:
state: absent
dest: "~{{ item }}/.rhosts"
with_items: "{{ users.stdout_lines }}"
when:
- rhel9cis_rule_6_2_16
tags:
- level1-server
- level1-workstation
- automated
- patch
- users
- files
- rule_6.2.16

View file

@ -1,79 +1,92 @@
# File created initially via RHEL9 CIS ansible-lockdown remdiation role
{% if rhel9cis_rule_4_1_3 %}
# This template will set all of the auditd configurations via a handler in the role in one task instead of individually
{% if rhel9cis_rule_4_1_3_1 %}
-w /etc/sudoers -p wa -k scope
-w /etc/sudoers.d/ -p wa -k scope
{% endif %}
{% if rhel9cis_rule_4_1_4 %}
-w /var/log/faillog -p wa -k logins
-w /var/log/lastlog -p wa -k logins
{% if rhel9cis_rule_4_1_3_2 %}
-a always,exit -F arch=b64 -C euid!=uid -F auid!=unset -S execve -k user_emulation
-a always,exit -F arch=b32 -C euid!=uid -F auid!=unset -S execve -k user_emulation
{% endif %}
{% if rhel9cis_rule_4_1_5 %}
-w /var/run/utmp -p wa -k session
-w /var/log/wtmp -p wa -k logins
-w /var/log/btmp -p wa -k logins
{% if rhel9cis_rule_4_1_3_3 %}
-w {{ rhel9cis_varlog_location }} -p wa -k sudo_log_file
{% endif %}
{% if rhel9cis_rule_4_1_6 %}
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change
-a always,exit -F arch=b64 -S clock_settime -k time-change
-a always,exit -F arch=b32 -S clock_settime -k time-change
{% if rhel9cis_rule_4_1_3_4 %}
-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change
-a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -k time-change
-w /etc/localtime -p wa -k time-change
{% endif %}
{% if rhel9cis_rule_4_1_7 %}
-w /etc/selinux/ -p wa -k MAC-policy
-w /usr/share/selinux/ -p wa -k MAC-policy
{% endif %}
{% if rhel9cis_rule_4_1_8 %}
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale
-a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale
{% if rhel9cis_rule_4_1_3_5 %}
-a always,exit -F arch=b64 -S sethostname,setdomainname -F key=system-locale
-a always,exit -F arch=b32 -S sethostname,setdomainname -F key=system-locale
-w /etc/issue -p wa -k system-locale
-w /etc/issue.net -p wa -k system-locale
-w /etc/hosts -p wa -k system-locale
-w /etc/sysconfig/network -p wa -k system-locale
-w /etc/sysconfig/network-scripts -p wa -k system-locale
{% endif %}
{% if rhel9cis_rule_4_1_9 %}
-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>={{ min_int_uid }} -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>={{ min_int_uid }} -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>={{ min_int_uid }} -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>={{ min_int_uid }} -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>={{ min_int_uid }} -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>={{ min_int_uid }} -F auid!=4294967295 -k perm_mod
{% if rhel9cis_rule_4_1_3_6 %}
{% for proc in priv_procs.stdout_lines -%}
-a always,exit -F path={{ proc }} -F perm=x -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -k privileged
{% endfor %}
{% endif %}
{% if rhel9cis_rule_4_1_10 %}
-a always,exit -F arch=b32 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EACCES -F auid>={{ min_int_uid }} -F auid!=4294967295 -F key=access
-a always,exit -F arch=b32 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EPERM -F auid>={{ min_int_uid }} -F auid!=4294967295 -F key=access
-a always,exit -F arch=b64 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EACCES -F auid>={{ min_int_uid }} -F auid!=4294967295 -F key=access
-a always,exit -F arch=b64 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EPERM -F auid>={{ min_int_uid }} -F auid!=4294967295 -F key=access
{% if rhel9cis_rule_4_1_3_7 %}
-a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=access
-a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=access
-a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>={{ rhel9cis_int_gid }} -F auid!=-4294967295 -F key=access
-a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=access
{% endif %}
{% if rhel9cis_rule_4_1_11 %}
{% if rhel9cis_rule_4_1_3_8 %}
-w /etc/group -p wa -k identity
-w /etc/passwd -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/security/opasswd -p wa -k identity
{% endif %}
{% if rhel9cis_rule_4_1_12 %}
-a always,exit -F arch=b32 -S mount -F auid>={{ min_int_uid }} -F auid!=4294967295 -k mounts
-a always,exit -F arch=b64 -S mount -F auid>={{ min_int_uid }} -F auid!=4294967295 -k mounts
{% if rhel9cis_rule_4_1_3_9 %}
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=perm_mod
-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=perm_mod
-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=perm_mod
-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=perm_mod
-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=perm_mod
-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=perm_mod
{% endif %}
{% if rhel9cis_rule_4_1_13 %}
{% for proc in priv_procs.stdout_lines -%}
-a always,exit -F path={{ proc }} -F perm=x -F auid>={{ min_int_uid }} -F auid!=4294967295 -k privileged
{% endfor %}
{% if rhel9cis_rule_4_1_3_10 %}
-a always,exit -F arch=b32 -S mount -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -k mounts
-a always,exit -F arch=b64 -S mount -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -k mounts
{% endif %}
{% if rhel9cis_rule_4_1_14 %}
-a always,exit -F arch=b32 -S rmdir,unlink,unlinkat,rename -S renameat -F auid>={{ min_int_uid }} -F auid!=4294967295 -F key=delete
-a always,exit -F arch=b64 -S rmdir,unlink,unlinkat,rename -S renameat -F auid>={{ min_int_uid }} -F auid!=4294967295 -F key=delete
{% if rhel9cis_rule_4_1_3_11 %}
-w /var/run/utmp -p wa -k session
-w /var/log/wtmp -p wa -k session
-w /var/log/btmp -p wa -k session
{% endif %}
{% if rhel9cis_rule_4_1_15 %}
-w /usr/sbin/insmod -p x -k modules
-w /usr/sbin/rmmod -p x -k modules
-w /usr/sbin/modprobe -p x -k modules
-a always,exit -F arch=b64 -S init_module -S delete_module -k modules
{% if rhel9cis_rule_4_1_3_12 %}
-w /var/log/lastlog -p wa -k logins
-w /var/run/faillock -p wa -k logins
{% endif %}
{% if rhel9cis_rule_4_1_16 %}
-w /var/log/sudo.log -p wa -k actions
{% if rhel9cis_rule_4_1_3_13 %}
-a always,exit -F arch=b64 -S rename,unlink,unlinkat,renameat -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=delete
-a always,exit -F arch=b32 -S rename,unlink,unlinkat,renameat -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -F key=delete
{% endif %}
{% if rhel9cis_rule_4_1_17 %}
{% if rhel9cis_rule_4_1_3_14 %}
-w /etc/selinux/ -p wa -k MAC-policy
-w /usr/share/selinux/ -p wa -k MAC-policy
{% endif %}
{% if rhel9cis_rule_4_1_3_15 %}
-a always,exit -F path=/usr/bin/chcon -F perm=x -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -k perm_chng
{% endif %}
{% if rhel9cis_rule_4_1_3_16 %}
-a always,exit -F path=/usr/bin/setfacl -F perm=x -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -k perm_chng
{% endif %}
{% if rhel9cis_rule_4_1_3_17 %}
-a always,exit -F path=/usr/bin/chacl -F perm=x -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -k priv_cmd
{% endif %}
{% if rhel9cis_rule_4_1_3_18 %}
-a always,exit -F path=/usr/sbin/usermod -F perm=x -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -k usermod
{% endif %}
{% if rhel9cis_rule_4_1_3_19 %}
-a always,exit -F arch=b64 -S init_module,finit_module,delete_module,create_module,query_module -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -k kernel_modules
-a always,exit -F path=/usr/bin/kmod -F perm=x -F auid>={{ rhel9cis_int_gid }} -F auid!=4294967295 -k kernel_modules
{% endif %}
{% if rhel9cis_rule_4_1_3_20 %}
-e 2
{% endif %}