4
0
Fork 0

Merge pull request #31 from ansible-lockdown/CIS_v1.0.0

Release for official Cis v1.0.0
This commit is contained in:
uk-bolly 2023-02-01 13:42:45 +00:00 committed by GitHub
commit 32e795d68d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
85 changed files with 2675 additions and 2658 deletions

View file

@ -1,18 +1,20 @@
parseable: true
quiet: true
skip_list:
- 'schema'
- 'no-changed-when'
- 'fqcn-builtins'
- 'experimental'
- 'name[casing]'
- 'name[template]'
- 'jinja[spacing]'
- '204'
- '305'
- '303'
- '403'
- '306'
- '602'
- 'schema'
- 'no-changed-when'
- 'var-spacing'
- 'experimental'
- 'name[play]'
- 'name[casing]'
- 'name[template]'
- 'fqcn[action]'
- '204'
- '305'
- '303'
- '403'
- '306'
- '602'
- '208'
use_default_rules: true
verbosity: 0

View file

@ -1,5 +1,5 @@
#Ami Alma 9
ami_id = "ami-02881bd671eb4ac61"
ami_id = "ami-0845395779540e3cb"
ami_os = "rhel9"
ami_username = "ec2-user"
ami_user_home = "/home/ec2-user"

View file

@ -26,12 +26,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/first-interaction@v1.1.1
- uses: actions/first-interaction@main
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
pr-message: |-
Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown!
Please join in the conversation happening on the [Discord Server](https://discord.io/iansible-lockdown) as well.
Please join in the conversation happening on the [Discord Server](https://discord.io/ansible-lockdown) as well.
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
@ -44,7 +44,7 @@ jobs:
steps:
# Checks-out your repository under $GITHUB_WORKSPACE,
# so your job can access it
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
@ -87,6 +87,12 @@ jobs:
run: sleep 60s
shell: bash
# Set up requirements for random root password CIS 5.6.6
- name: add urandom passwd to root account
shell: bash
run: |
ANSIBLE_HOST_KEY_CHECKING=False && ansible all -i .github/workflows/hosts.yml -m shell -a "cat /dev/urandom | tr -dc [:print:] | head -c50 | passwd --stdin root" --private-key ${{ secrets.SSH_PRV_KEY }} -b
# Run the ansible playbook
- name: Run_Ansible_Playbook
uses: arillso/action.playbook@master

View file

@ -78,6 +78,7 @@ resource "local_file" "inventory" {
run_audit: true
system_is_ec2: true
audit_git_version: devel
skip_reboot: false
EOF
}

View file

@ -1,6 +0,0 @@
RHEL7=$(grep -c RHEL7 OS.tfvars)
if [ `echo $?` != 0 ]; then
exit 0
fi

View file

@ -9,12 +9,6 @@ ignore: |
extends: default
rules:
indentation:
# Requiring 4 space indentation
spaces: 4
# Requiring consistent indentation within a file, either indented or not
indent-sequences: consistent
truthy: disable
braces:
max-spaces-inside: 1
level: error
@ -32,4 +26,4 @@ rules:
trailing-spaces: enable
truthy:
allowed-values: ['true', 'false']
check-keys: false
check-keys: true

View file

@ -1,5 +1,29 @@
# Changes to rhel9CIS
## Initial CIS v1.0.0 - released Dec 2022
### Official CIS release
Jan-2023 release
- updated ansible minimum to 2.10
- Lint file updates and improvements
- auditd now shows diff ater initial template added
- many control rewritten
- Many controls moved ID references
- Audit updates aligned
- Command warn arg removed
- Ansible 2.14 now supported
- makefile added (hopefully help some)
- fqcn added to all controls
- some controls rewritten using module rather than shell
- typo fixes from rhel_08 inheritance
- workflow update for 5.6.6 to set random root password to allow for testing
- incorporates issues
- #23
- #24
- New option to add faillock for users without authselect - defaults/main 5.4.2
## 0.5
- audit path updated and output file name

32
Makefile Executable file
View file

@ -0,0 +1,32 @@
.PHONY: all help galaxy-install ansible-list yamllint pip-requirements
GALAXY=ansible-galaxy
ANSIBLE_LINT='/usr/local/bin/ansible-lint'
ANSIBLE_FILE=site.yml
all: help
help:
@echo "Make command examples for Ansible"
@echo "Command for assisting with ansible setup"
@echo " galaxy-install to install roles using ansible-galaxy"
@echo " ansible-lint to lint playbook files"
@echo " yamllint to lint playbook files"
@echo " pip-requirements add pip required file"
galaxy-install:
$(GALAXY) install -r ./collections/requirements.yml
ansible-lint:
$(ANSIBLE_LINT) $(ANSIBLE_FILE)
yamllint:
git ls-files "*.yml"|xargs yamllint
pip-requirements:
@echo 'Python dependencies:'
@cat requirements.txt
pip3 install -r requirements.txt

View file

@ -1,19 +1,15 @@
# Development Only
## RHEL 9 CIS (predicted) - Beta - CIS baselines or OS not yet GA
# RHEL 9 CIS
## Testing if you have access to the RH developer branches
### This should work on RHEL8 and derivatives currently
## v1.0.0 - released Dec 2022
![Build Status](https://img.shields.io/github/workflow/status/ansible-lockdown/RHEL9-CIS/CommunityToDevel?label=Devel%20Build%20Status&style=plastic)
![Build Status](https://img.shields.io/github/workflow/status/ansible-lockdown/RHEL9-CIS/DevelToMain?label=Main%20Build%20Status&style=plastic)
![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
Configure RHEL 9 machine to be [CIS](https://www.cisecurity.org/cis-benchmarks/)
Based on [CIS RedHat Enterprise Linux 8 Benchmark v2.0.0. - 02-23-2022 ](https://www.cisecurity.org/cis-benchmarks/)
Based on [CIS RedHat Enterprise Linux 9 Benchmark v1.0.0. - 11-30-2022 ](https://www.cisecurity.org/cis-benchmarks/)
## Join us
@ -41,9 +37,20 @@ RHEL 9
Almalinux 9
Rocky 9
ansible 2.10
jmespath
relevant collections
- Access to download or add the goss binary and content to the system if using auditing (other options are available on how to get the content to the system.)
**General:**
## Tested with
ansible-base 2.10.17 - python 3.8
ansible-core 2.13.4 - python 3.10
- makefile - this is there purely for testing and initial setup purposes.
## General
- Basic knowledge of Ansible, below are some links to the Ansible documentation to help get started if you are unfamiliar with Ansible
- [Main Ansible documentation page](https://docs.ansible.com)
@ -61,11 +68,13 @@ Rocky 9
- Ansible 2.9+
- python-def (should be included in RHEL 9)
- libselinux-python
- jmespath
- pip packages
- jmespath ( complete list found in requirements.txt)
- collections found in collections/requirememnts.yml
## Role Variables
This role is designed that the end user should not have to edit the tasks themselves. All customizing should be done via the defaults/main.yml file or with extra vars within the project, job, workflow, etc. These variables can be found [here](https://github.com/ansible-lockdown/RHEL9-CIS/wiki/Main-Variables) in the Main Variables Wiki page. All variables are listed there along with descriptions.
This role is designed that the end user should not have to edit the tasks themselves. All customizing should be done by overriding the required varaibles as found in defaults/main.yml file. e.g. using inventory, group_vars, extra_vars
## Tags
@ -83,3 +92,10 @@ Below is an example of the tag section from a control within this role. Using th
- patch
- rule_2.2.4
```
### Known Issues
CIS 1.2.4 - repo_gpgcheck is not carried out for RedHat hosts as the default repos do not have this function. This also affect EPEL(not covered by var).
- Rocky and Alma not affected.
Variable used to unset.
rhel9cis_rhel_default_repo: true # to be set to false if using repo that does have this ability

View file

@ -5,7 +5,13 @@ system_warnings=False
command_warnings=False
nocows=1
retry_files_save_path=/dev/null
library=~/.ansible/plugins/modules:/usr/share/ansible/plugins/modules:./library
pipelining=true
# Use the YAML callback plugin.
stdout_callback = yaml
# Use the stdout_callback when running ad-hoc commands.
bin_ansible_callbacks = True
[privilege_escalation]
@ -14,6 +20,7 @@ record_host_keys=False
[ssh_connection]
transfer_method=scp
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
[accelerate]

View file

@ -71,7 +71,6 @@ audit_cmd_timeout: 60000
# Section 1 rules
rhel9cis_rule_1_1_1_1: true
rhel9cis_rule_1_1_1_2: true
rhel9cis_rule_1_1_1_3: true
rhel9cis_rule_1_1_2_1: true
rhel9cis_rule_1_1_2_2: true
rhel9cis_rule_1_1_2_3: true
@ -79,7 +78,6 @@ rhel9cis_rule_1_1_2_4: true
rhel9cis_rule_1_1_3_1: true
rhel9cis_rule_1_1_3_2: true
rhel9cis_rule_1_1_3_3: true
rhel9cis_rule_1_1_3_4: true
rhel9cis_rule_1_1_4_1: true
rhel9cis_rule_1_1_4_2: true
rhel9cis_rule_1_1_4_3: true
@ -95,26 +93,24 @@ rhel9cis_rule_1_1_6_4: true
rhel9cis_rule_1_1_7_1: true
rhel9cis_rule_1_1_7_2: true
rhel9cis_rule_1_1_7_3: true
rhel9cis_rule_1_1_7_4: true
rhel9cis_rule_1_1_7_5: true
rhel9cis_rule_1_1_8_1: true
rhel9cis_rule_1_1_8_2: true
rhel9cis_rule_1_1_8_3: true
rhel9cis_rule_1_1_8_4: true
rhel9cis_rule_1_1_18: true
rhel9cis_rule_1_1_19: true
rhel9cis_rule_1_1_20: true
rhel9cis_rule_1_1_21: true
rhel9cis_rule_1_1_9: true
rhel9cis_rule_1_1_10: true
rhel9cis_rule_1_2_1: true
rhel9cis_rule_1_2_2: true
rhel9cis_rule_1_2_3: true
rhel9cis_rule_1_2_4: true
rhel9cis_rule_1_3_1: true
rhel9cis_rule_1_3_2: true
rhel9cis_rule_1_3_3: true
rhel9cis_rule_1_4_1: true
rhel9cis_rule_1_4_2: true
rhel9cis_rule_1_4_3: true
rhel9cis_rule_1_5_1: true
rhel9cis_rule_1_5_2: true
rhel9cis_rule_1_5_3: true
@ -125,6 +121,7 @@ rhel9cis_rule_1_6_1_4: true
rhel9cis_rule_1_6_1_5: true
rhel9cis_rule_1_6_1_6: true
rhel9cis_rule_1_6_1_7: true
rhel9cis_rule_1_6_1_8: true
rhel9cis_rule_1_7_1: true
rhel9cis_rule_1_7_2: true
rhel9cis_rule_1_7_3: true
@ -136,6 +133,11 @@ rhel9cis_rule_1_8_2: true
rhel9cis_rule_1_8_3: true
rhel9cis_rule_1_8_4: true
rhel9cis_rule_1_8_5: true
rhel9cis_rule_1_8_6: true
rhel9cis_rule_1_8_7: true
rhel9cis_rule_1_8_8: true
rhel9cis_rule_1_8_9: true
rhel9cis_rule_1_8_10: true
rhel9cis_rule_1_9: true
rhel9cis_rule_1_10: true
@ -160,21 +162,16 @@ rhel9cis_rule_2_2_15: true
rhel9cis_rule_2_2_16: true
rhel9cis_rule_2_2_17: true
rhel9cis_rule_2_2_18: true
rhel9cis_rule_2_2_19: true
rhel9cis_rule_2_2_20: true
rhel9cis_rule_2_3_1: true
rhel9cis_rule_2_3_2: true
rhel9cis_rule_2_3_3: true
rhel9cis_rule_2_3_4: true
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_3_1: true
@ -188,11 +185,6 @@ 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
@ -200,11 +192,6 @@ 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_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
# Section 4 rules
rhel9cis_rule_4_1_1_1: true
@ -235,6 +222,16 @@ 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_1_4_1: true
rhel9cis_rule_4_1_4_2: true
rhel9cis_rule_4_1_4_3: true
rhel9cis_rule_4_1_4_4: true
rhel9cis_rule_4_1_4_5: true
rhel9cis_rule_4_1_4_6: true
rhel9cis_rule_4_1_4_7: true
rhel9cis_rule_4_1_4_8: true
rhel9cis_rule_4_1_4_9: true
rhel9cis_rule_4_1_4_10: true
rhel9cis_rule_4_2_1_1: true
rhel9cis_rule_4_2_1_2: true
rhel9cis_rule_4_2_1_3: true
@ -253,9 +250,7 @@ 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_1: true
rhel9cis_rule_4_3_2: true
rhel9cis_rule_4_3_3: true
rhel9cis_rule_4_3: true
# Section 5 rules
rhel9cis_rule_5_1_1: true
@ -310,6 +305,7 @@ rhel9cis_rule_5_6_2: true
rhel9cis_rule_5_6_3: true
rhel9cis_rule_5_6_4: true
rhel9cis_rule_5_6_5: true
rhel9cis_rule_5_6_6: true
# Section 6 rules
rhel9cis_rule_6_1_1: true
@ -369,11 +365,18 @@ rhel9cis_rh_sub_password: password
# RedHat Satellite Subscription items
rhel9cis_rhnsd_required: false
# 1.4.2 Bootloader password
rhel9cis_bootloader_password_hash: 'grub.pbkdf2.sha512.changethispassword'
rhel9cis_bootloader_password: random
rhel9cis_set_boot_pass: false
# 1.2.4 repo_gpgcheck
rhel9cis_rhel_default_repo: true
# 1.4.2 Bootloader password
rhel9cis_bootloader_password_hash: 'grub.pbkdf2.sha512.10000.9306A36764A7BEA3BF492D1784396B27F52A71812E9955A58709F94EE70697F9BD5366F36E07DEC41B52279A056E2862A93E42069D7BBB08F5DFC2679CD43812.6C32ADA5449303AD5E67A4C150558592A05381331DE6B33463469A236871FA8E70738C6F9066091D877EF88A213C86825E093117F30E9E1BF158D0DB75E7581B'
rhel9cis_bootloader_password: random
rhel9cis_set_boot_pass: true
# 1.8 Gnome Desktop
rhel9cis_dconf_db_name: local
rhel9cis_screensaver_idle_delay: 900 # Set max value for idle-delay in seconds (between 1 and 900)
rhel9cis_screensaver_lock_delay: 5 # Set max value for lock-delay in seconds (between 0 and 5)
# 1.10 Set crypto policy DEFAULT
# Control 1.10 states not to use LEGACY
@ -400,6 +403,8 @@ rhel9cis_aide_cron:
# SELinux policy
rhel9cis_selinux_pol: targeted
# chose onf or enfocing or permissive
rhel9cis_selinux_enforce: enforcing
# Whether or not to run tasks related to auditing/patching the desktop environment
@ -417,13 +422,12 @@ rhel9cis_chrony_server_options: "minpoll 8"
### 2.2 Special Purposes
##### Service configuration booleans set true to keep service
rhel9cis_xinetd_server: false
rhel9cis_gui: false
rhel9cis_avahi_server: false
rhel9cis_cups_server: false
rhel9cis_dhcp_server: false
rhel9cis_dns_server: false
rhel9cis_ftp_server: false
rhel9cis_dnsmasq_server: false
rhel9cis_vsftpd_server: false
rhel9cis_tftp_server: false
rhel9cis_httpd_server: false
@ -433,7 +437,6 @@ rhel9cis_imap_server: false
rhel9cis_samba_server: false
rhel9cis_squid_server: false
rhel9cis_snmp_server: false
rhel9cis_nis_server: false
rhel9cis_telnet_server: false
rhel9cis_is_mail_server: false
# Note the options
@ -450,12 +453,10 @@ rhel9cis_use_rsync_server: false
rhel9cis_use_rsync_service: false
#### 2.3 Service clients
rhel9cis_ypbind_required: false
rhel9cis_rsh_required: false
rhel9cis_talk_required: false
rhel9cis_telnet_required: false
rhel9cis_openldap_clients_required: false
rhel9cis_tftp_client: false
rhel9cis_ftp_client: false
## Section3 vars
@ -473,18 +474,20 @@ rhel9cis_firewall: firewalld
##### firewalld
rhel9cis_default_zone: public
rhel9cis_firewalld_nftables_state: masked # Note if absent removes the firewalld pkg dependancy
# These are added to demonstrate how this can be done
rhel9cis_firewalld_ports:
- number: 80
protocol: tcp
#### nftables
rhel9cis_nftables_firewalld_state: masked
rhel9cis_nft_tables_autonewtable: true
rhel9cis_nft_tables_tablename: filter
rhel9cis_nft_tables_autochaincreate: true
# Warning Banner Content (issue, issue.net, motd)
rhel9cis_warning_banner: |
Authorized uses only. All activity may be monitored and reported.
rhel9cis_warning_banner: Authorized uses only. All activity may be monitored and reported.
# End Banner
## Section4 vars
@ -518,10 +521,17 @@ rhel9cis_auditd_extra_conf: {}
## Preferred method of logging
## Whether rsyslog or journald preferred method for local logging
## Affects rsyslog cis 4.2.1.3 and journald cis 4.2.2.5
rhel9cis_preferred_log_capture: rsyslog
rhel9cis_syslog: rsyslog
rhel9cis_rsyslog_ansiblemanaged: true
#### 4.2.1.6 remote and destation log server name
rhel9cis_remote_log_server: logagg.example.com
rhel9cis_remote_log_server: false
rhel9cis_remote_log_host: logagg.example.com
rhel9cis_remote_log_port: 514
rhel9cis_remote_log_protocol: tcp
rhel9cis_remote_log_retrycount: 100
rhel9cis_remote_log_queuesize: 1000
#### 4.2.1.7
rhel9cis_system_is_log_server: false
@ -588,9 +598,6 @@ rhel9cis_pass:
max_days: 365
min_days: 7
warn_age: 7
# Syslog system - either rsyslog or syslog-ng
rhel9cis_syslog: rsyslog
rhel9cis_rsyslog_ansiblemanaged: true
# 5.5.1
## PAM
@ -615,6 +622,14 @@ rhel9cis_sudolog_location: "/var/log/sudo.log"
#### 5.3.6
rhel9cis_sudo_timestamp_timeout: 15
### 5.4.2 authselect and faillock
## This option is used at your own risk it will enable faillock for users
## Only to be used on a new clean system if not using authselect
## THIS CAN BREAK ACCESS EVEN FOR ROOT - UNDERSTAND RISKS ##
rhel9cis_add_faillock_without_authselect: false
# This needs to be set to ACCEPT
rhel9cis_5_4_2_risks: NEVER
# RHEL-09-5.4.5
# Session timeout setting file (TMOUT setting can be set in multiple files)
# Timeout value is in seconds. (60 seconds * 10 = 600)
@ -627,7 +642,7 @@ rhel9cis_futurepwchgdate_autofix: true
# 5.7
# rhel9cis_sugroup: sugroup # change accordingly wheel is default
# wheel users list
# wheel users list please supply comma seperated e.g. "vagrant,root"
rhel9cis_sugroup_users: "root"
## Section6 vars
@ -650,14 +665,14 @@ audit_run_script_environment:
### Goss binary settings ###
goss_version:
release: v0.3.18
checksum: 'sha256:432308ebca0caf8165d45bd27e3262126aad9d15572ac8cb3149b3c91f75aace'
release: v0.3.21
checksum: 'sha256:9a9200779603acf0353d2c0e85ae46e083596c10838eaf4ee050c924678e4fe3'
audit_bin_path: /usr/local/bin/
audit_bin: "{{ audit_bin_path }}goss"
audit_format: json
# if get_goss_file == download change accordingly
goss_url: "https://github.com/aelsabbahy/goss/releases/download/{{ goss_version.release }}/goss-linux-amd64"
goss_url: "https://github.com/goss-org/goss/releases/download/{{ goss_version.release }}/goss-linux-amd64"
## if get_goss_file - copy the following needs to be updated for your environment
## it is expected that it will be copied from somewhere accessible to the control node

View file

@ -1,16 +1,13 @@
---
# handlers file for RHEL9-CIS
- name: reload sysctl
shell: sysctl --system
args:
warn: false
- name: Reload sysctl
ansible.builtin.shell: sysctl --system
when:
- sysctl_updated.changed
- name: sysctl flush ipv4 route table
become: true
sysctl:
- name: Sysctl flush ipv4 route table
ansible.posix.sysctl:
name: net.ipv4.route.flush
value: '1'
sysctl_set: true
@ -18,12 +15,9 @@
when:
- flush_ipv4_route
- not system_is_container
tags:
- skip_ansible_lint
- name: sysctl flush ipv6 route table
become: true
sysctl:
- name: Sysctl flush ipv6 route table
ansible.posix.sysctl:
name: net.ipv6.route.flush
value: '1'
sysctl_set: true
@ -31,98 +25,81 @@
- flush_ipv6_route
- not system_is_container
- name: systemd restart tmp.mount
become: true
systemd:
- name: Systemd restart tmp.mount
ansible.builtin.systemd:
name: tmp.mount
daemon_reload: true
daemon_Reload: true
enabled: true
masked: false
state: reloaded
state: Reloaded
- name: systemd restart var-tmp.mount
become: true
systemd:
name: var-tmp.mount
daemon_reload: true
enabled: true
masked: false
state: reloaded
- name: Remount tmp
ansible.posix.mount:
path: /tmp
state: remounted
- name: remount tmp
shell: mount -o remount /tmp
args:
warn: false
- name: restart firewalld
service:
- name: Restart firewalld
ansible.builtin.systemd:
name: firewalld
state: restarted
- name: restart sshd
service:
- name: Restart sshd
ansible.builtin.systemd:
name: sshd
state: restarted
- name: restart postfix
service:
- name: Restart postfix
ansible.builtin.systemd:
name: postfix
state: restarted
- name: reload dconf
shell: dconf update
args:
warn: false
- name: Reload dconf
ansible.builtin.shell: dconf update
- name: grub2cfg
shell: "grub2-mkconfig -o /boot/grub2/grub.cfg"
args:
warn: false
- name: Grub2cfg
ansible.builtin.shell: "grub2-mkconfig -o /boot/grub2/grub.cfg"
ignore_errors: true # noqa ignore-errors
tags:
- skip_ansible_lint
- name: restart rsyslog
become: true
service:
- name: Restart rsyslog
ansible.builtin.systemd:
name: rsyslog
state: restarted
- name: restart journald
service:
- name: Restart journald
ansible.builtin.systemd:
name: systemd-journald
state: restarted
- name: restart systemd_journal_upload
service:
- name: Restart systemd_journal_upload
ansible.builtin.systemd:
name: systemd-journal-upload
state: restarted
- name: systemd_daemon_reload
systemd:
- name: Systemd daemon reload
ansible.builtin.systemd:
daemon-reload: true
## Auditd tasks note order for handlers to run
- name: auditd_immutable_check
shell: grep -c "^-e 2" /etc/audit/rules.d/99_auditd.rules
- name: Auditd immutable check
ansible.builtin.shell: grep -c "^-e 2" /etc/audit/rules.d/99_auditd.rules
changed_when: false
register: auditd_immutable_check
- name: audit_immutable_fact
debug:
- name: Audit immutable fact
ansible.builtin.debug:
msg: "Reboot required for auditd to apply new rules as immutable set"
notify: change_requires_reboot
notify: Change_requires_reboot
when:
- auditd_immutable_check.stdout == '1'
- name: restart auditd
shell: service auditd restart
args:
warn: false
- name: Restart auditd
ansible.builtin.shell: service auditd restart
tags:
- skip_ansible_lint
- name: change_requires_reboot
set_fact:
- name: Change_requires_reboot
ansible.builtin.set_fact:
change_requires_reboot: true

View file

@ -1,7 +1,7 @@
---
galaxy_info:
author: "Sam Doran, Josh Springer, Daniel Shepherd, Bas Meijeri, James Cassell, Mike Renfro, DFed, George Nalen, Mark Bolwell"
description: "Apply the RHEL 8 CIS"
description: "Apply the RHEL 9 CIS"
company: "MindPoint Group"
license: MIT
role_name: rhel9_cis
@ -10,7 +10,7 @@ galaxy_info:
platforms:
- name: EL
versions:
- 9
- "9"
galaxy_tags:
- system
- security
@ -22,6 +22,9 @@ galaxy_info:
- complianceascode
- disa
- rhel9
- cis
- rocky
- alma
collections:
- community.general
- community.crypto

5
requirements.txt Normal file
View file

@ -0,0 +1,5 @@
passlib
lxml
xmltodict
jmespath
yamllint

View file

@ -1,4 +1,5 @@
---
- hosts: all
become: true
roles:

View file

@ -1,7 +1,7 @@
---
- name: Download audit binary
get_url:
ansible.builtin.get_url:
url: "{{ goss_url }}"
dest: "{{ audit_bin }}"
owner: root
@ -11,8 +11,8 @@
when:
- get_goss_file == 'download'
- name: copy audit binary
copy:
- name: Copy audit binary
ansible.builtin.copy:
src:
dest: "{{ audit_bin }}"
mode: 0555
@ -21,8 +21,8 @@
when:
- get_goss_file == 'copy'
- name: install git if not present
package:
- name: Install git if not present
ansible.builtin.package:
name: git
state: present
register: git_installed

View file

@ -1,26 +1,37 @@
---
- name: POST | AUDITD | Apply auditd template will for section 4.1.3 - only required rules will be added | stat file
ansible.builtin.stat:
path: /etc/audit/rules.d/99_auditd.rules
register: auditd_file
- name: POST | AUDITD | Apply auditd template will for section 4.1.3 - only required rules will be added
template:
- name: POST | AUDITD | Apply auditd template will for section 4.1.3 - only required rules will be added | setup file
ansible.builtin.template:
src: audit/99_auditd.rules.j2
dest: /etc/audit/rules.d/99_auditd.rules
owner: root
group: root
mode: 0600
mode: 0640
diff: "{{ auditd_file.stat.exists }}" # Only run diff if not a new file
register: audit_rules_updated
notify:
- auditd_immutable_check
- audit_immutable_fact
- restart auditd
- Auditd immutable check
- Audit immutable fact
- Restart auditd
- name: POST | Set up auditd user logging exceptions
template:
- name: POST | AUDITD | Apply auditd template will for section 4.1.3 - only required rules will be added | stat file
ansible.builtin.stat:
path: /etc/audit/rules.d/98_auditd_exceptions.rules
register: auditd_exception_file
- name: POST | Set up auditd user logging exceptions | setup file
ansible.builtin.template:
src: audit/98_auditd_exception.rules.j2
dest: /etc/audit/rules.d/98_auditd_exceptions.rules
owner: root
group: root
mode: 0600
notify: restart auditd
mode: 0640
diff: "{{ auditd_exception_file.stat.exists }}"
notify: Restart auditd
when:
- allow_auditd_uid_user_exclusions
- rhel9cis_auditd_uid_exclude | length > 0

View file

@ -1,7 +1,7 @@
---
- name: "PREREQ | If required install libselinux package to manage file changes."
package:
ansible.builtin.package:
name: libselinux-python3
state: present
when:

View file

@ -2,7 +2,7 @@
# tasks file for RHEL9-CIS
- name: Check OS version and family
assert:
ansible.builtin.assert:
that: (ansible_distribution != 'CentOS' and ansible_os_family == 'RedHat' or ansible_os_family == "Rocky") and ansible_distribution_major_version is version_compare('9', '==')
fail_msg: "This role can only be run against Supported OSs. {{ ansible_distribution }} {{ ansible_distribution_major_version }} is not supported."
success_msg: "This role is running against a supported OS {{ ansible_distribution }} {{ ansible_distribution_major_version }}"
@ -13,7 +13,7 @@
- always
- name: Check ansible version
assert:
ansible.builtin.assert:
that: ansible_version.full is version_compare(min_ansible_version, '>=')
fail_msg: "You must use Ansible {{ min_ansible_version }} or greater"
success_msg: "This role is running a supported version of ansible {{ ansible_version.full }} >= {{ min_ansible_version }}"
@ -23,14 +23,14 @@
- name: "Check password set for {{ ansible_user }}"
block:
- name: Capture current password state of "{{ ansible_user }}"
shell: "grep {{ ansible_user }} /etc/shadow | awk -F: '{print $2}'"
ansible.builtin.shell: "grep {{ ansible_user }} /etc/shadow | awk -F: '{print $2}'"
changed_when: false
failed_when: false
check_mode: false
register: ansible_user_password_set
- name: "Assert that password set for {{ ansible_user }} and account not locked"
assert:
ansible.builtin.assert:
that: ansible_user_password_set.stdout | length != 0 and ansible_user_password_set.stdout != "!!"
fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_user }} has no password set - It can break access"
success_msg: "You a password set for the {{ ansible_user }}"
@ -42,18 +42,40 @@
tags:
- user_passwd
- name: "Ensure root password is set"
block:
- name: "Ensure root password is set"
ansible.builtin.shell: passwd -S root | grep "Password set, SHA512 crypt"
changed_when: false
register: root_passwd_set
- name: "Ensure root password is set"
ansible.builtin.assert:
that: root_passwd_set.rc == 0
fail_msg: "You have rule 5.6.6 enabled this requires that you have a root password set"
success_msg: "You have a root password set"
when:
- rhel9cis_rule_5_6_6
tags:
- level1-server
- level1-workstation
- patch
- accounts
- root
- rule_5.6.6
- name: Setup rules if container
block:
- name: Discover and set container variable if required
set_fact:
ansible.builtin.set_fact:
system_is_container: true
- name: Load variable for container
include_vars:
ansible.builtin.include_vars:
file: "{{ container_vars_file }}"
- name: output if discovered is a container
debug:
- name: Output if discovered is a container
ansible.builtin.debug:
msg: system has been discovered as a container
when:
- system_is_container
@ -65,13 +87,13 @@
- always
- name: Check crypto-policy input
assert:
ansible.builtin.assert:
that: rhel9cis_crypto_policy in rhel9cis_allowed_crypto_policies
fail_msg: "Crypto policy is not a permitted version"
success_msg: "Crypto policy is a permitted version"
- name: Check rhel9cis_bootloader_password_hash variable has been changed
assert:
ansible.builtin.assert:
that: rhel9cis_bootloader_password_hash.find('grub.pbkdf2.sha512') != -1 and rhel9cis_bootloader_password_hash != 'grub.pbkdf2.sha512.changethispassword'
msg: "This role will not be able to run single user password commands as rhel9cis_bootloader_password_hash variable has not been set correctly"
when:
@ -80,132 +102,90 @@
tags:
- always
- name: "check sugroup exists if used"
block:
- name: "Check su group exists if defined"
shell: grep -w "{{ rhel9cis_sugroup }}" /etc/group
args:
warn: false
register: sugroup_exists
changed_when: false
failed_when: sugroup_exists.rc >= 2
tags:
- skip_ansible_lint
- name: Check sugroup if defined exists before continuing
assert:
that: sugroup_exists.rc == 0
msg: "The variable rhel9cis_sugroup is defined but does not exist please rectify"
when:
- rhel9cis_sugroup is defined
- rhel9cis_rule_5_7
tags:
- rule_5.7
- name: Gather the package facts
package_facts:
ansible.builtin.package_facts:
manager: auto
tags:
- always
- name: Include OS specific variables
include_vars: "{{ ansible_distribution }}.yml"
ansible.builtin.include_vars: "{{ ansible_distribution }}.yml"
tags:
- always
- name: Include preliminary steps
import_tasks: prelim.yml
ansible.builtin.import_tasks: prelim.yml
tags:
- prelim_tasks
- always
- name: run pre_remediation audit
include_tasks: pre_remediation_audit.yml
ansible.builtin.include_tasks: pre_remediation_audit.yml
when:
- run_audit
- name: Gather the package facts after prelim
package_facts:
manager: auto
tags:
- always
- name: capture /etc/password variables
include_tasks: parse_etc_password.yml
when:
- rhel9cis_section6
tags:
- rule_5.5.2
- rule_5.6.2
- rule_6.2.9
- rule_6.2.10
- rule_6.2.11
- rhel9cis_section5
- rhel9cis_section6
- name: run Section 1 tasks
import_tasks: section_1/main.yml
ansible.builtin.import_tasks: section_1/main.yml
when: rhel9cis_section1
tags:
- rhel9cis_section1
- name: run Section 2 tasks
import_tasks: section_2/main.yml
ansible.builtin.import_tasks: section_2/main.yml
when: rhel9cis_section2
tags:
- rhel9cis_section2
- name: run Section 3 tasks
import_tasks: section_3/main.yml
ansible.builtin.import_tasks: section_3/main.yml
when: rhel9cis_section3
tags:
- rhel9cis_section3
- name: run Section 4 tasks
import_tasks: section_4/main.yml
ansible.builtin.import_tasks: section_4/main.yml
when: rhel9cis_section4
tags:
- rhel9cis_section4
- name: run Section 5 tasks
import_tasks: section_5/main.yml
ansible.builtin.import_tasks: section_5/main.yml
when: rhel9cis_section5
tags:
- rhel9cis_section5
- name: run Section 6 tasks
import_tasks: section_6/main.yml
ansible.builtin.import_tasks: section_6/main.yml
when: rhel9cis_section6
tags:
- rhel9cis_section6
- name: run auditd logic
import_tasks: auditd.yml
when:
- update_audit_template
ansible.builtin.import_tasks: auditd.yml
when: update_audit_template
tags:
- always
- name: run post remediation tasks
import_tasks: post.yml
ansible.builtin.import_tasks: post.yml
tags:
- post_tasks
- always
- name: run post_remediation audit
import_tasks: post_remediation_audit.yml
ansible.builtin.import_tasks: post_remediation_audit.yml
when:
- run_audit
- name: Show Audit Summary
debug:
ansible.builtin.debug:
msg: "{{ audit_results.split('\n') }}"
when:
- run_audit
when: run_audit
- name: If Warnings found Output count and control IDs affected
debug:
msg: "You have {{ warn_count }} Warning(s) that require investigating that are related to the following benchmark ID(s) {{ control_number }}"
ansible.builtin.debug:
msg: "You have {{ warn_count }} Warning(s) that require investigating that are related to the following benchmark ID(s) {{ warn_control_list }}"
when: warn_count != 0
tags:
- always

View file

@ -3,15 +3,15 @@
- name: "PRELIM | 5.5.2 | 6.2.7 | 6.2.8 | 6.2.20 | Parse /etc/passwd"
block:
- name: "PRELIM | 5.5.2 | 6.2.7 | 6.2.8 | 6.2.20 | Parse /etc/passwd"
shell: cat /etc/passwd
ansible.builtin.shell: cat /etc/passwd
changed_when: false
check_mode: false
register: rhel9cis_passwd_file_audit
- name: "PRELIM | 5.5.2 | 6.2.7 | 6.2.8 | 6.2.20 | Split passwd entries"
set_fact:
ansible.builtin.set_fact:
rhel9cis_passwd: "{{ rhel9cis_passwd_file_audit.stdout_lines | map('regex_replace', ld_passwd_regex, ld_passwd_yaml) | map('from_yaml') | list }}"
with_items: "{{ rhel9cis_passwd_file_audit.stdout_lines }}"
loop: "{{ rhel9cis_passwd_file_audit.stdout_lines }}"
vars:
ld_passwd_regex: >-
^(?P<id>[^:]*):(?P<password>[^:]*):(?P<uid>[^:]*):(?P<gid>[^:]*):(?P<gecos>[^:]*):(?P<dir>[^:]*):(?P<shell>[^:]*)

View file

@ -1,27 +1,22 @@
---
# Post tasks
- name: Perform DNF package cleanup
dnf:
autoremove: true
changed_when: false
- name: Gather the package facts after remediation
package_facts:
ansible.builtin.package_facts:
manager: auto
tags:
- always
- name: update sysctl
template:
- name: Update sysctl
ansible.builtin.template:
src: "etc/sysctl.d/{{ item }}.j2"
dest: "/etc/sysctl.d/{{ item }}"
owner: root
group: root
mode: 0600
register: sysctl_updated
notify: reload sysctl
with_items:
notify: Reload sysctl
loop:
- 60-kernel_sysctl.conf
- 60-disable_ipv6.conf
- 60-netipv4_sysctl.conf
@ -31,19 +26,19 @@
- not system_is_container
- "'procps-ng' in ansible_facts.packages"
- name: flush handlers
meta: flush_handlers
- name: Flush handlers
ansible.builtin.meta: flush_handlers
- name: POST | reboot system if changes require it and not skipped
block:
- name: POST | Reboot system if changes require it and not skipped
reboot:
ansible.builtin.reboot:
when:
- change_requires_reboot
- not skip_reboot
- name: POST | Warning a reboot required but skip option set
debug:
ansible.builtin.debug:
msg: "Warning!! changes have been made that require a reboot to be implemented but skip reboot was set - Can affect compliance check results"
changed_when: true
when:
@ -51,13 +46,12 @@
- skip_reboot
- name: "POST | Warning a reboot required but skip option set | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'Reboot_required' ]"
warn_count: "{{ warn_count | int + 1 }}"
ansible.builtin.import_tasks: warning_facts.yml
when:
- change_requires_reboot
- skip_reboot
vars:
warn_control_id: Reboot_required
tags:
- grub
- level1-server

View file

@ -1,15 +1,13 @@
---
- name: "Post Audit | Run post_remediation {{ benchmark }} audit"
shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }}"
ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }}"
environment: "{{ audit_run_script_environment | default({}) }}"
changed_when: audit_run_post_remediation.rc == 0
register: audit_run_post_remediation
args:
warn: false
- name: Post Audit | ensure audit files readable by users
file:
ansible.builtin.file:
path: "{{ item }}"
mode: 0644
state: file
@ -19,15 +17,13 @@
- name: Post Audit | Capture audit data if json format
block:
- name: "capture data {{ post_audit_outfile }}"
shell: "cat {{ post_audit_outfile }}"
args:
warn: false
- name: "Capture data {{ post_audit_outfile }}"
ansible.builtin.shell: "cat {{ post_audit_outfile }}"
register: post_audit
changed_when: false
- name: Capture post-audit result
set_fact:
ansible.builtin.set_fact:
post_audit_summary: "{{ post_audit.stdout | from_json | json_query(summary) }}"
vars:
summary: 'summary."summary-line"'
@ -37,14 +33,12 @@
- name: Post Audit | Capture audit data if documentation format
block:
- name: "Post Audit | capture data {{ post_audit_outfile }}"
shell: "tail -2 {{ post_audit_outfile }}"
args:
warn: false
ansible.builtin.shell: "tail -2 {{ post_audit_outfile }}"
register: post_audit
changed_when: false
- name: Post Audit | Capture post-audit result
set_fact:
ansible.builtin.set_fact:
post_audit_summary: "{{ post_audit.stdout_lines }}"
when:
- audit_format == "documentation"

View file

@ -1,20 +1,20 @@
---
- name: Pre Audit | Setup the audit
include_tasks: LE_audit_setup.yml
ansible.builtin.include_tasks: LE_audit_setup.yml
when:
- setup_audit
tags:
- setup_audit
- name: "Pre Audit | Ensure {{ audit_conf_dir }} exists"
file:
ansible.builtin.file:
path: "{{ audit_conf_dir }}"
state: directory
mode: '0755'
- name: Pre Audit | retrieve audit content files from git
git:
ansible.builtin.git:
repo: "{{ audit_file_git }}"
dest: "{{ audit_conf_dir }}"
version: "{{ audit_git_version }}"
@ -22,7 +22,7 @@
- audit_content == 'git'
- name: Pre Audit | copy to audit content files to server
copy:
ansible.builtin.copy:
src: "{{ audit_local_copy }}"
dest: "{{ audit_conf_dir }}"
mode: 0644
@ -30,7 +30,7 @@
- audit_content == 'copy'
- name: Pre Audit | get audit content from url
get_url:
ansible.builtin.get_url:
url: "{{ audit_files_url }}"
dest: "{{ audit_conf_dir }}"
owner: root
@ -42,27 +42,26 @@
- name: Pre Audit | Check Goss is available
block:
- name: Pre Audit | Check for goss file
stat:
ansible.builtin.stat:
path: "{{ audit_bin }}"
register: goss_available
- name: Pre Audit | Alert if goss not available
assert:
ansible.builtin.assert:
that: goss_available.stat.exists
fail_msg: "Audit binary file {{ audit_bin }} does not exist"
success_msg: "Audit binary file {{ audit_bin }} exists"
when:
- run_audit
- name: "Pre Audit | Check whether machine is UEFI-based"
stat:
ansible.builtin.stat:
path: /sys/firmware/efi
register: rhel9_efi_boot
tags:
- goss_template
- name: Pre Audit | Copy ansible default vars values to test audit
template:
ansible.builtin.template:
src: ansible_vars_goss.yml.j2
dest: "{{ audit_vars_path }}"
mode: 0600
@ -72,24 +71,20 @@
- goss_template
- name: "Pre Audit | Run pre_remediation {{ benchmark }} audit"
shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }}"
ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }}"
environment: "{{ audit_run_script_environment | default({}) }}"
changed_when: audit_run_pre_remediation.rc == 0
register: audit_run_pre_remediation
args:
warn: false
- name: Pre Audit | Capture audit data if json format
block:
- name: "Pre Audit | capture data {{ pre_audit_outfile }}"
shell: "cat {{ pre_audit_outfile }}"
args:
warn: false
ansible.builtin.shell: "cat {{ pre_audit_outfile }}"
register: pre_audit
changed_when: false
- name: Pre Audit | Capture pre-audit result
set_fact:
ansible.builtin.set_fact:
pre_audit_summary: "{{ pre_audit.stdout | from_json | json_query(summary) }}"
vars:
summary: 'summary."summary-line"'
@ -99,14 +94,12 @@
- name: Pre Audit | Capture audit data if documentation format
block:
- name: "Pre Audit | capture data {{ pre_audit_outfile }}"
shell: "tail -2 {{ pre_audit_outfile }}"
args:
warn: false
ansible.builtin.shell: "tail -2 {{ pre_audit_outfile }}"
register: pre_audit
changed_when: false
- name: Pre Audit | Capture pre-audit result
set_fact:
ansible.builtin.set_fact:
pre_audit_summary: "{{ pre_audit.stdout_lines }}"
when:
- audit_format == "documentation"

View file

@ -3,9 +3,7 @@
# Preliminary tasks that should always be run
# List users in order to look files inside each home directory
- name: "PRELIM | List users accounts"
shell: "awk -F: '{print $1}' /etc/passwd"
args:
warn: false
ansible.builtin.shell: "awk -F: '{print $1}' /etc/passwd"
changed_when: false
check_mode: false
register: users
@ -14,10 +12,27 @@
- level1-workstation
- users
- name: "PRELIM | capture /etc/password variables"
ansible.builtin.include_tasks: parse_etc_password.yml
tags:
- rule_5.5.2
- rule_5.6.2
- rule_6.2.9
- rule_6.2.10
- rule_6.2.11
- rhel9cis_section5
- rhel9cis_section6
- level1-server
- name: "PRELIM | Interactive User accounts"
ansible.builtin.shell: 'cat /etc/passwd | grep -Ev "nologin|/sbin" | cut -d: -f6'
changed_when: false
register: interactive_users_home
tags:
- always
- name: "PRELIM | Gather accounts with empty password fields"
shell: "cat /etc/shadow | awk -F: '($2 == \"\" ) {j++;print $1; } END {exit j}'"
args:
warn: false
ansible.builtin.shell: "cat /etc/shadow | awk -F: '($2 == \"\" ) {j++;print $1; } END {exit j}'"
changed_when: false
check_mode: false
register: empty_password_accounts
@ -27,14 +42,12 @@
- passwords
- name: "PRELIM | Gather UID 0 accounts other than root"
shell: "cat /etc/passwd | awk -F: '($3 == 0 && $1 != \"root\") {i++;print $1 } END {exit i}'"
args:
warn: false
ansible.builtin.shell: "cat /etc/passwd | awk -F: '($3 == 0 && $1 != \"root\") {i++;print $1 } END {exit i}'"
changed_when: false
check_mode: false
register: rhel9cis_uid_zero_accounts_except_root
tags:
- rule_6.2.8
- rule_6.2.9
- level1-server
- level1-workstation
- users
@ -42,16 +55,14 @@
- name: "PRELIM | Setup crypto-policy"
block:
- name: "PRELIM | Install crypto-policies"
dnf:
ansible.builtin.package:
name:
- crypto-policies
- crypto-policies-scripts
state: present
- name: "PRELIM | Gather system-wide crypto-policy"
shell: update-crypto-policies --show
args:
warn: false
ansible.builtin.shell: update-crypto-policies --show
changed_when: false
check_mode: false
register: system_wide_crypto_policy
@ -64,7 +75,7 @@
- crypto
- name: "PRELIM | if systemd coredump"
stat:
ansible.builtin.stat:
path: /etc/systemd/coredump.conf
register: systemd_coredump
when:
@ -76,14 +87,14 @@
- systemd
- name: "PRELIM | Section 1.1 | Create list of mount points"
set_fact:
ansible.builtin.set_fact:
mount_names: "{{ ansible_mounts | map(attribute='mount') | list }}"
tags:
- level1-server
- level1-workstation
- name: "PRELIM | Ensure python3-libselinux is installed"
package:
ansible.builtin.package:
name: python3-libselinux
state: present
when:
@ -92,23 +103,31 @@
- name: "PRELIM | Set facts based on boot type"
block:
- name: "PRELIM | Check whether machine is UEFI-based"
stat:
ansible.builtin.stat:
path: /sys/firmware/efi
register: rhel_09_efi_boot
- name: "PRELIM | AUDIT | set legacy boot and grub path | Bios"
set_fact:
- name: "PRELIM | set legacy boot and grub path | Bios"
ansible.builtin.set_fact:
rhel9cis_legacy_boot: true
grub2_path: /etc/grub2.cfg
when: not rhel_09_efi_boot.stat.exists
- name: "PRELIM | set grub fact | UEFI"
set_fact:
ansible.builtin.set_fact:
grub2_path: /etc/grub2-efi.cfg
when: rhel_09_efi_boot.stat.exists
- name: "PRELIM | Update to latest gpg keys"
ansible.builtin.package:
name: "{{ ansible_distribution | lower }}-gpg-keys"
state: latest
when:
- rhel9cis_rule_1_2_4
- ansible_distribution != 'RedHat'
- name: "PRELIM | Section 4.1 | Configure System Accounting (auditd)"
package:
ansible.builtin.package:
name: audit
state: present
become: true
@ -122,19 +141,28 @@
- rule_4.1.1.1
- auditd
- name: "PRELIM | 4.1.12 | 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
changed_when: false
failed_when: false
check_mode: false
register: priv_procs
- name: "PRELIM | 4.1.4.5 | Audit conf and rules files | list files"
ansible.builtin.find:
path: /etc/audit
file_type: file
recurse: true
patterns: '*.conf,*.rules'
register: auditd_conf_files
when:
- rhel9cis_rule_4_1_4_5 or
rhel9cis_rule_4_1_4_6 or
rhel9cis_rule_4_1_4_7
tags:
- level1-server
- level1-workstation
- always
- level2-server
- level2-workstation
- patch
- auditd
- rule_4.1.4.5
- rule_4.1.4.6
- rule_4.1.4.7
- name: "PRELIM | Section 5.1 | Configure cron"
package:
ansible.builtin.package:
name: cronie
state: present
become: true
@ -148,7 +176,7 @@
- cron
- name: "PRELIM | Install authconfig"
package:
ansible.builtin.package:
name: authconfig
state: present
become: true
@ -169,7 +197,7 @@
- auditd
- name: "PRELIM | 5.3.4 | Find all sudoers files."
command: "find /etc/sudoers /etc/sudoers.d/ -type f ! -name '*~' ! -name '*.*'"
ansible.builtin.shell: "find /etc/sudoers /etc/sudoers.d/ -type f ! -name '*~' ! -name '*.*'"
changed_when: false
failed_when: false
check_mode: false
@ -181,45 +209,58 @@
- rule_5.3.4
- rule_5.3.5
- name: "PRELIM | Check for rhnsd service"
shell: "systemctl show rhnsd | grep LoadState | cut -d = -f 2"
changed_when: false
check_mode: false
become: true
register: rhnsd_service_status
when:
- rhel9cis_rule_1_2_2
- ansible_distribution == "RedHat"
tags:
- rule_1.2.2
- skip_ansible_lint
- name: "PRELIM | AUDIT | Discover Interactive UID MIN and MIN from logins.def"
- name: "PRELIM | Check sugroup exists if used"
block:
- name: "PRELIM | AUDIT | Capture UID_MIN information from logins.def"
shell: grep -w "^UID_MIN" /etc/login.defs | awk '{print $NF}'
- name: "PRELIM | Check su group exists if defined"
ansible.builtin.shell: grep -w "{{ rhel9cis_sugroup }}" /etc/group
register: sugroup_exists
changed_when: false
failed_when: sugroup_exists.rc >= 2
tags:
- skip_ansible_lint
- name: "PRELIM | Check sugroup if defined exists before continuing"
ansible.builtin.assert:
that: sugroup_exists.rc == 0
msg: "The variable rhel9cis_sugroup is defined but does not exist please rectify"
when:
- rhel9cis_sugroup is defined
- rhel9cis_rule_5_7
tags:
- rule_5.7
- name: "PRELIM | Discover Interactive UID MIN and MIN from logins.def"
block:
- name: "PRELIM | Capture UID_MIN information from logins.def"
ansible.builtin.shell: grep -w "^UID_MIN" /etc/login.defs | awk '{print $NF}'
changed_when: false
register: uid_min_id
- name: "PRELIM | AUDIT | Capture UID_MAX information from logins.def"
shell: grep -w "^UID_MAX" /etc/login.defs | awk '{print $NF}'
- name: "PRELIM | Capture UID_MAX information from logins.def"
ansible.builtin.shell: grep -w "^UID_MAX" /etc/login.defs | awk '{print $NF}'
changed_when: false
register: uid_max_id
- name: "PRELIM | AUDIT | Capture GID_MIN information from logins.def"
shell: grep -w "^GID_MIN" /etc/login.defs | awk '{print $NF}'
- name: "PRELIM | Capture GID_MIN information from logins.def"
ansible.builtin.shell: grep -w "^GID_MIN" /etc/login.defs | awk '{print $NF}'
changed_when: false
register: gid_min_id
- name: "PRELIM | AUDIT | set_facts for interactive uid/gid"
set_fact:
- name: "PRELIM | set_facts for interactive uid/gid"
ansible.builtin.set_fact:
min_int_uid: "{{ uid_min_id.stdout }}"
max_int_uid: "{{ uid_max_id.stdout }}"
min_int_gid: "{{ gid_min_id.stdout }}"
- name: Output of uid findings
debug:
- name: "PRELIM | Output of uid findings"
ansible.builtin.debug:
msg: "{{ min_int_uid }} {{ max_int_uid }}"
when:
- not discover_int_uid
- name: "PRELIM | Gather the package facts after prelim"
ansible.builtin.package_facts:
manager: auto
tags:
- always

View file

@ -1,76 +1,66 @@
---
- name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled"
- name: "1.1.1.1 | PATCH | Ensure mounting of squashfs filesystems is disabled"
block:
- name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled | Edit modprobe config"
lineinfile:
path: /etc/modprobe.d/CIS.conf
regexp: "^(#)?install cramfs(\\s|$)"
line: "install cramfs /bin/true"
create: true
mode: 0600
- name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled | Disable cramfs"
modprobe:
name: cramfs
state: absent
when: not system_is_container
when:
- rhel9cis_rule_1_1_1_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_1.1.1.1
- cramfs
- name: "1.1.1.2 | PATCH | Ensure mounting of squashfs filesystems is disabled"
block:
- name: "1.1.1.2 | PATCH | Ensure mounting of squashfs filesystems is disabled | Edit modprobe config"
lineinfile:
- name: "1.1.1.1 | PATCH | Ensure mounting of squashfs filesystems is disabled | Edit modprobe config"
ansible.builtin.lineinfile:
path: /etc/modprobe.d/CIS.conf
regexp: "^(#)?install squashfs(\\s|$)"
line: "install squashfs /bin/true"
create: true
mode: 0600
- name: "1.1.1.2 | PATCH | Ensure mounting of squashfs filesystems is disabled | Disable squashfs"
modprobe:
- name: "1.1.1.1 | PATCH | Ensure mounting of squashfs filesystems is disabled | blacklist"
ansible.builtin.lineinfile:
path: /etc/modprobe.d/blacklist.conf
regexp: "^(#)?blacklist squashfs(\\s|$)"
line: "blacklist squashfs"
create: true
mode: 0600
- name: "1.1.1.1 | PATCH | Ensure mounting of squashfs filesystems is disabled | Disable squashfs"
community.general.modprobe:
name: squashfs
state: absent
when: not system_is_container
when:
- rhel9cis_rule_1_1_1_1
tags:
- level2-server
- level2-workstation
- patch
- rule_1.1.1.1
- squashfs
- name: "1.1.1.2 | PATCH | Ensure mounting of udf filesystems is disabled"
block:
- name: "1.1.1.2 | PATCH | Ensure mounting of udf filesystems is disable | Edit modprobe config"
ansible.builtin.lineinfile:
path: /etc/modprobe.d/CIS.conf
regexp: "^(#)?install udf(\\s|$)"
line: "install udf /bin/true"
create: true
mode: 0600
- name: "1.1.1.2 | PATCH | Ensure mounting of udf filesystems is disabled | blacklist"
ansible.builtin.lineinfile:
path: /etc/modprobe.d/blacklist.conf
regexp: "^(#)?blacklist udf(\\s|$)"
line: "blacklist udf"
create: true
mode: 0600
- name: "1.1.1.2 | PATCH | Ensure mounting of udf filesystems is disable | Disable udf"
community.general.modprobe:
name: udf
state: absent
when: not system_is_container
when:
- rhel9cis_rule_1_1_1_2
tags:
- level2-server
- level2-workstation
- automated
- patch
- rule_1.1.1.2
- squashfs
- name: "1.1.1.3 | PATCH | Ensure mounting of udf filesystems is disabled"
block:
- name: "1.1.1.3 | PATCH | Ensure mounting of udf filesystems is disable | Edit modprobe config"
lineinfile:
path: /etc/modprobe.d/CIS.conf
regexp: "^(#)?install udf(\\s|$)"
line: "install udf /bin/true"
create: true
mode: 0600
- name: "1.1.1.3 | PATCH | Ensure mounting of udf filesystems is disable | Disable udf"
modprobe:
name: udf
state: absent
when: not system_is_container
when:
- rhel9cis_rule_1_1_1_3
tags:
- level2-server
- level2-workstation
- automated
- patch
- rule_1.1.1.3
- udf

View file

@ -3,32 +3,20 @@
- name: "1.1.2.1 | PATCH | Ensure /tmp is a separate partition"
block:
- name: "1.1.2.1 | PATCH | Ensure /tmp is a separate partition | Absent"
debug:
msg: "Warning!! /tmp is not mounted on a separate partition"
when:
- required_mount not in mount_names
ansible.builtin.debug:
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
- name: "1.1.2.1 | PATCH | Ensure /tmp is a separate partition | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.2.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.3.1 | AUDIT | Ensure separate partition exists for /var | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."
register: var_mount_present
when:
- required_mount in mount_names
- name: "1.1.2.1 | PATCH | Ensure /tmp is a separate partition | Present"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '1.1.2.1'
required_mount: '/tmp'
when:
- required_mount not in mount_names
- rhel9cis_rule_1_1_2_1
tags:
- level1-server
- level1-workstation
- automated
- audit
- mounts
- rule_1.1.2.1
@ -38,15 +26,14 @@
"1.1.2.2 | PATCH | Ensure nodev option set on /tmp partition"
"1.1.2.3 | PATCH | Ensure noexec option set on /tmp partition"
"1.1.2.4 | PATCH | Ensure nosuid option set on /tmp partition"
mount:
ansible.builtin.mount:
name: /tmp
src: "{{ item.device }}"
fstype: "{{ item.fstype }}"
state: present
opts: defaults,{% if rhel9cis_rule_1_1_2_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_2_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_2_4 %}nosuid{% endif %}
notify: remount tmp
with_items:
- "{{ ansible_mounts }}"
notify: Remount tmp
loop: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.device }}"
when:
@ -58,7 +45,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- mounts
- rule_1.1.2.2
@ -71,13 +57,13 @@
"1.1.2.2 | PATCH | Ensure nodev option set on /tmp partition"
"1.1.2.3 | PATCH | Ensure noexec option set on /tmp partition"
"1.1.2.4 | PATCH | Ensure nosuid option set on /tmp partition"
template:
ansible.builtin.template:
src: etc/systemd/system/tmp.mount.j2
dest: /etc/systemd/system/tmp.mount
owner: root
group: root
mode: 0644
notify: systemd restart tmp.mount
notify: Systemd restart tmp.mount
when:
- rhel9cis_tmp_svc
- rhel9cis_rule_1_1_2_1 or

View file

@ -3,34 +3,20 @@
- name: "1.1.3.1 | AUDIT | Ensure separate partition exists for /var"
block:
- name: "1.1.3.1 | AUDIT | Ensure separate partition exists for /var | Absent"
debug:
ansible.builtin.debug:
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
register: var_mount_absent
changed_when: var_mount_absent.skipped is undefined
when:
- required_mount not in mount_names
- name: "1.1.3.1 | AUDIT | Ensure separate partition exists for /var | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.3.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.3.1 | AUDIT | Ensure separate partition exists for /var | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."
register: var_mount_present
when:
- required_mount in mount_names
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '1.1.3.1'
required_mount: '/var'
when:
- required_mount not in mount_names
- rhel9cis_rule_1_1_3_1
tags:
- level2-server
- level2-workstation
- automated
- patch
- mounts
- rule_1.1.3.1
@ -38,33 +24,26 @@
# skips if mount is absent
- name: |
"1.1.3.2 | PATCH | Ensure nodev option set on /var partition"
"1.1.3.3 | PATCH | Ensure noexec option set on /var partition"
"1.1.3.4 | PATCH | Ensure nosuid option set on /var partition"
mount:
"1.1.3.3 | PATCH | Ensure nosuid option set on /var partition"
ansible.builtin.mount:
name: /var
src: "{{ item.device }}"
fstype: "{{ item.fstype }}"
state: present
opts: defaults,{% if rhel9cis_rule_1_1_3_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_3_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_3_4 %}nosuid{% endif %}
with_items:
- "{{ ansible_mounts }}"
opts: defaults,{% if rhel9cis_rule_1_1_3_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_3_3 %}nosuid,{% endif %}
loop: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.device }}"
notify: change_requires_reboot
notify: Change_requires_reboot
when:
- var_mount_present is defined
- item.mount == "/var"
- rhel9cis_rule_1_1_3_1 # This is required so the check takes place
- rhel9cis_rule_1_1_3_2 or
rhel9cis_rule_1_1_3_3 or
rhel9cis_rule_1_1_3_4
rhel9cis_rule_1_1_3_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- mounts
- skip_ansible_lint
- rule_1.1.3.2
- rule_1.1.3.3
- rule_1.1.3.4

View file

@ -4,34 +4,20 @@
- name: "1.1.4.1 | AUDIT | Ensure separate partition exists for /var/tmp"
block:
- name: "1.1.4.1 | AUDIT | Ensure separate partition exists for /var/tmp | Absent"
debug:
ansible.builtin.debug:
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
register: var_tmp_mount_absent
changed_when: var_tmp_mount_absent.skipped is undefined
when:
- required_mount not in mount_names
- name: "1.1.4.1 | AUDIT | Ensure separate partition exists for /var/tmp | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.4.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.4.1 | AUDIT | Ensure separate partition exists for /var/tmp | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."
register: var_tmp_mount_present
when:
- required_mount in mount_names
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '1.1.4.1'
required_mount: '/var/tmp'
when:
- required_mount not in mount_names
- rhel9cis_rule_1_1_4_1
tags:
- level2-server
- level2-workstation
- automated
- audit
- mounts
- rule_1.1.4.1
@ -41,28 +27,24 @@
"1.1.4.2 | PATCH | Ensure noexec option set on /var/tmp partition"
"1.1.4.3 | PATCH | Ensure nosuid option set on /var/tmp partition"
"1.1.4.4 | PATCH | Ensure nodev option set on /var/tmp partition"
mount:
ansible.builtin.mount:
name: /var/tmp
src: "{{ item.device }}"
fstype: "{{ item.fstype }}"
state: present
opts: defaults,{% if rhel9cis_rule_1_1_4_2 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_4_4 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_4_3 %}nosuid{% endif %}
with_items:
- "{{ ansible_mounts }}"
opts: defaults,{% if rhel9cis_rule_1_1_4_2 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_4_3 %}nosuid,{% endif %}{% if rhel9cis_rule_1_1_4_4 %}nodev{% endif %}
loop: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.device }}"
notify: change_requires_reboot
notify: Change_requires_reboot
when:
- var_tmp_mount_present is defined
- item.mount == "/var/tmp"
- rhel9cis_rule_1_1_4_1 # This is required so the check takes place
- rhel9cis_rule_1_1_4_2 or
rhel9cis_rule_1_1_4_3 or
rhel9cis_rule_1_1_4_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- mounts
- skip_ansible_lint

View file

@ -3,34 +3,21 @@
- name: "1.1.5.1 | AUDIT | Ensure separate partition exists for /var/log"
block:
- name: "1.1.5.1 | AUDIT | Ensure separate partition exists for /var/log | Absent"
debug:
ansible.builtin.debug:
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
register: var_log_mount_absent
changed_when: var_log_mount_absent.skipped is undefined
when:
- required_mount not in mount_names
- name: "1.1.5.1 | AUDIT | Ensure separate partition exists for /var/log | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.5.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.5.1 | AUDIT | Ensure separate partition exists for /var/log | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."
register: var_log_mount_present
when:
- required_mount in mount_names
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '1.1.5.1'
required_mount: '/var/log'
when:
- required_mount not in mount_names
- rhel9cis_rule_1_1_5_1
tags:
- level2-server
- level2-workstation
- automated
- audit
- mounts
- rule_1.1.5.1
@ -40,28 +27,24 @@
"1.1.5.2 | PATCH | Ensure nodev option set on /var/log partition"
"1.1.5.3 | PATCH | Ensure noexec option set on /var/log partition"
"1.1.5.4 | PATCH | Ensure nosuid option set on /var/log partition"
mount:
ansible.builtin.mount:
name: /var/log
src: "{{ item.device }}"
fstype: "{{ item.fstype }}"
state: present
opts: defaults,{% if rhel9cis_rule_1_1_5_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_5_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_5_4 %}nosuid{% endif %}
with_items:
- "{{ ansible_mounts }}"
opts: defaults,{% if rhel9cis_rule_1_1_5_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_5_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_5_4 %}nosuid{% endif %}
loop: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.device }}"
notify: change_requires_reboot
notify: Change_requires_reboot
when:
- var_log_mount_present is defined
- item.mount == "/var/log"
- rhel9cis_rule_1_1_5_1 # This is required so the check takes place
- rhel9cis_rule_1_1_5_2 or
rhel9cis_rule_1_1_5_3 or
rhel9cis_rule_1_1_5_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- mounts
- skip_ansible_lint

View file

@ -3,34 +3,21 @@
- name: "1.1.6.1 | AUDIT | Ensure separate partition exists for /var/log/audit"
block:
- name: "1.1.6.1 | AUDIT | Ensure separate partition exists for /var/log/audit | Absent"
debug:
ansible.builtin.debug:
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
register: var_log_audit_mount_absent
changed_when: var_log_audit_mount_absent.skipped is undefined
when:
- required_mount not in mount_names
- name: "1.1.6.1 | AUDIT | Ensure separate partition exists for /var/log/audit | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.6.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.6.1 | AUDIT | Ensure separate partition exists for /var/log/audit | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."
register: var_log_audit_mount_present
when:
- required_mount in mount_names
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '1.1.6.1'
required_mount: '/var/log/audit'
when:
- required_mount not in mount_names
- rhel9cis_rule_1_1_6_1
tags:
- level2-server
- level2-workstation
- automated
- audit
- mounts
- rule_1.1.6.1
@ -39,28 +26,24 @@
"1.1.6.2 | PATCH | Ensure noexec option set on /var/log/audit partition"
"1.1.6.3 | PATCH | Ensure nodev option set on /var/log/audit partition"
"1.1.6.4 | PATCH | Ensure nosuid option set on /var/log/audit partition"
mount:
ansible.builtin.mount:
name: /var/log/audit
src: "{{ item.device }}"
fstype: "{{ item.fstype }}"
state: present
opts: defaults,{% if rhel9cis_rule_1_1_6_2 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_6_3 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_6_4 %}nosuid{% endif %}
with_items:
- "{{ ansible_mounts }}"
loop: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.device }}"
notify: change_requires_reboot
notify: Change_requires_reboot
when:
- var_log_audit_mount_present is defined
- item.mount == "/var/log/audit"
- rhel9cis_rule_1_1_6_1 # This is required so the check takes place
- rhel9cis_rule_1_1_6_2 or
rhel9cis_rule_1_1_6_3 or
rhel9cis_rule_1_1_6_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- mounts
- skip_ansible_lint

View file

@ -3,34 +3,21 @@
- name: "1.1.7.1 | AUDIT | Ensure separate partition exists for /home"
block:
- name: "1.1.7.1 | AUDIT | Ensure separate partition exists for /home | Absent"
debug:
ansible.builtin.debug:
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
register: home_mount_absent
changed_when: home_mount_absent.skipped is undefined
when:
- required_mount not in mount_names
- name: "1.1.7.1 | AUDIT | Ensure separate partition exists for /home | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.7.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.7.1 | AUDIT | Ensure separate partition exists for /home | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."
register: home_mount_present
when:
- required_mount in mount_names
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '1.1.7.1'
required_mount: '/home'
when:
- required_mount not in mount_names
- rhel9cis_rule_1_1_7_1
tags:
- level2-server
- level2-workstation
- automated
- audit
- mounts
- rule_1.1.7.1
@ -38,32 +25,25 @@
- name: |
"1.1.7.2 | PATCH | Ensure nodev option set on /home partition
1.1.7.3 | PATCH | Ensure nosuid option set on /home partition
1.1.7.4 | PATCH | Ensure usrquota option set on /home partition
1.1.7.5 | PATCH | Ensure grpquota option set on /home partition"
mount:
1.1.7.3 | PATCH | Ensure nosuid option set on /home partition"
ansible.builtin.mount:
name: /home
src: "{{ item.device }}"
fstype: "{{ item.fstype }}"
state: present
opts: defaults,{% if rhel9cis_rule_1_1_7_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_7_3 %}nosuid,{% endif %}{% if rhel9cis_rule_1_1_7_4 %}usrquota,{% endif %}{% if rhel9cis_rule_1_1_7_5 %}grpquota{% endif %}
with_items:
- "{{ ansible_mounts }}"
opts: defaults,{% if rhel9cis_rule_1_1_7_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_7_3 %}nosuid,{% endif %}
loop: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.device }}"
notify: change_requires_reboot
notify: Change_requires_reboot
when:
- home_mount_present is defined
- item.mount == "/home"
- rhel9cis_rule_1_1_7_1
- rhel9cis_rule_1_1_7_2 or
rhel9cis_rule_1_1_7_3 or
rhel9cis_rule_1_1_7_4 or
rhel9cis_rule_1_1_7_5
rhel9cis_rule_1_1_7_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- mounts
- rule_1.1.7.2

View file

@ -1,43 +1,49 @@
---
# Skips if mount is absent
- name: |
"1.1.8.1 | PATCH | Ensure nodev option set on /dev/shm partition
1.1.8.2 | PATCH | Ensure nosuid option set on /dev/shm partition
1.1.8.3 | PATCH | Ensure noexec option set on /dev/shm partition"
- name: "1.1.8.1 | AUDIT | Ensure /dev/shm is a separate partition"
block:
- name: |
"1.1.8.1 | AUDIT | Ensure nodev option set on /dev/shm partition | Check for /dev/shm existence
1.1.8.2 | AUDIT | Ensure nosuid option set on /dev/shm partition | Check for /dev/shm existence
1.1.8.3 | AUDIT | Ensure noexec option set on /dev/shm partition | Check for /dev/shm existence"
shell: mount -l | grep -E '\s/dev/shm\s'
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_1_1_8_x_dev_shm_status
- name: "1.1.8.1 | AUDIT | Ensure /dev/shm is a separate partition | Absent"
ansible.builtin.debug:
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
- name: |
"1.1.8.1 | PATCH | Ensure nodev option set on /dev/shm partition | Set nodev option
1.1.8.2 | PATCH | Ensure noexec option set on /dev/shm partition | Set nosuid option
1.1.8.3 | PATCH | Ensure nosuid option set on /dev/shm partition | Set noexec option"
mount:
name: /dev/shm
src: tmpfs
fstype: tmpfs
state: mounted
opts: defaults,{% if rhel9cis_rule_1_1_8_2 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_8_1 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_8_3 %}nosuid{% endif %}
when: "'dev/shm' in rhel9cis_1_1_8_x_dev_shm_status.stdout"
notify: change_requires_reboot
- name: "1.1.8.1 | AUDIT | Ensure separate partition exists for /home | Present"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '1.1.8.1'
required_mount: '/dev/shm'
when:
- rhel9cis_rule_1_1_8_1 or
rhel9cis_rule_1_1_8_2 or
rhel9cis_rule_1_1_8_3
- required_mount not in mount_names
- rhel9cis_rule_1_1_8_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- audit
- mounts
- rule_1.1.8.1
- skip_ansible_lint
- name: |
"1.1.8.2 | PATCH | Ensure nodev option set on /dev/shm partition | Set nodev option
1.1.8.3 | PATCH | Ensure noexec option set on /dev/shm partition | Set nosuid option
1.1.8.4 | PATCH | Ensure nosuid option set on /dev/shm partition | Set noexec option"
ansible.builtin.mount:
name: /dev/shm
src: tmpfs
fstype: tmpfs
state: mounted
opts: defaults,{% if rhel9cis_rule_1_1_8_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_8_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_8_4 %}nosuid{% endif %}
notify: Change_requires_reboot
when:
- rhel9cis_rule_1_1_8_2 or
rhel9cis_rule_1_1_8_3 or
rhel9cis_rule_1_1_8_4
tags:
- level1-server
- level1-workstation
- patch
- mounts
- rule_1.1.8.2
- rule_1.1.8.3
- rule_1.1.8.4

View file

@ -1,26 +1,9 @@
---
- name: "1.1.9 | PATCH | Disable Automounting"
service:
name: autofs
enabled: false
when:
- not rhel9cis_allow_autofs
- "'autofs' in ansible_facts.packages"
- rhel9cis_rule_1_1_9
tags:
- level1-server
- level2-workstation
- automated
- patch
- mounts
- automounting
- rule_1.1.9
- name: "1.1.10 | PATCH | Disable USB Storage"
- name: "1.1.9 | PATCH | Disable USB Storage"
block:
- name: "1.1.10 | PATCH | Disable USB Storage | Edit modprobe config"
lineinfile:
- name: "1.1.9 | PATCH | Disable USB Storage | Edit modprobe config"
ansible.builtin.lineinfile:
path: /etc/modprobe.d/CIS.conf
regexp: "^(#)?install usb-storage(\\s|$)"
line: "install usb-storage /bin/true"
@ -29,17 +12,24 @@
group: root
mode: 0600
- name: "1.1.10 | PATCH | Disable USB Storage | Edit modprobe config"
modprobe:
- name: "1.1.9 | PATCH | Disable USB Storage | Edit modprobe config"
ansible.builtin.modprobe:
name: usb-storage
state: absent
- name: "1.1.9 | PATCH | Disable USB Storage | blacklist"
ansible.builtin.lineinfile:
path: /etc/modprobe.d/blacklist.conf
regexp: "^(#)?blacklist usb-storage(\\s|$)"
line: "blacklist usb-storage"
create: true
mode: 0600
when:
- rhel9cis_rule_1_1_10
- rhel9cis_rule_1_1_9
tags:
- level1-server
- level2-workstation
- automated
- patch
- mounts
- removable_storage
- rule_1.1.10
- rule_1.1.9

View file

@ -1,17 +1,16 @@
---
- name: "1.10 | PATCH | Ensure system-wide crypto policy is not legacy"
shell: |
ansible.builtin.shell: |
update-crypto-policies --set "{{ rhel9cis_crypto_policy }}"
update-crypto-policies
notify: change_requires_reboot
notify: Change_requires_reboot
when:
- rhel9cis_rule_1_10
- system_wide_crypto_policy['stdout'] == 'LEGACY'
tags:
- level1-server
- level1-workstation
- automated
- no system_is_ec2
- patch
- rule_1.10

View file

@ -1,54 +1,28 @@
---
- name: "1.2.1 | PATCH | Ensure Red Hat Subscription Manager connection is configured"
redhat_subscription:
state: present
username: "{{ rhel9cis_rh_sub_user }}"
password: "{{ rhel9cis_rh_sub_password }}"
auto_attach: true
no_log: true
when:
- ansible_distribution == "RedHat"
- rhel9cis_rhnsd_required
- rhel9cis_rule_1_2_1
tags:
- level1-server
- level1-workstation
- manual
- patch
- rule_1.2.1
- skip_ansible_lint # Added as no_log still errors on ansuible-lint
- name: "1.2.2 | AUDIT | Ensure GPG keys are configured"
- name: "1.2.1 | AUDIT | Ensure GPG keys are configured"
block:
- name: "1.2.2 | AUDIT | Ensure GPG keys are configured | list installed pubkey keys"
shell: "rpm -qa | grep {{ os_gpg_key_pubkey_name }}"
- name: "1.2.1 | AUDIT | Ensure GPG keys are configured | list installed pubkey keys"
ansible.builtin.shell: "rpm -qa | grep {{ os_gpg_key_pubkey_name }}"
changed_when: false
failed_when: false
register: os_installed_pub_keys
- name: "1.2.2 | AUDIT | Ensure GPG keys are configured | Query found keys"
shell: "rpm -q --queryformat \"%{PACKAGER} %{VERSION}\\n\" {{ os_gpg_key_pubkey_name }} | grep \"{{ os_gpg_key_pubkey_content }}\""
- name: "1.2.1 | AUDIT | Ensure GPG keys are configured | Query found keys"
ansible.builtin.shell: 'rpm -q --queryformat "%{PACKAGER} %{VERSION}\\n" {{ os_gpg_key_pubkey_name }} | grep "{{ os_gpg_key_pubkey_content }}"'
changed_when: false
failed_when: false
register: os_gpg_key_check
when: os_installed_pub_keys.rc == 0
- name: "1.2.2 | AUDIT | Ensure GPG keys are configured | expected keys pass"
debug:
msg: "Congratulations !! - The installed gpg keys match expected values"
when:
- os_installed_pub_keys.rc == 0
- os_gpg_key_check.rc == 0
- name: "1.2.2 | AUDIT | Ensure GPG keys are configured | expected keys fail"
fail:
- name: "1.2.1 | AUDIT | Ensure GPG keys are configured | expected keys fail"
ansible.builtin.fail:
msg: Installed GPG Keys do not meet expected values or keys installed that are not expected
when:
- os_installed_pub_keys.rc == 1 or
os_gpg_key_check.rc == 1
when:
- rhel9cis_rule_1_2_2
- rhel9cis_rule_1_2_1
- ansible_distribution == "RedHat" or
ansible_distribution == "Rocky" or
ansible_distribution == "AlmaLinux"
@ -57,62 +31,90 @@
- level1-workstation
- manual
- patch
- rule_1.2.2
- rule_1.2.1
- name: "1.2.3| PATCH | Ensure gpgcheck is globally activated"
- name: "1.2.2 | PATCH | Ensure gpgcheck is globally activated"
block:
- name: "1.2.3 | AUDIT | Ensure gpgcheck is globally activated | Find repos"
find:
- name: "1.2.2 | AUDIT | Ensure gpgcheck is globally activated | Find repos"
ansible.builtin.find:
paths: /etc/yum.repos.d
patterns: "*.repo"
register: yum_repos
changed_when: false
- name: "1.2.3 | PATCH | Ensure gpgcheck is globally activated | Update yum.repos"
replace:
- name: "1.2.2 | PATCH | Ensure gpgcheck is globally activated | Update yum.repos"
ansible.builtin.replace:
name: "{{ item.path }}"
regexp: "^gpgcheck=0"
replace: "gpgcheck=1"
with_items:
- "{{ yum_repos.files }}"
loop: "{{ yum_repos.files }}"
loop_control:
label: "{{ item.path }}"
when:
- rhel9cis_rule_1_2_2
tags:
- level1-server
- level1-workstation
- patch
- rule_1.2.2
- name: "1.2.3 | AUDIT | Ensure package manager repositories are configured"
block:
- name: "1.2.3 | AUDIT | Ensure package manager repositories are configured | Get repo list"
ansible.builtin.shell: dnf repolist
changed_when: false
failed_when: false
register: dnf_configured
check_mode: false
- name: "1.2.3 | AUDIT | Ensure package manager repositories are configured | Display repo list"
ansible.builtin.debug:
msg:
- "Warning!! Below are the configured repos. Please review and make sure all align with site policy"
- "{{ dnf_configured.stdout_lines }}"
- name: "1.2.3 | AUDIT | Ensure package manager repositories are configured | Warn Count"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '1.2.3'
when:
- rhel9cis_rule_1_2_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- manual
- audit
- rule_1.2.3
- skip_ansible_lint
- name: "1.2.4 | AUDIT | Ensure package manager repositories are configured"
- name: "1.2.4 | AUDIT | Ensure repo_gpgcheck is globally activated"
block:
- name: "1.2.4 | AUDIT | Ensure package manager repositories are configured | Get repo list"
command: dnf repolist
changed_when: false
failed_when: false
register: dnf_configured
check_mode: false
args:
warn: false
- name: "1.2.4 | PATCH | Ensure repo_gpgcheck is globally activated | dnf.conf"
ansible.builtin.lineinfile:
path: /etc/dnf/dnf.conf
regexp: '^repo_gpgcheck'
line: repo_gpgcheck=1
- name: "1.2.4 | AUDIT | Ensure package manager repositories are configured | Display repo list"
debug:
msg:
- "Warning!! Below are the configured repos. Please review and make sure all align with site policy"
- "{{ dnf_configured.stdout_lines }}"
- name: "1.2.4 | AUDIT| Ensure repo_gpgcheck is globally activated | get repo files"
ansible.builtin.find:
paths: /etc/yum.repos.d
patterns: "*.repo"
register: repo_files
- name: "1.2.4 | PATCH | Ensure repo_gpgcheck is globally activated | amend repo files"
ansible.builtin.replace:
path: "{{ item.path }}"
regexp: '^repo_gpgcheck( |)=( |)0'
replace: repo_gpgcheck=1
loop: "{{ repo_files.files }}"
loop_control:
label: "{{ item.path }}"
- name: "1.2.4 | AUDIT | Ensure package manager repositories are configured | Warn Count"
set_fact:
control_number: "{{ control_number }} + ['rule_1.2.4']"
warn_count: "{{ warn_count | int + 1 }}"
when:
- rhel9cis_rule_1_2_4
- not rhel9cis_rhel_default_repo or ansible_distribution != 'RedHat'
tags:
- level1-server
- level1-workstation
- manual
- audit
- rule_1.2.4
- skip_ansible_lint

View file

@ -3,32 +3,37 @@
- name: "1.3.1 | PATCH | Ensure AIDE is installed"
block:
- name: "1.3.1 | PATCH | Ensure AIDE is installed | Install AIDE"
package:
ansible.builtin.package:
name: aide
state: present
- name: "1.3.1 | PATCH | Ensure AIDE is installed | Configure AIDE"
command: /usr/sbin/aide --init -B 'database_out=file:/var/lib/aide/aide.db.gz'
- name: "1.3.1 | PATCH | Ensure AIDE is installed | Build AIDE DB"
ansible.builtin.shell: /usr/sbin/aide --init
changed_when: false
failed_when: false
async: 45
poll: 0
args:
creates: /var/lib/aide/aide.db.gz
creates: /var/lib/aide/aide.db.new.gz
when: not ansible_check_mode
- name: "1.3.1 | PATCH | Ensure AIDE is installed | copy AIDE DB"
ansible.builtin.copy:
src: /var/lib/aide/aide.db.new.gz
dest: /var/lib/aide/aide.db.gz
remote_src: true
when:
- rhel9cis_config_aide
- rhel9cis_rule_1_3_1
tags:
- level1-server
- level1-workstation
- automated
- aide
- patch
- rule_1.3.1
- name: "1.3.2 | PATCH | Ensure filesystem integrity is regularly checked"
cron:
ansible.builtin.cron:
name: Run AIDE integrity check
cron_file: "{{ rhel9cis_aide_cron['cron_file'] }}"
user: "{{ rhel9cis_aide_cron['cron_user'] }}"
@ -44,8 +49,30 @@
tags:
- level1-server
- level1-workstation
- automated
- aide
- file_integrity
- patch
- rule_1.3.2
- name: "1.3.3 | Ensure cryptographic mechanisms are used to protect the integrity of audit tools"
ansible.builtin.blockinfile:
path: /etc/aide.conf
marker: "# {mark} Audit tools (CIS - Ansible)"
block: |
/sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512
/sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512
/sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512
/sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512
/sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512
/sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512
validate: aide -D --config %s
when:
- rhel9cis_rule_1_3_2
- not system_is_ec2
tags:
- level1-server
- level1-workstation
- aide
- file_integrity
- patch
- rule_1.3.3

View file

@ -1,20 +1,19 @@
---
- name: "1.4.1 | PATCH | Ensure bootloader password is set"
copy:
ansible.builtin.copy:
dest: /boot/grub2/user.cfg
content: "GRUB2_PASSWORD={{ rhel9cis_bootloader_password_hash }}" # noqa template-instead-of-copy
owner: root
group: root
mode: 0600
notify: grub2cfg
notify: Grub2cfg
when:
- rhel9cis_set_boot_pass
- rhel9cis_rule_1_4_1
tags:
- level1-server
- level1-workstation
- automated
- grub
- patch
- rule_1.4.1
@ -22,51 +21,21 @@
- name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured"
block:
- name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured"
file:
path: /boot/grub2/grub.cfg
ansible.builtin.file:
path: "/boot/grub2/{{ item.path }}"
owner: root
group: root
mode: 0600
mode: "{{ item.mode }}"
loop:
- { path: 'grub.cfg', mode: '0700' }
- { path: 'grubenv', mode: '0600' }
- { path: 'user.cfg', mode: '0600' }
- name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured | UEFI"
mount:
name: /boot/efi
src: "UUID={{ item.uuid }}"
fstype: vfat
state: present
opts: defaults,umask=0027,fmask=0077,uid=0,gid=0
passno: '0'
with_items:
- "{{ ansible_mounts }}"
loop_control:
label: "{{ item.mount }}"
when:
- not rhel9cis_legacy_boot
- item.mount == "/boot/efi"
when:
- rhel9cis_rule_1_4_2
tags:
- level1-server
- level1-workstation
- automated
- grub
- patch
- rule_1.4.2
- name: "1.4.3 | PATCH | Ensure authentication is required when booting into rescue mode"
lineinfile:
path: /etc/systemd/system/rescue.service.d/00-require-auth.conf
regexp: '^ExecStart='
line: "ExecStart=-/usr/lib/systemd/systemd-sulogin-shell rescue"
create: true
owner: root
group: root
mode: 0644
when:
- rhel9cis_rule_1_4_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_1.4.3

View file

@ -1,23 +1,22 @@
---
- name: "1.5.1 | PATCH | Ensure core dump storage is disabled"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/systemd/coredump.conf
regexp: '^Storage\s*=\s*(?!none).*'
line: 'Storage=none'
notify: systemd_daemon_reload
notify: Systemd daemon reload
when:
- rhel9cis_rule_1_5_1
- systemd_coredump.stat.exists
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_1.5.1
- name: "1.5.2 | PATCH | Ensure core dump backtraces are disabled"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/systemd/coredump.conf
regexp: '^ProcessSizeMax\s*=\s*.*[1-9]$'
line: 'ProcessSizeMax=0'
@ -26,7 +25,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- sysctl
- rule_1.5.2
@ -34,17 +32,17 @@
- name: "1.5.3 | PATCH | Ensure address space layout randomization (ASLR) is enabled"
block:
- name: "1.5.3 | PATCH | Ensure address space layout randomization (ASLR) is enabled"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
- name: "1.5.3 | PATCH | Ensure address space layout randomization (ASLR) is enabled"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-kernel_sysctl.conf"
when:
- rhel9cis_rule_1_5_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- sysctl
- rule_1.5.3

View file

@ -1,7 +1,7 @@
---
- name: "1.6.1.1 | PATCH | Ensure SELinux is installed"
package:
ansible.builtin.package:
name: libselinux
state: present
when:
@ -9,18 +9,20 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_1.6.1.1
- name: "1.6.1.2 | PATCH | Ensure SELinux is not disabled in bootloader configuration"
replace:
dest: /etc/default/grub
regexp: 'selinux=0'
ansible.builtin.replace:
path: /etc/default/grub
regexp: '{{ item }}'
replace: ''
loop:
- selinux=0
- enforcing=0
register: selinux_grub_patch
ignore_errors: true # noqa ignore-errors
notify: grub2cfg
notify: Grub2cfg
when:
- rhel9cis_rule_1_6_1_2
tags:
@ -32,93 +34,99 @@
# State set to enforcing because control 1.6.1.5 requires enforcing to be set
- name: "1.6.1.3 | PATCH | Ensure SELinux policy is configured"
selinux:
ansible.posix.selinux:
conf: /etc/selinux/config
policy: "{{ rhel9cis_selinux_pol }}"
state: enforcing
state: "{{ rhel9cis_selinux_enforce }}"
when:
- not rhel9cis_selinux_disable
- rhel9cis_rule_1_6_1_3
tags:
- level1-server
- level1-workstation
- automated
- selinux
- patch
- rule_1.6.1.3
- name: "1.6.1.4 | PATCH | Ensure the SELinux state is enforcing"
selinux:
- name: "1.6.1.4 | PATCH | Ensure the SELinux state is not disabled"
ansible.posix.selinux:
conf: /etc/selinux/config
policy: "{{ rhel9cis_selinux_pol }}"
state: "{{ rhel9cis_selinux_enforce }}"
when:
- not rhel9cis_selinux_disable
- rhel9cis_rule_1_6_1_4
tags:
- level1-server
- level1-workstation
- selinux
- patch
- rule_1.6.1.4
- name: "1.6.1.5 | PATCH | Ensure the SELinux state is enforcing"
ansible.posix.selinux:
conf: /etc/selinux/config
policy: "{{ rhel9cis_selinux_pol }}"
state: enforcing
when:
- not rhel9cis_selinux_disable
- rhel9cis_rule_1_6_1_4
- rhel9cis_selinux_enforce == 'enforcing'
- rhel9cis_rule_1_6_1_5
tags:
- level2-server
- level2-workstation
- automated
- selinux
- patch
- rule_1.6.1.4
- rule_1.6.1.5
- name: "1.6.1.5 | AUDIT | Ensure no unconfined services exist"
- name: "1.6.1.6 | AUDIT | Ensure no unconfined services exist"
block:
- name: "1.6.1.5 | AUDIT | Ensure no unconfined services exist | Find the unconfined services"
shell: ps -eZ | grep unconfined_service_t | egrep -vw "tr|ps|egrep|bash|awk" | tr ':' ' ' | awk '{ print $NF }'
register: rhelcis_1_6_1_5_unconf_services
- name: "1.6.1.6 | AUDIT | Ensure no unconfined services exist | Find the unconfined services"
ansible.builtin.shell: ps -eZ | grep unconfined_service_t | egrep -vw "tr|ps|egrep|bash|awk" | tr ':' ' ' | awk '{ print $NF }'
register: rhelcis_1_6_1_6_unconf_services
failed_when: false
changed_when: false
- name: "1.6.1.5 | AUDIT | Ensure no unconfined services exist | Message on no unconfined services"
debug:
msg: "Good News! There are no services found on your system"
when: rhelcis_1_6_1_5_unconf_services.stdout | length == 0
- name: "1.6.1.6 | AUDIT | Ensure no unconfined services exist | Message on unconfined services"
ansible.builtin.debug:
msg: "Warning!! You have unconfined services: {{ rhelcis_1_6_1_6_unconf_services.stdout_lines }}"
when: rhelcis_1_6_1_6_unconf_services.stdout | length > 0
- name: "1.6.1.5 | AUDIT | Ensure no unconfined services exist | Message on unconfined services"
debug:
msg: "Warning!! You have unconfined services: {{ rhelcis_1_6_1_5_unconf_services.stdout_lines }}"
when: rhelcis_1_6_1_5_unconf_services.stdout | length > 0
- name: "1.6.1.5 | AUDIT | Ensure no unconfined services exist | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.6.1.5' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhelcis_1_6_1_5_unconf_services.stdout | length > 0
- name: "1.6.1.6 | AUDIT | Ensure no unconfined services exist | warning count"
ansible.builtin.import_tasks: warning_facts.yml
when: rhelcis_1_6_1_6_unconf_services.stdout | length > 0
vars:
warn_control_id: '1.6.1.6'
when:
- rhel9cis_rule_1_6_1_5
- rhel9cis_rule_1_6_1_6
tags:
- level1-server
- level1-workstation
- automated
- audit
- services
- rule_1.6.1.5
- rule_1.6.1.6
- name: "1.6.1.6 | PATCH | Ensure SETroubleshoot is not installed"
package:
- name: "1.6.1.7 | PATCH | Ensure SETroubleshoot is not installed"
ansible.builtin.package:
name: setroubleshoot
state: absent
when:
- rhel9cis_rule_1_6_1_6
- rhel9cis_rule_1_6_1_7
- "'setroubleshoot' in ansible_facts.packages"
tags:
- level1-server
- automated
- selinux
- patch
- rule_1.6.1.6
- rule_1.6.1.7
- name: "1.6.1.7 | PATCH | Ensure the MCS Translation Service (mcstrans) is not installed"
package:
- name: "1.6.1.8 | PATCH | Ensure the MCS Translation Service (mcstrans) is not installed"
ansible.builtin.package:
name: mcstrans
state: absent
when:
- rhel9cis_rule_1_6_1_7
- rhel9cis_rule_1_6_1_8
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_1.6.1.7
- rule_1.6.1.8

View file

@ -1,7 +1,7 @@
---
- name: "1.7.1 | PATCH | Ensure message of the day is configured properly"
template:
ansible.builtin.template:
src: etc/motd.j2
dest: /etc/motd
owner: root
@ -12,13 +12,12 @@
tags:
- level1-server
- level1-workstation
- automated
- banner
- patch
- rule_1.7.1
- name: "1.7.2 | PATCH | Ensure local login warning banner is configured properly"
template:
ansible.builtin.template:
src: etc/issue.j2
dest: /etc/issue
owner: root
@ -29,12 +28,11 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_1.7.2
- name: "1.7.3 | PATCH | Ensure remote login warning banner is configured properly"
template:
ansible.builtin.template:
src: etc/issue.net.j2
dest: /etc/issue.net
owner: root
@ -45,15 +43,13 @@
tags:
- level1-server
- level1-workstation
- automated
- banner
- patch
- rule_1.7.3
- name: "1.7.4 | PATCH | Ensure permissions on /etc/motd are configured"
file:
dest: /etc/motd
state: file
ansible.builtin.file:
path: /etc/motd
owner: root
group: root
mode: 0644
@ -62,15 +58,13 @@
tags:
- level1-server
- level1-workstation
- automated
- perms
- patch
- rule_1.7.4
- name: "1.7.5 | PATCH | Ensure permissions on /etc/issue are configured"
file:
dest: /etc/issue
state: file
ansible.builtin.file:
path: /etc/issue
owner: root
group: root
mode: 0644
@ -79,15 +73,13 @@
tags:
- level1-server
- level1-workstation
- automated
- perms
- patch
- rule_1.7.5
- name: "1.7.6 | PATCH | Ensure permissions on /etc/issue.net are configured"
file:
dest: /etc/issue.net
state: file
ansible.builtin.file:
path: /etc/issue.net
owner: root
group: root
mode: 0644
@ -96,7 +88,6 @@
tags:
- level1-server
- level1-workstation
- automated
- perms
- patch
- rule_1.7.6

View file

@ -1,52 +1,58 @@
---
- name: "1.8.1 | PATCH | Ensure GNOME Display Manager is removed"
package:
ansible.builtin.package:
name: gdm
state: absent
when:
- rhel9cis_rule_1_8_1
- "'gdm' in ansible_facts.packages"
- not rhel9cis_gui
tags:
- level2-server
- automated
- patch
- gui
- gdm
- rule_1.8.1
- name: "1.8.2 | PATCH | Ensure GDM login banner is configured"
lineinfile:
path: "{{ item.file }}"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: present
create: true
owner: root
group: root
mode: 0644
notify: reload dconf
with_items:
- { file: '/etc/dconf/profile/gdm', regexp: 'user-db', line: 'user-db:user' }
- { file: '/etc/dconf/profile/gdm', regexp: 'system-db', line: 'system-db:gdm' }
- { file: '/etc/dconf/profile/gdm', regexp: 'file-db', line: 'file-db:/usr/share/gdm/greeter-dconf-defaults' }
- { file: '/etc/dconf/db/gdm.d/01-banner-message', regexp: '\[org\/gnome\/login-screen\]', line: '[org/gnome/login-screen]' }
- { file: '/etc/dconf/db/gdm.d/01-banner-message', regexp: 'banner-message-enable', line: 'banner-message-enable=true' }
- { file: '/etc/dconf/db/gdm.d/01-banner-message', regexp: 'banner-message-text', line: "banner-message-text='{{ rhel9cis_warning_banner }}' " }
block:
- name: "1.8.2 | PATCH | Ensure GDM login banner is configured | gdm profile"
ansible.builtin.lineinfile:
path: /etc/dconf/profile/gdm
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
create: true
owner: root
group: root
mode: 0644
notify: Reload dconf
loop:
- { regexp: 'user-db', line: 'user-db:user' }
- { regexp: 'system-db', line: 'system-db:gdm' }
- { regexp: 'file-db', line: 'file-db:/usr/share/gdm/greeter-dconf-defaults' }
- name: "1.8.2 | PATCH | Ensure GDM login banner is configured | gdm profile"
ansible.builtin.template:
src: etc/dconf/db/gdm.d/01-banner-message.j2
dest: /etc/dconf/db/gdm.d/01-banner-message
owner: root
group: root
mode: 0644
notify: Reload dconf
when:
- rhel9cis_rule_1_8_2
- rhel9cis_gui
tags:
- level1-server
- level1-workstation
- automated
- patch
- gui
- gdm
- rule_1.8.2
- name: "1.8.3 | PATCH | Ensure last logged in user display is disabled"
lineinfile:
- name: "1.8.3 | PATCH | Ensure GDM disable-user-list option is enabled"
ansible.builtin.lineinfile:
path: "{{ item.file }}"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
@ -54,8 +60,8 @@
owner: root
group: root
mode: 0644
notify: reload dconf
with_items:
notify: Reload dconf
loop:
- { file: '/etc/dconf/profile/gdm', regexp: 'user-db', line: 'user-db:user' }
- { file: '/etc/dconf/profile/gdm', regexp: 'system-db', line: 'system-db:gdm' }
- { file: '/etc/dconf/profile/gdm', regexp: 'file-db', line: 'file-db:/usr/share/gdm/greeter-dconf-defaults'}
@ -67,48 +73,192 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- gui
- rule_1.8.3
- name: "1.8.4 | PATCH | Ensure XDMCP is not enabled"
lineinfile:
path: /etc/gdm/custom.conf
regexp: 'Enable=true'
state: absent
- name: "1.8.4 | PATCH | Ensure GDM screen locks when the user is idle"
block:
- name: "1.8.4 | PATCH | Ensure GDM screen locks when the user is idle | User profile"
ansible.builtin.lineinfile:
path: /etc/dconf/profile/user
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
create: true
owner: root
group: root
mode: 0644
loop:
- { regexp: '^user-db', line: 'user-db: user' }
- { regexp: '^system-db', line: 'system-db: local' }
- name: "1.8.4 | PATCH | Ensure GDM screen locks when the user is idle | Make db directory"
ansible.builtin.file:
path: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d"
owner: root
group: root
mode: 0755
state: directory
- name: "1.8.4 | PATCH | Ensure GDM screen locks when the user is idle | Make conf file"
ansible.builtin.template:
src: etc/dconf/db/00-screensaver.j2
dest: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/00-screensaver"
owner: root
group: root
mode: '0644'
notify: Reload dconf
when:
- rhel9cis_rule_1_8_4
- rhel9cis_gui
tags:
- level1-server
- level1-workstation
- automated
- patch
- gui
- rule_1.8.4
- name: "1.8.5 | PATCH | Ensure automatic mounting of removable media is disabled"
lineinfile:
path: /etc/dconf/db/local.d/00-media-automount
regexp: "{{ item.regex }}"
line: "{{ item.line }}"
create: true
owner: root
group: root
mode: 0644
notify: reload dconf
with_items:
- { regex: '\[org\/gnome\/desktop\/media-handling\]', line: '[org/gnome/desktop/media-handling]' }
- { regex: 'automount=', line: 'automount=false' }
- { regex: 'automount-open=', line: 'automount-open=false'}
- name: "1.8.5 PATCH | Ensure GDM screen locks cannot be overridden"
block:
- name: "1.8.5 | PATCH | Ensure GDM screen locks cannot be overridden | Make lock directory"
ansible.builtin.file:
path: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/locks"
owner: root
group: root
mode: 0755
state: directory
- name: "1.8.5 | PATCH | Ensure GDM screen locks cannot be overridden | Make lock file"
ansible.builtin.template:
src: etc/dconf/db/00-screensaver_lock.j2
dest: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/locks/00-screensaver"
owner: root
group: root
mode: 0644
notify: Reload dconf
when:
- rhel9cis_rule_1_8_5
- rhel9cis_gui
tags:
- level1-server
- level2-workstation
- automated
- level1-workstation
- patch
- gui
- rule_1.8.5
- name: "1.8.6 | PATCH | Ensure GDM automatic mounting of removable media is disabled"
ansible.builtin.template:
src: etc/dconf/db/00-media-automount.j2
dest: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/00-media-automount"
owner: root
group: root
mode: '0644'
notify: Reload dconf
when:
- rhel9cis_rule_1_8_6
- rhel9cis_gui
tags:
- level1-server
- level2-workstation
- patch
- gui
- rule_1.8.6
- name: "1.8.7 | PATCH | Ensure GDM disabling automatic mounting of removable media is not overridden"
block:
- name: "1.8.7 | PATCH | Ensure GDM disabling automatic mounting of removable media is not overridden | Make lock directory"
ansible.builtin.file:
path: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/locks"
owner: root
group: root
mode: 0755
state: directory
- name: "1.8.7 | PATCH | Ensure GDM disabling automatic mounting of removable media is not overridden | Make lock file"
ansible.builtin.template:
src: etc/dconf/db/00-automount_lock.j2
dest: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/locks/00-automount_lock"
owner: root
group: root
mode: 0644
notify: Reload dconf
when:
- rhel9cis_rule_1_8_7
- rhel9cis_gui
tags:
- level1-server
- level2-workstation
- patch
- gui
- rule_1.8.7
- name: "1.8.8 | PATCH | Ensure GDM autorun-never is enabled"
block:
- name: "1.8.8 | PATCH | Ensure GDM autorun-never is enabled | Make directory"
ansible.builtin.file:
path: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d"
owner: root
group: root
mode: 0755
state: directory
- name: "1.8.8 | PATCH | Ensure GDM autorun-never is enabled | Make conf file"
ansible.builtin.template:
src: etc/dconf/db/00-media-autorun.j2
dest: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/00-media-autorun"
owner: root
group: root
mode: '0644'
notify: Reload dconf
when:
- rhel9cis_rule_1_8_8
- rhel9cis_gui
tags:
- level1-server
- level2-workstation
- patch
- gui
- rule_1.8.8
- name: "1.8.9 | PATCH | Ensure GDM autorun-never is not overridden"
block:
- name: "1.8.9 | PATCH | Ensure GDM autorun-never is not overridden | Make lock directory"
ansible.builtin.file:
path: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/locks"
owner: root
group: root
mode: 0755
state: directory
- name: "1.8.9 | PATCH | Ensure GDM autorun-never is not overridden | Make lockfile"
ansible.builtin.template:
src: etc/dconf/db/00-autorun_lock.j2
dest: "/etc/dconf/db/{{ rhel9cis_dconf_db_name }}.d/locks/00-autorun_lock"
owner: root
group: root
mode: 0644
notify: Reload dconf
when:
- rhel9cis_rule_1_8_9
- rhel9cis_gui
tags:
- level1-server
- level2-workstation
- patch
- gui
- rule_1.8.9
- name: "1.8.10 | PATCH | Ensure XDMCP is not enabled"
ansible.builtin.lineinfile:
path: /etc/gdm/custom.conf
regexp: 'Enable=true'
state: absent
when:
- rhel9cis_rule_1_8_10
- rhel9cis_gui
tags:
- level1-server
- level1-workstation
- patch
- gui
- rule_1.8.4

View file

@ -1,17 +1,16 @@
---
- name: "1.9 | PATCH | Ensure updates, patches, and additional security software are installed"
package:
ansible.builtin.package:
name: "*"
state: latest
notify: change_requires_reboot
notify: Change_requires_reboot
when:
- rhel9cis_rule_1_9
- not system_is_ec2
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_1.9
- skip_ansible_lint

View file

@ -1,57 +1,57 @@
---
- name: "SECTION | 1.1.1.x | Disable unused filesystems"
import_tasks: cis_1.1.1.x.yml
ansible.builtin.import_tasks: cis_1.1.1.x.yml
- name: "SECTION | 1.1.2.x | Configure /tmp"
import_tasks: cis_1.1.2.x.yml
ansible.builtin.import_tasks: cis_1.1.2.x.yml
- name: "SECTION | 1.1.3.x | Configure /var"
import_tasks: cis_1.1.3.x.yml
ansible.builtin.import_tasks: cis_1.1.3.x.yml
- name: "SECTION | 1.1.4.x | Configure /var/tmp"
import_tasks: cis_1.1.4.x.yml
ansible.builtin.import_tasks: cis_1.1.4.x.yml
- name: "SECTION | 1.1.5.x | Configure /var/log"
import_tasks: cis_1.1.5.x.yml
ansible.builtin.import_tasks: cis_1.1.5.x.yml
- name: "SECTION | 1.1.6.x | Configure /var/log/audit"
import_tasks: cis_1.1.6.x.yml
ansible.builtin.import_tasks: cis_1.1.6.x.yml
- name: "SECTION | 1.1.7.x | Configure /home"
import_tasks: cis_1.1.7.x.yml
ansible.builtin.import_tasks: cis_1.1.7.x.yml
- name: "SECTION | 1.1.8.x | Configure /dev/shm"
import_tasks: cis_1.1.8.x.yml
ansible.builtin.import_tasks: cis_1.1.8.x.yml
- name: "SECTION | 1.1.x | Disable various mounting"
import_tasks: cis_1.1.x.yml
ansible.builtin.import_tasks: cis_1.1.x.yml
- name: "SECTION | 1.2 | Configure Software Updates"
import_tasks: cis_1.2.x.yml
ansible.builtin.import_tasks: cis_1.2.x.yml
- name: "SECTION | 1.3 | Filesystem Integrity Checking"
import_tasks: cis_1.3.x.yml
ansible.builtin.import_tasks: cis_1.3.x.yml
when: rhel9cis_config_aide
- name: "SECTION | 1.4 | Secure Boot Settings"
import_tasks: cis_1.4.x.yml
ansible.builtin.import_tasks: cis_1.4.x.yml
- name: "SECTION | 1.5 | Additional Process Hardening"
import_tasks: cis_1.5.x.yml
ansible.builtin.import_tasks: cis_1.5.x.yml
- name: "SECTION | 1.6 | Mandatory Access Control"
include_tasks: cis_1.6.1.x.yml
when: not rhel9cis_selinux_disable
- name: "SECTION | 1.7 | Command Line Warning Banners"
import_tasks: cis_1.7.x.yml
ansible.builtin.import_tasks: cis_1.7.x.yml
- name: "SECTION | 1.8 | Gnome Display Manager"
import_tasks: cis_1.8.x.yml
ansible.builtin.import_tasks: cis_1.8.x.yml
- name: "SECTION | 1.9 | Updates and Patches"
import_tasks: cis_1.9.yml
ansible.builtin.import_tasks: cis_1.9.yml
- name: "SECTION | 1.10 | Crypto policies"
include_tasks: cis_1.10.yml

View file

@ -1,7 +1,7 @@
---
- name: "2.1.1 | PATCH | Ensure time synchronization is in use"
package:
ansible.builtin.package:
name: chrony
state: present
when:
@ -10,14 +10,13 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_2.1.1
- name: "2.1.2 | PATCH | Ensure chrony is configured"
block:
- name: "2.1.2 | PATCH | Ensure chrony is configured | Set configuration"
template:
ansible.builtin.template:
src: etc/chrony.conf.j2
dest: /etc/chrony.conf
owner: root
@ -25,7 +24,7 @@
mode: 0644
- name: "2.1.2 | PATCH | Ensure chrony is configured | modify /etc/sysconfig/chronyd | 1"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/sysconfig/chronyd
regexp: "^(#)?OPTIONS"
line: "OPTIONS=\"-u chrony\""

View file

@ -1,54 +1,39 @@
---
- name: "2.2.1 | PATCH | Ensure xinetd is not installed"
package:
name: xinetd
state: absent
when:
- rhel9cis_rule_2_2_1
- not rhel9cis_xinetd_server
- "'xinetd' in ansible_facts.packages"
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_2.2.1
- name: "2.2.2 | PATCH | Ensure xorg-x11-server-common is not installed"
package:
- name: "2.2.1 | PATCH | Ensure xorg-x11-server-common is not installed"
ansible.builtin.package:
name: xorg-x11-server-common
state: absent
when:
- rhel9cis_rule_2_2_2
- rhel9cis_rule_2_2_1
- "'xorg-x11-server-common' in ansible_facts.packages"
- not rhel9cis_gui
tags:
- level1-server
- automated
- patch
- x11
- rule_2.2.2
- rule_2.2.1
- name: "2.2.3 | PATCH | Ensure Avahi Server is not installed"
package:
- name: "2.2.2 | PATCH | Ensure Avahi Server is not installed"
ansible.builtin.package:
name:
- avahi-autoipd
- avahi
state: absent
when:
- rhel9cis_rule_2_2_3
- rhel9cis_rule_2_2_2
- not rhel9cis_avahi_server
- "'avahi' in ansible_facts.packages or 'avahi-autopd' in ansible_facts.packages"
tags:
- level1-server
- level2-workstation
- automated
- patch
- avahi
- rule_2.2.3
- rule_2.2.2
- name: "2.2.4 | PATCH | Ensure CUPS is not installed"
package:
- name: "2.2.3 | PATCH | Ensure CUPS is not installed"
ansible.builtin.package:
name: cups
state: absent
when:
@ -57,124 +42,102 @@
- rhel9cis_rule_2_2_3
tags:
- level1-server
- automated
- patch
- cups
- rule_2.2.3
- name: "2.2.5 | PATCH | Ensure DHCP Server is not installed"
package:
- name: "2.2.4 | PATCH | Ensure DHCP Server is not installed"
ansible.builtin.package:
name: dhcp-server
state: absent
when:
- not rhel9cis_dhcp_server
- "'dhcp-server' in ansible_facts.packages"
- rhel9cis_rule_2_2_5
- rhel9cis_rule_2_2_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- dhcp
- rule_2.2.5
- rule_2.2.4
- name: "2.2.6 | PATCH | Ensure DNS Server is not installed"
package:
- name: "2.2.5 | PATCH | Ensure DNS Server is not installed"
ansible.builtin.package:
name: bind
state: absent
when:
- not rhel9cis_dns_server
- "'bind' in ansible_facts.packages"
- rhel9cis_rule_2_2_6
- rhel9cis_rule_2_2_5
tags:
- level1-server
- level1-workstation
- automated
- patch
- dns
- rule_2.2.6
- rule_2.2.5
- name: "2.2.7 | PATCH | Ensure FTP Server is not installed"
package:
name: ftp
state: absent
when:
- not rhel9cis_ftp_server
- "'ftp' in ansible_facts.packages"
- rhel9cis_rule_2_2_7
tags:
- level1-server
- level1-workstation
- automated
- patch
- ftp
- rule_2.2.7
- name: "2.2.8 | PATCH | Ensure VSFTP Server is not installed"
package:
- name: "2.2.6 | PATCH | Ensure VSFTP Server is not installed"
ansible.builtin.package:
name: vsftpd
state: absent
when:
- not rhel9cis_vsftpd_server
- "'vsftpd' in ansible_facts.packages"
- rhel9cis_rule_2_2_8
- rhel9cis_rule_2_2_6
tags:
- level1-server
- level1-workstation
- automated
- patch
- vsftpd
- rule_2.2.8
- rule_2.2.6
- name: "2.2.9 | PACH | Ensure TFTP Server is not installed"
package:
- name: "2.2.7 | PACH | Ensure TFTP Server is not installed"
ansible.builtin.package:
name: tftp-server
state: absent
when:
- not rhel9cis_tftp_server
- "'tftp-server' in ansible_facts.packages"
- rhel9cis_rule_2_2_9
- rhel9cis_rule_2_2_7
tags:
- level1-server
- level1-workstation
- automated
- patch
- tftp
- rule_2.2.9
- rule_2.2.7
- name: "2.2.10 | PATCH | Ensure a web server is not installed"
- name: "2.2.8 | PATCH | Ensure a web server is not installed"
block:
- name: "2.2.10 | PATCH | Ensure a web server is not installed | Remove httpd server"
package:
- name: "2.2.8 | PATCH | Ensure a web server is not installed | Remove httpd server"
ansible.builtin.package:
name: httpd
state: absent
when:
- not rhel9cis_httpd_server
- "'httpd' in ansible_facts.packages"
- name: "2.2.10 | PATCH | Ensure a web server is not installed | Remove nginx server"
package:
- name: "2.2.8 | PATCH | Ensure a web server is not installed | Remove nginx server"
ansible.builtin.package:
name: nginx
state: absent
when:
- not rhel9cis_nginx_server
- "'nginx' in ansible_facts.packages"
when:
- rhel9cis_rule_2_2_10
- rhel9cis_rule_2_2_8
tags:
- level1-server
- level1-workstation
- automated
- patch
- httpd
- nginx
- webserver
- rule_2.2.9
- rule_2.2.8
- name: "2.2.11 | PATCH | Ensure IMAP and POP3 server is not installed"
- name: "2.2.9 | PATCH | Ensure IMAP and POP3 server is not installed"
block:
- name: "2.2.11 | PATCH | Ensure IMAP and POP3 server is not installed"
package:
- name: "2.2.9 | PATCH | Ensure IMAP and POP3 server is not installed"
ansible.builtin.package:
name:
- dovecot
state: absent
@ -182,8 +145,8 @@
- not rhel9cis_dovecot_server
- "'dovecot' in ansible_facts.packages"
- name: "2.2.11 | PATCH | Ensure IMAP and POP3 server is not installed"
package:
- name: "2.2.9 | PATCH | Ensure IMAP and POP3 server is not installed"
ansible.builtin.package:
name:
- cyrus-imapd
state: absent
@ -192,129 +155,123 @@
- "'cyrus-imapd' in ansible_facts.packages"
when:
- rhel9cis_rule_2_2_11
- rhel9cis_rule_2_2_9
tags:
- level1-server
- level1-workstation
- automated
- patch
- dovecot
- imap
- pop3
- rule_2.2.11
- rule_2.2.9
- name: "2.2.12 | PATCH | Ensure Samba is not enabled"
package:
- name: "2.2.10 | PATCH | Ensure Samba is not enabled"
ansible.builtin.package:
name: samba
state: absent
when:
- not rhel9cis_samba_server
- "'samba' in ansible_facts.packages"
- rhel9cis_rule_2_2_12
- rhel9cis_rule_2_2_10
tags:
- level1-server
- level1-workstation
- automated
- patch
- samba
- rule_2.2.12
- rule_2.2.10
- name: "2.2.13 | PATCH | Ensure HTTP Proxy Server is not installed"
package:
- name: "2.2.11 | PATCH | Ensure HTTP Proxy Server is not installed"
ansible.builtin.package:
name: squid
state: absent
when:
- not rhel9cis_squid_server
- "'squid' in ansible_facts.packages"
- rhel9cis_rule_2_2_6
- rhel9cis_rule_2_2_11
tags:
- level1-server
- level1-workstation
- automated
- patch
- squid
- rule_2.2.13
- rule_2.2.11
- name: "2.2.14 | PATCH | Ensure net-snmp is not installed"
package:
- name: "2.2.12 | PATCH | Ensure net-snmp is not installed"
ansible.builtin.package:
name: net-snmp
state: absent
when:
- not rhel9cis_snmp_server
- "'net-snmp' in ansible_facts.packages"
- rhel9cis_rule_2_2_14
- rhel9cis_rule_2_2_12
tags:
- level1-server
- level1-workstation
- automated
- patch
- snmp
- rule_2.2.14
- rule_2.2.12
- name: "2.2.15 | PATCH | Ensure NIS Server is not installed"
package:
name: ypserv
state: absent
when:
- not rhel9cis_nis_server
- "'ypserv' in ansible_facts.packages"
- rhel9cis_rule_2_2_17
tags:
- level1-server
- level1-workstation
- automated
- patch
- nis
- rule_2.2.17
- name: "2.2.16 | PATCH | Ensure telnet-server is not installed"
package:
- name: "2.2.13 | PATCH | Ensure telnet-server is not installed"
ansible.builtin.package:
name: telnet-server
state: absent
when:
- not rhel9cis_telnet_server
- "'telnet-server' in ansible_facts.packages"
- rhel9cis_rule_2_2_16
- rhel9cis_rule_2_2_13
tags:
- level1-server
- level1-workstation
- automated
- patch
- telnet
- rule_2.2.16
- rule_2.2.13
- name: "2.2.17 | PATCH | Ensure mail transfer agent is configured for local-only mode"
lineinfile:
- name: "2.2.14 | PATCH | Ensure dnsmasq is not installed"
ansible.builtin.package:
name: dnsmasq
state: absent
notify: Restart postfix
when:
- not rhel9cis_is_mail_server
- "'dnsmasq' in ansible_facts.packages"
- rhel9cis_rule_2_2_14
tags:
- level1-server
- level1-workstation
- patch
- dnsmasq
- rule_2.2.14
- name: "2.2.15 | PATCH | Ensure mail transfer agent is configured for local-only mode"
ansible.builtin.lineinfile:
path: /etc/postfix/main.cf
regexp: "^(#)?inet_interfaces"
line: "inet_interfaces = loopback-only"
notify: restart postfix
notify: Restart postfix
when:
- not rhel9cis_is_mail_server
- "'postfix' in ansible_facts.packages"
- rhel9cis_rule_2_2_17
- rhel9cis_rule_2_2_15
tags:
- level1-server
- level1-workstation
- automated
- patch
- postfix
- rule_2.2.17
- rule_2.2.15
# The name title of the service says mask the service, but the fix allows for both options
# Options available in default/main if to remove the package default is false just mask the server service
- name: "2.2.18 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked"
- name: "2.2.16 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked"
block:
- name: "2.2.18 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked | remove package"
package:
- name: "2.2.16 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked | remove package"
ansible.builtin.package:
name: nfs-utils
state: absent
when:
- not rhel9cis_use_nfs_server
- not rhel9cis_use_nfs_service
- name: "2.2.18 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked | mask service"
systemd:
- name: "2.2.16 | PATCH | Ensure nfs-utils is not installed or the nfs-server service is masked | mask service"
ansible.builtin.systemd:
name: nfs-server
masked: true
state: stopped
@ -323,30 +280,29 @@
- rhel9cis_use_nfs_service
when:
- "'nfs-utils' in ansible_facts.packages"
- rhel9cis_rule_2_2_18
- rhel9cis_rule_2_2_16
tags:
- level1-server
- level1-workstation
- automated
- patch
- nfs
- services
- rule_2.2.18
- rule_2.2.16
# The name title of the service says mask the service, but the fix allows for both options
# Options available in default/main if to remove the package default is false just mask the server service
- name: "2.2.19 | PATCH | Ensure rpcbind is not installed or the rpcbind services are masked"
- name: "2.2.17 | PATCH | Ensure rpcbind is not installed or the rpcbind services are masked"
block:
- name: "2.2.19 | PATCH | Ensure rpcbind is not installed or the rpcbind services are masked | remove package"
package:
- name: "2.2.17 | PATCH | Ensure rpcbind is not installed or the rpcbind services are masked | remove package"
ansible.builtin.package:
name: rpcbind
state: absent
when:
- not rhel9cis_use_rpc_server
- not rhel9cis_use_rpc_service
- name: "2.2.19 | PATCH | Ensure rpcbind is not installed or the rpcbind services are masked | mask service"
systemd:
- name: "2.2.17 | PATCH | Ensure rpcbind is not installed or the rpcbind services are masked | mask service"
ansible.builtin.systemd:
name: rpcbind.socket
masked: true
state: stopped
@ -355,29 +311,28 @@
- not rhel9cis_use_rpc_service
when:
- "'rpcbind' in ansible_facts.packages"
- rhel9cis_rule_2_2_19
- rhel9cis_rule_2_2_17
tags:
- level1-server
- level1-workstation
- automated
- patch
- rpc
- rule_2.2.19
- rule_2.2.17
# The name title of the service says mask the service, but the fix allows for both options
# Options available in default/main if to remove the package default is false just mask the server service
- name: "2.2.20 | PATCH | Ensure rsync service is not enabled "
- name: "2.2.18 | PATCH | Ensure rsync service is not enabled "
block:
- name: "2.2.20 | PATCH | Ensure rsync service is not enabled | remove package"
package:
name: rsync
- name: "2.2.18 | PATCH | Ensure rsync-daemon is not installed or the rsync service is masked | remove package"
ansible.builtin.package:
name: rsync-daemon
state: absent
when:
- not rhel9cis_use_rsync_server
- not rhel9cis_use_rsync_service
- name: "2.2.20 | PATCH | Ensure rsync service is not enabled | mask service"
systemd:
- name: "2.2.18 | PATCH | Ensure rsync service is not enabled | mask service"
ansible.builtin.systemd:
name: rsyncd
masked: true
state: stopped
@ -386,11 +341,10 @@
- not rhel9cis_use_rsync_service
when:
- "'rsync' in ansible_facts.packages"
- rhel9cis_rule_2_2_20
- rhel9cis_rule_2_2_18
tags:
- level1-server
- level1-workstation
- automated
- patch
- rsync
- rule_2.2.20
- rule_2.2.18

View file

@ -1,97 +1,61 @@
---
- name: "2.3.1 | PATCH | Ensure NIS Client is not installed"
package:
name: ypbind
state: absent
when:
- not rhel9cis_ypbind_required
- "'ypbind' in ansible_facts.packages"
- rhel9cis_rule_2_3_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- nis
- rule_2.3.1
- name: "2.3.2 | PATCH | Ensure rsh client is not installed"
package:
name: rsh
state: absent
when:
- not rhel9cis_rsh_required
- "'rsh' in ansible_facts.packages"
- rhel9cis_rule_2_3_2
tags:
- level1-server
- level2-server
- automated
- patch
- rsh
- rule_2.3.2
- name: "2.3.3 | PATCH | Ensure talk client is not installed"
package:
name: talk
state: absent
when:
- not rhel9cis_talk_required
- "'talk' in ansible_facts.packages"
- rhel9cis_rule_2_3_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- talk
- rule_2.3.3
- name: "2.3.4 | PATCH | Ensure telnet client is not installed"
package:
- name: "2.3.1 | PATCH | Ensure telnet client is not installed"
ansible.builtin.package:
name: telnet
state: absent
when:
- not rhel9cis_telnet_required
- "'telnet' in ansible_facts.packages"
- rhel9cis_rule_2_3_4
- rhel9cis_rule_2_3_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- telnet
- rule_2.3.4
- rule_2.3.1
- name: "2.3.5 | PATCH | Ensure LDAP client is not installed"
package:
- name: "2.3.2 | PATCH | Ensure LDAP client is not installed"
ansible.builtin.package:
name: openldap-clients
state: absent
when:
- not rhel9cis_openldap_clients_required
- "'openldap-clients' in ansible_facts.packages"
- rhel9cis_rule_2_3_5
- rhel9cis_rule_2_3_2
tags:
- level1-server
- level1-workstation
- automated
- patch
- ldap
- rule_2.3.5
- rule_2.3.2
- name: "2.3.6 | PATCH | Ensure TFTP client is not installed"
package:
- name: "2.3.3 | PATCH | Ensure TFTP client is not installed"
ansible.builtin.package:
name: tftp
state: absent
when:
- not rhel9cis_tftp_client
- "'tftp' in ansible_facts.packages"
- rhel9cis_rule_2_3_6
- rhel9cis_rule_2_3_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- tftp
- rule_2.3.6
- rule_2.3.3
- name: "2.3.4 | PATCH | Ensure FTP client is not installed"
ansible.builtin.package:
name: ftp
state: absent
when:
- not rhel9cis_tftp_client
- "'ftp' in ansible_facts.packages"
- rhel9cis_rule_2_3_4
tags:
- level1-server
- level1-workstation
- patch
- ftp
- rule_2.3.4

View file

@ -1,25 +1,33 @@
---
- name: "2.4 | AUDIT | Ensure nonessential services are removed or masked"
- name: "2.4 | AUDIT | Ensure nonessential services listening on the system are removed or masked"
block:
- name: "2.4 | AUDIT | Ensure nonessential services are removed or masked | Get list of services"
shell: systemctl list-units --type=service
- name: "2.4 | AUDIT | Ensure nonessential services listening on the system are removed or masked | Get list of services"
ansible.builtin.shell: systemctl list-units --type=service
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_2_4_services
- name: "2.4 | AUDIT | Ensure nonessential services are removed or masked | Display list of services"
debug:
- name: "2.4 | AUDIT | Ensure nonessential services listening on the system are removed or masked | Get list of sockets"
ansible.builtin.shell: systemctl list-units --type=sockets
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_2_4_sockets
- name: "2.4 | AUDIT | Ensure nonessential services listening on the system are removed or masked | Display list of services"
ansible.builtin.debug:
msg:
- "Warning!! Below are the list of services, both active and inactive"
- "Warning!! Below are the list of services and sockets, both active and inactive"
- "Please review to make sure all are essential"
- "{{ rhel9cis_2_4_services.stdout_lines }}"
- "{{ rhel9cis_2_4_sockets.stdout_lines }}"
- name: "2.4 | AUDIT | Ensure nonessential services are removed or masked | Warn Count"
set_fact:
control_number: "{{ control_number }} + ['rule_2.4']"
warn_count: "{{ warn_count | int + 1 }}"
- name: "2.4 | AUDIT | Ensure nonessential services listening on the system are removed or masked | Warn Count"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '2.4'
when:
- rhel9cis_rule_2_4
tags:

View file

@ -1,13 +1,13 @@
---
- name: "SECTION | 2.1 | Time Synchronization"
import_tasks: cis_2.1.x.yml
ansible.builtin.import_tasks: cis_2.1.x.yml
- name: "SECTION | 2.2 | Special Purpose Services"
import_tasks: cis_2.2.x.yml
ansible.builtin.import_tasks: cis_2.2.x.yml
- name: "SECTION | 2.3 | Service Clients"
import_tasks: cis_2.3.x.yml
ansible.builtin.import_tasks: cis_2.3.x.yml
- name: "SECTION | 2.4 | Nonessential services removed"
import_tasks: cis_2.4.yml
ansible.builtin.import_tasks: cis_2.4.yml

View file

@ -2,15 +2,15 @@
# The CIS Control wants IPv6 disabled if not in use.
# We are using the rhel9cis_ipv6_required to specify if you have IPv6 in use
- name: "3.1.1 | PATCH | Verify if IPv6 is enabled on the system"
- name: "3.1.1 | PATCH | Ensure IPv6 status is identified"
block:
- name: "3.1.1 | PATCH | Verify if IPv6 is enabled on the system"
set_fact:
- name: "3.1.1 | PATCH | Ensure IPv6 status is identified | refresh"
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv6_route: true
- name: "3.1.1 | PATCH | Verify if IPv6 is enabled on the system"
debug:
- name: "3.1.1 | PATCH | Ensure IPv6 status is identified | disable"
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-disable_ipv6.conf"
when:
- not rhel9cis_ipv6_required
@ -24,72 +24,60 @@
- networking
- rule_3.1.1
- name: "3.1.2 | PATCH | Ensure SCTP is disabled"
template:
src: "etc/modprobe.d/modprobe.conf.j2"
dest: "/etc/modprobe.d/{{ item }}.conf"
mode: "0600"
owner: root
group: root
with_items:
- sctp
- name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled"
block:
- name: "3.1.2 | AUDIT | Ensure wireless interfaces are disabled | Check if nmcli command is available"
ansible.builtin.shell: rpm -q NetworkManager
changed_when: false
failed_when: false
check_mode: false
register: rhel_09_nmcli_available
- name: "3.1.2 | AUDIT | Ensure wireless interfaces are disabled | Check if wifi is enabled"
ansible.builtin.shell: nmcli radio wifi
register: rhel_09_wifi_enabled
changed_when: rhel_09_wifi_enabled.stdout != "disabled"
failed_when: false
when: rhel_09_nmcli_available.rc == 0
- name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Disable wifi if enabled"
ansible.builtin.shell: nmcli radio all off
changed_when: false
failed_when: false
when: rhel_09_wifi_enabled is changed
when:
- rhel9cis_rule_3_1_2
tags:
- level2-server
- level2-workstation
- automated
- level1-server
- patch
- sctp
- wireless
- rule_3.1.2
- name: "3.1.3 | PATCH | Ensure DCCP is disabled"
template:
src: "etc/modprobe.d/modprobe.conf.j2"
dest: "/etc/modprobe.d/{{ item }}.conf"
mode: "0600"
owner: root
group: root
with_items:
- dccp
- name: "3.1.3 | PATCH | Ensure TIPC is disabled"
block:
- name: "3.1.3 | PATCH | Ensure TIPC is disabled"
ansible.builtin.template:
src: "etc/modprobe.d/modprobe.conf.j2"
dest: "/etc/modprobe.d/{{ item }}.conf"
mode: "0600"
owner: root
group: root
loop:
- tipc
# note the item used in the template
- name: "3.1.3 | PATCH | Ensure TIPC is disabled | blacklist"
ansible.builtin.lineinfile:
path: /etc/modprobe.d/blacklist.conf
regexp: "^(#)?blacklist tipc(\\s|$)"
line: "blacklist tipc"
create: true
mode: 0600
when:
- rhel9cis_rule_3_1_3
tags:
- level2-server
- level2-workstation
- automated
- dccp
- patch
- tipc
- rule_3.1.3
- name: "3.1.4 | PATCH | Ensure wireless interfaces are disabled"
block:
- name: "3.1.4 | AUDIT | Ensure wireless interfaces are disabled | Check if nmcli command is available"
command: rpm -q NetworkManager
changed_when: false
failed_when: false
check_mode: false
args:
warn: false
register: rhel_08_nmcli_available
- name: "3.1.4 | AUDIT | Ensure wireless interfaces are disabled | Check if wifi is enabled"
command: nmcli radio wifi
register: rhel_08_wifi_enabled
changed_when: rhel_08_wifi_enabled.stdout != "disabled"
failed_when: false
when: rhel_08_nmcli_available.rc == 0
- name: "3.1.4 | PATCH | Ensure wireless interfaces are disabled | Disable wifi if enabled"
command: nmcli radio all off
changed_when: false
failed_when: false
when: rhel_08_wifi_enabled is changed
when:
- rhel9cis_rule_3_1_4
tags:
- level1-server
- automated
- patch
- wireless
- rule_3.1.4

View file

@ -3,22 +3,22 @@
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled"
block:
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv4 forwarding | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv4 forwarding"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | IPv6"
block:
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv6 forwarding | Set Fact"
set_fact:
ansible.builtin.set_fact:
flush_ipv6_route: true
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv6 forwarding"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl.conf"
when: rhel9cis_ipv6_required
@ -28,7 +28,6 @@
tags:
- level1-server
- level1-workstation
- automated
- sysctl
- patch
- rule_3.2.1
@ -36,11 +35,11 @@
- name: "3.2.2 | PATCH | Ensure packet redirect sending is disabled"
block:
- name: "3.2.2 | PATCH | Ensure packet redirect sending is disabled | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.2.2 | PATCH | Ensure packet redirect sending is disabled"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- not rhel9cis_is_router
@ -48,7 +47,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- sysctl
- rule_3.2.2

View file

@ -3,21 +3,21 @@
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted"
block:
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv4 | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv4"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv6"
block:
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv6 | Set Fact"
set_fact:
ansible.builtin.set_fact:
flush_ipv6_route: true
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv6"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl.conf"
when: rhel9cis_ipv6_required
when:
@ -32,22 +32,22 @@
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted"
block:
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv4 | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv4"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv6"
block:
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv6 | Set Fact"
set_fact:
ansible.builtin.set_fact:
flush_ipv6_route: true
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv6"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl.conf"
when: rhel9cis_ipv6_required
when:
@ -62,12 +62,12 @@
- name: "3.3.3 | PATCH | Ensure secure ICMP redirects are not accepted"
block:
- name: "3.3.3 | PATCH | Ensure secure ICMP redirects are not accepted | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.3 | PATCH | Ensure secure ICMP redirects are not accepted"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_3
@ -81,12 +81,12 @@
- name: "3.3.4 | PATCH | Ensure suspicious packets are logged"
block:
- name: "3.3.4 | PATCH | Ensure suspicious packets are logged | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.4 | PATCH | Ensure suspicious packets are logged"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_4
@ -100,12 +100,12 @@
- name: "3.3.5 | PATCH | Ensure broadcast ICMP requests are ignored"
block:
- name: "3.3.5 | PATCH | Ensure broadcast ICMP requests are ignored | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: 3.3.5 | PATCH | Ensure broadcast ICMP requests are ignored"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_5
@ -119,12 +119,12 @@
- name: "3.3.6 | PATCH | Ensure bogus ICMP responses are ignored"
block:
- name: "3.3.6 | PATCH | Ensure bogus ICMP responses are ignored | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.6 | PATCH | Ensure bogus ICMP responses are ignored"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_6
@ -138,12 +138,12 @@
- name: "3.3.7 | PATCH | Ensure Reverse Path Filtering is enabled"
block:
- name: "3.3.7 | PATCH | Ensure Reverse Path Filtering is enabled | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.7 | PATCH | Ensure Reverse Path Filtering is enabled"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_7
@ -157,12 +157,12 @@
- name: "3.3.8 | PATCH | Ensure TCP SYN Cookies is enabled"
block:
- name: "3.3.8 | PATCH | Ensure TCP SYN Cookies is enabled | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.8 | PATCH | Ensure TCP SYN Cookies is enabled"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_8
@ -176,12 +176,12 @@
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted"
block:
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted | IPv6 | Set Fact"
set_fact:
ansible.builtin.set_fact:
sysctl_update: true
flush_ipv6_route: true
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted | IPv6"
debug:
ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl"
when:
- rhel9cis_ipv6_required

View file

@ -1,153 +1,59 @@
---
- name: "3.4.1.1 | PATCH | Ensure firewalld is installed"
package:
- name: "3.4.1.1 | PATCH | Ensure nftables is installed"
ansible.builtin.package:
name:
- firewalld
- iptables
- nftables
state: present
when:
- rhel9cis_rule_3_4_1_1
- rhel9cis_firewall == 'nftables'
tags:
- level1-server
- level1-workstation
- automated
- patch
- firewalld
- nftables
- rule_3.4.1.1
- name: "3.4.1.2 | PATCH | Ensure iptables-services not installed with firewalld"
- name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use"
block:
- name: "3.4.1.2 | PATCH | Ensure iptables-services not installed with firewalld | Stop running services"
systemd:
- name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | nftables"
ansible.builtin.systemd:
name: "{{ item }}"
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-services pkg "
package:
name: iptables-services
state: absent
loop:
- firewalld
when:
- item in ansible_facts.packages
- rhel9cis_firewall == 'nftables'
- name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | firewalld"
ansible.builtin.systemd:
name: "{{ item }}"
masked: true
loop:
- nftables
when:
- item in ansible_facts.packages
- rhel9cis_firewall == 'firewalld'
- name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | package installed"
ansible.builtin.package:
name: "{{ rhel9cis_firewall }}"
state: installed
- name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | {{ rhel9cis_firewall }} started and enabled"
ansible.builtin.systemd:
name: "{{ rhel9cis_firewall }}"
enabled: true
state: started
when:
- rhel9cis_rule_3_4_1_2
- "'iptables-services' in ansible_facts.packages"
tags:
- level1-server
- level1-workstation
- automated
- patch
- firewalld
- nftables
- rule_3.4.1.2
- name: "3.4.1.3 | PATCH | Ensure nftables either not installed or masked with firewalld"
block:
- name: "3.4.1.3 | PATCH | Ensure nftables either not installed or masked with firewalld | mask service"
systemd:
name: nftables
state: stopped
masked: true
when:
- rhel9cis_firewalld_nftables_state == "masked"
- name: "3.4.1.3 | PATCH | Ensure nftables either not installed or masked with firewalld | pkg removed"
package:
name: nftables
state: absent
when:
- rhel9cis_firewalld_nftables_state == "absent"
when:
- 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: true
when:
- 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"
block:
- name: "3.4.1.5 | AUDIT | Ensure firewalld default zone is set"
shell: "firewall-cmd --get-default-zone | grep {{ rhel9cis_default_zone }}"
changed_when: false
failed_when: ( firewalld_zone_set.rc not in [ 0, 1 ] )
register: firewalld_zone_set
- name: "3.4.1.5 | AUDIT | Ensure firewalld default zone is set"
command: firewall-cmd --set-default-zone="{{ rhel9cis_default_zone }}"
when:
- firewalld_zone_set.rc != 0
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: false
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_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: false
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_rule_3_4_1_7
tags:
- level1-server
- level1-workstation
- manual
- audit
- rule_3.4.1.7

View file

@ -1,352 +1,300 @@
---
- name: "3.4.2.1 | PATCH | Ensure nftables is installed"
package:
name: nftables
state: present
- name: "3.4.2.1 | PATCH | Ensure firewalld default zone is set"
block:
- name: "3.4.2.1 | AUDIT | Ensure firewalld default zone is set"
ansible.builtin.shell: "firewall-cmd --get-default-zone | grep {{ rhel9cis_default_zone }}"
changed_when: false
failed_when: ( firewalld_zone_set.rc not in [ 0, 1 ] )
register: firewalld_zone_set
- name: "3.4.2.1 | AUDIT | Ensure firewalld default zone is set"
ansible.builtin.command: firewall-cmd --set-default-zone="{{ rhel9cis_default_zone }}"
when: firewalld_zone_set.rc != 0
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_firewall == "firewalld"
- rhel9cis_rule_3_4_2_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- nftables
- firewalld
- rule_3.4.2.1
# 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
- name: "3.4.2.2 | AUDIT | Ensure at least one nftables table exists"
block:
- name: "3.4.2.2 | AUDIT | Ensure a table exists | Check for tables"
ansible.builtin.command: nft list tables
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_2_nft_tables
- name: "3.4.2.2 | AUDIT | Ensure an nftables table exists | Show existing tables"
ansible.builtin.debug:
msg:
- "Below are the current nft tables, please review"
- "{{ rhel9cis_3_4_2_2_nft_tables.stdout_lines }}"
when: rhel9cis_3_4_2_2_nft_tables.stdout | length > 0
- name: "3.4.2.2 | AUDIT | Ensure an nftables table exists | Alert on no tables"
ansible.builtin.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_3_4_2_2_nft_tables.stdout | length == 0
- not rhel9cis_nft_tables_autonewtable
- name: "3.4.2.2 | AUDIT | Ensure an nftables table exists | Alert on no tables | warning count"
ansible.builtin.import_tasks: warning_facts.yml
when:
- rhel9cis_3_4_2_2_nft_tables.stdout | length == 0
- not rhel9cis_nft_tables_autonewtable
- name: "3.4.2.2 | PATCH | Ensure a table exists | Create table if needed"
ansible.builtin.command: nft create table inet "{{ rhel9cis_nft_tables_tablename }}"
failed_when: false
when: rhel9cis_nft_tables_autonewtable
vars:
warn_control_id: '3.4.2.2'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_2
tags:
- level1-server
- level1-workstation
- automated
- patch
- nftables
- rule_3.4.2.2
- name: "3.4.2.3 | PATCH | Ensure iptables-services not installed with nftables"
- name: "3.4.2.3 | PATCH | Ensure nftables base chains exist"
block:
- name: "3.4.2.3 | PATCH | Ensure iptables-services not installed with nftables | Stop services"
systemd:
name: "{{ item }}"
enabled: false
masked: true
ignore_errors: true # noqa ignore-errors
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 == "nftables"
- rhel9cis_rule_3_4_2_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- nftables
- rule_3.4.2.3
- 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_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 | AUDIT | Ensure an nftables table exists"
block:
- name: "3.4.2.5 | AUDIT | Ensure a table exists | Check for tables"
command: nft list tables
- name: "3.4.2.3 | AUDIT | Ensure nftables base chains exist | Get current chains for INPUT"
ansible.builtin.shell: nft list ruleset | grep 'hook input'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_5_nft_tables
register: rhel9cis_3_4_2_3_input_chains
- name: "3.4.2.5 | AUDIT | Ensure an nftables table exists | Show existing tables"
debug:
msg:
- "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_3_4_2_5_nft_tables.stdout | length == 0
- not rhel9cis_nft_tables_autonewtable
- name: "3.4.2.5 | AUDIT | Ensure an nftables table exists | Alert on no tables | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_3.4.2.5' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- 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: false
when: rhel9cis_nft_tables_autonewtable
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_5
tags:
- level1-server
- level1-workstation
- automated
- patch
- nftables
- rule_3.4.2.5
- name: "3.4.2.6 | PATCH | Ensure nftables base chains exist"
block:
- name: "3.4.2.6 | AUDIT | Ensure nftables base chains exist | Get current chains for INPUT"
shell: nft list ruleset | grep 'hook input'
- name: "3.4.2.3 | AUDIT | Ensure nftables base chains exist | Get current chains for FORWARD"
ansible.builtin.shell: nft list ruleset | grep 'hook forward'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_6_input_chains
register: rhel9cis_3_4_2_3_forward_chains
- name: "3.4.2.6 | AUDIT | Ensure nftables base chains exist | Get current chains for FORWARD"
shell: nft list ruleset | grep 'hook forward'
- name: "3.4.2.3 | AUDIT | Ensure nftables base chains exist | Get current chains for OUTPUT"
ansible.builtin.shell: nft list ruleset | grep 'hook output'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_6_forward_chains
register: rhel9cis_3_4_2_3_output_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:
- name: "3.4.2.3 | AUDIT | Ensure nftables base chains exist | Display chains for review"
ansible.builtin.debug:
msg:
- "Below are the current INPUT chains"
- "{{ rhel9cis_3_4_2_6_input_chains.stdout_lines }}"
- "{{ rhel9cis_3_4_2_3_input_chains.stdout_lines }}"
- "Below are the current FORWARD chains"
- "{{ rhel9cis_3_4_2_6_forward_chains.stdout_lines }}"
- "{{ rhel9cis_3_4_2_3_forward_chains.stdout_lines }}"
- "Below are teh current OUTPUT chains"
- "{{ rhel9cis_3_4_2_6_output_chains.stdout_lines }}"
- "{{ rhel9cis_3_4_2_3_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: false
- name: "3.4.2.3 | PATCH | Ensure nftables base chains exist | Create chains if needed"
ansible.builtin.shell: "{{ item }}"
failed_when: false
with_items:
loop:
- 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_2_3
tags:
- level1-server
- level1-workstation
- patch
- nftables
- rule_3.4.2.3
- name: "3.4.2.4 | PATCH | Ensure host based firewall loopback traffic is configured"
block:
- name: "3.4.2.4 | AUDIT | Ensure host based firewall loopback traffic is configured | Gather iif lo accept existence | nftables"
ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_4_iiflo
- name: "3.4.2.4 | AUDIT | Ensure host based firewall loopback traffic is configured | Gather ip saddr existence | nftables"
ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_4_ipsaddr
- name: "3.4.2.4 | AUDIT | Ensure host based firewall loopback traffic is configured | Gather ip6 saddr existence | nftables"
ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr'
changed_when: false
failed_when: false
register: rhel9cis_3_4_2_4_ip6saddr
- name: "3.4.2.4 | PATCH | Ensure host based firewall loopback traffic is configured | Set iif lo accept rule | nftables"
ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input iif lo accept
when: '"iif \"lo\" accept" not in rhel9cis_3_4_2_4_iiflo.stdout'
- name: "3.4.2.4 | PATCH | Ensure host based firewall loopback traffic is configured | Set ip sddr rule | nftables"
ansible.builtin.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_4_ipsaddr.stdout'
- name: "3.4.2.4 | PATCH | Ensure host based firewall loopback traffic is configured | Set ip6 saddr rule | nftables"
ansible.builtin.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_4_ip6saddr.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_4
tags:
- level1-server
- level1-workstation
- patch
- nftables
- rule_3.4.2.4
- name: "3.4.2.4 | PATCH | Ensure host based firewall loopback traffic is configured | firewalld"
ansible.posix.firewalld:
rich_rule: "{{ item }}"
zone: "{{ rhel9cis_default_zone }}"
permanent: true
immediate: true
state: enabled
loop:
- rule family="ipv4" source address="127.0.0.1" destination not address="127.0.0.1" drop
- rule family="ipv6" source address="::1" destination not address="::1" drop
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_rule_3_4_2_4
tags:
- level1-server
- level1-workstation
- patch
- nftables
- rule_3.4.2.4
- name: "3.4.2.5 | AUDIT | Ensure firewalld drops unnecessary services and ports"
block:
- name: "3.4.2.5 | AUDIT | Ensure firewalld drops unnecessary services and ports | Get list of services and ports"
ansible.builtin.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: false
register: rhel9cis_3_4_2_5_servicesport
- name: "3.4.2.5 | AUDIT | Ensure firewalld drops unnecessary services and ports | Show services and ports"
ansible.builtin.debug:
msg:
- "The items below are the services and ports that are accepted, please correct as needed"
- "{{ rhel9cis_3_4_2_5_servicesport.stdout_lines }}"
when:
- rhel9cis_rule_3_4_2_5
tags:
- level1-server
- level1-workstation
- manual
- audit
- rule_3.4.2.5
- name: "3.4.2.6 | PATCH | Ensure nftables established connections are configured"
block:
- name: "3.4.2.6 | AUDIT | EEnsure nftables established connections are configured | Gather incoming connection rules"
ansible.builtin.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_6_inconnectionrule
- name: "3.4.2.6| AUDIT | Ensure nftables established connections are configured | Gather outbound connection rules"
ansible.builtin.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_6_outconnectionrule
- name: "3.4.2.6| PATCH | Ensure nftables established connections are configured | Add input tcp established accept policy"
ansible.builtin.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_6_inconnectionrule.stdout'
- name: "3.4.2.6 | PATCH | Ensure nftables established connections are configured | Add input udp established accept policy"
ansible.builtin.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_6_inconnectionrule.stdout'
- name: "3.4.2.6 | PATCH | Ensure nftables established connections are configured | Add input icmp established accept policy"
ansible.builtin.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_6_inconnectionrule.stdout'
- name: "3.4.2.6 | PATCH | Ensure nftables established connections are configured | Add output tcp new, related, established accept policy"
ansible.builtin.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_6_outconnectionrule.stdout'
- name: "3.4.2.6 | PATCH | Ensure nftables established connections are configured | Add output udp new, related, established accept policy"
ansible.builtin.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_6_outconnectionrule.stdout'
- name: "3.4.2.6 | PATCH | Ensure nftables established connections are configured | Add output icmp new, related, established accept policy"
ansible.builtin.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_6_outconnectionrule.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_6
tags:
- level1-server
- level1-workstation
- automated
- patch
- nftables
- rule_3.4.2.6
- name: "3.4.2.7 | PATCH | Ensure nftables loopback traffic is configured"
- name: "3.4.2.7 | PATCH | Ensure nftables default deny firewall policy"
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
- name: "3.4.2.7 | AUDIT | Ensure nftables default deny firewall policy | Check for hook input deny policy"
ansible.builtin.shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook input'
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
register: rhel9cis_3_4_2_7_inputpolicy
- 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'
- name: "3.4.2.7 | AUDIT | Ensure nftables default deny firewall policy | Check for hook forward deny policy"
ansible.builtin.shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook forward'
failed_when: false
changed_when: false
register: rhel9cis_3_4_2_7_forwardpolicy
- name: "3.4.2.7 | AUDIT | Ensure nftables default deny firewall policy | Check for hook output deny policy"
ansible.builtin.shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook output'
failed_when: false
register: rhel9cis_3_4_2_7_ip6saddr
changed_when: false
register: rhel9cis_3_4_2_7_outputpolicy
- 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 | AUDIT | Ensure nftables default deny firewall policy | Check for SSH allow"
ansible.builtin.shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'ssh'
failed_when: false
changed_when: false
register: rhel9cis_3_4_2_7_sshallowcheck
- 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 default deny firewall policy | Enable SSH traffic"
ansible.builtin.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_7_sshallowcheck.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'
- name: "3.4.2.7 | PATCH | Ensure nftables default deny firewall policy | Set hook input deny policy"
ansible.builtin.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_7_inputpolicy.stdout'
- name: "3.4.2.7 | PATCH | Ensure nftables default deny firewall policy | Create hook forward deny policy"
ansible.builtin.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_7_forwardpolicy.stdout'
- name: "3.4.2.7 | PATCH | Ensure nftables default deny firewall policy | Create hook output deny policy"
ansible.builtin.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_7_outputpolicy.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: true
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

@ -1,20 +1,16 @@
---
- name: "SECTION | 3.1.x | Disable unused network protocols and devices"
import_tasks: cis_3.1.x.yml
ansible.builtin.import_tasks: cis_3.1.x.yml
- name: "SECTION | 3.2.x | Network Parameters (Host Only)"
import_tasks: cis_3.2.x.yml
ansible.builtin.import_tasks: cis_3.2.x.yml
- name: "SECTION | 3.3.x | Network Parameters (host and Router)"
import_tasks: cis_3.3.x.yml
ansible.builtin.import_tasks: cis_3.3.x.yml
- name: "SECTION | 3.4.1.x | Configure firewalld"
import_tasks: cis_3.4.1.x.yml
when:
- rhel9cis_firewall == "firewalld"
- name: "SECTION | 3.4.1.x | Firewall configuration"
ansible.builtin.import_tasks: cis_3.4.1.x.yml
- name: "SECTION | 3.4.2.x | Configure nftables"
include_tasks: cis_3.4.2.x.yml
when:
- rhel9cis_firewall == "nftables"
- name: "SECTION | 3.4.2.x | Configure firewall"
ansible.builtin.import_tasks: cis_3.4.2.x.yml

View file

@ -3,13 +3,13 @@
- name: "4.1.1.1 | PATCH | Ensure auditd is installed"
block:
- name: "4.1.1.1 | PATCH | Ensure auditd is installed | Install auditd packages"
package:
ansible.builtin.package:
name: audit
state: present
when: '"auditd" not in ansible_facts.packages'
- name: "4.1.1.1 | PATCH | Ensure auditd is installed | Install auditd-lib packages"
package:
ansible.builtin.package:
name: audit-libs
state: present
when: '"auditd-lib" not in ansible_facts.packages'
@ -18,92 +18,88 @@
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.1.1
- name: "4.1.1.2 | PATCH | Ensure auditd service is enabled"
service:
name: auditd
state: started
enabled: true
- name: "4.1.1.2 | PATCH | Ensure auditing for processes that start prior to auditd is enabled"
block:
- name: "4.1.1.2 | AUDIT | Ensure auditing for processes that start prior to auditd is enabled | Get GRUB_CMDLINE_LINUX"
ansible.builtin.shell: grep 'GRUB_CMDLINE_LINUX=' /etc/default/grub | sed 's/.$//'
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_4_1_1_2_grub_cmdline_linux
- name: "4.1.1.2 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Replace existing setting"
ansible.builtin.replace:
path: /etc/default/grub
regexp: 'audit=.'
replace: 'audit=1'
notify: Grub2cfg
when: "'audit=' in rhel9cis_4_1_1_2_grub_cmdline_linux.stdout"
- name: "4.1.1.2 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Add audit setting if missing"
ansible.builtin.lineinfile:
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX='
line: '{{ rhel9cis_4_1_1_2_grub_cmdline_linux.stdout }} audit=1"'
notify: Grub2cfg
when: "'audit=' not in rhel9cis_4_1_1_2_grub_cmdline_linux.stdout"
when:
- rhel9cis_rule_4_1_1_2
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- grub
- rule_4.1.1.2
- name: "4.1.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled"
- name: "4.1.1.3 | PATCH | Ensure audit_backlog_limit is sufficient"
block:
- 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/.$//'
- name: "4.1.1.3 | AUDIT | Ensure audit_backlog_limit is sufficient | Get GRUB_CMDLINE_LINUX"
ansible.builtin.shell: grep 'GRUB_CMDLINE_LINUX=' /etc/default/grub | sed 's/.$//'
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_4_1_1_3_grub_cmdline_linux
- 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=.'
replace: 'audit=1'
notify: grub2cfg
when: "'audit=' in rhel9cis_4_1_1_3_grub_cmdline_linux.stdout"
- name: "4.1.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Replace existing setting"
ansible.builtin.replace:
path: /etc/default/grub
regexp: 'audit_backlog_limit=\d+'
replace: 'audit_backlog_limit={{ rhel9cis_audit_back_log_limit }}'
notify: Grub2cfg
when: "'audit_backlog_limit=' in rhel9cis_4_1_1_3_grub_cmdline_linux.stdout"
- name: "4.1.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Add audit setting if missing"
lineinfile:
- name: "4.1.1.3 | PATCH | Ensure audit_backlog_limit is sufficient | Add audit_backlog_limit setting if missing"
ansible.builtin.lineinfile:
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX='
line: '{{ rhel9cis_4_1_1_3_grub_cmdline_linux.stdout }} audit=1"'
notify: grub2cfg
when: "'audit=' not in rhel9cis_4_1_1_3_grub_cmdline_linux.stdout"
line: '{{ rhel9cis_4_1_1_3_grub_cmdline_linux.stdout }} audit_backlog_limit={{ rhel9cis_audit_back_log_limit }}"'
notify: Grub2cfg
when: "'audit_backlog_limit=' not in rhel9cis_4_1_1_3_grub_cmdline_linux.stdout"
when:
- rhel9cis_rule_4_1_1_3
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- grub
- rule_4.1.1.3
- name: "4.1.1.4 | PATCH | Ensure audit_backlog_limit is sufficient"
block:
- 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/.$//'
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_4_1_1_4_grub_cmdline_linux
- 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+'
replace: 'audit_backlog_limit={{ rhel9cis_audit_back_log_limit }}'
notify: grub2cfg
when: "'audit_backlog_limit=' in rhel9cis_4_1_1_4_grub_cmdline_linux.stdout"
- 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='
line: '{{ rhel9cis_4_1_1_4_grub_cmdline_linux.stdout }} audit_backlog_limit={{ rhel9cis_audit_back_log_limit }}"'
notify: grub2cfg
when: "'audit_backlog_limit=' not in rhel9cis_4_1_1_4_grub_cmdline_linux.stdout"
- name: "4.1.1.4 | PATCH | Ensure auditd service is enabled"
ansible.builtin.systemd:
name: auditd
state: started
enabled: true
when:
- rhel9cis_rule_4_1_1_4
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- grub
- rule_4.1.1.4

View file

@ -1,44 +1,42 @@
---
- name: "4.1.2.1 | PATCH | Ensure audit log storage size is configured"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/audit/auditd.conf
regexp: "^max_log_file( |=)"
line: "max_log_file = {{ rhel9cis_max_log_file_size }}"
notify: restart auditd
notify: Restart auditd
when:
- rhel9cis_rule_4_1_2_1
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.2.1
- name: "4.1.2.2 | PATCH | Ensure audit logs are not automatically deleted"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/audit/auditd.conf
regexp: "^max_log_file_action"
line: "max_log_file_action = {{ rhel9cis_auditd['max_log_file_action'] }}"
notify: restart auditd
notify: Restart auditd
when:
- rhel9cis_rule_4_1_2_2
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.2.2
- name: "4.1.2.3 | PATCH | Ensure system is disabled when audit logs are full"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/audit/auditd.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
notify: restart auditd
with_items:
notify: Restart auditd
loop:
- { regexp: '^admin_space_left_action', line: 'admin_space_left_action = {{ rhel9cis_auditd.admin_space_left_action }}' }
- { regexp: '^action_mail_acct', line: 'action_mail_acct = {{ rhel9cis_auditd.action_mail_acct }}' }
- { regexp: '^space_left_action', line: 'space_left_action = {{ rhel9cis_auditd.space_left_action }}' }
@ -47,23 +45,21 @@
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.2.3
- name: PATCH | Configure other keys for auditd.conf
lineinfile:
ansible.builtin.lineinfile:
path: /etc/audit/auditd.conf
regexp: "^{{ item }}( |=)"
line: "{{ item }} = {{ rhel9cis_auditd_extra_conf[item] }}"
loop: "{{ rhel9cis_auditd_extra_conf.keys() }}"
notify: restart auditd
notify: Restart auditd
when:
- rhel9cis_auditd_extra_conf.keys() | length > 0
- rhel9cis_auditd_extra_conf.keys() | length > 0
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd

View file

@ -2,70 +2,65 @@
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.1 | PATCH | Ensure changes to system administration scope (sudoers) is collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_1
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.1
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.2 | PATCH | Ensure actions as another user are always logged"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_2
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.2
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.3 | PATCH | Ensure events that modify the sudo log file are collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_3
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.3
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.4 | PATCH | Ensure events that modify date and time information are collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_4
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.4
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.5 | PATCH | Ensure events that modify the system's network environment are collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_5
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.5
@ -74,14 +69,14 @@
- 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
ansible.builtin.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: false
register: priv_procs
- name: "4.1.3.6 | PATCH | Ensure use of privileged commands is collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
notify: update auditd
when:
@ -89,98 +84,91 @@
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.6
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.7 | PATCH | Ensure unsuccessful unauthorized file access attempts are collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_7
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3_7
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.8 | PATCH | Ensure events that modify user/group information are collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_8
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.8
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.9 | PATCH | Ensure discretionary access control permission modification events are collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_9
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.9
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.10 | PATCH | Ensure successful file system mounts are collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_10
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.10
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.11 | PATCH | Ensure session initiation information is collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_11
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.11
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.12 | PATCH | Ensure login and logout events are collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_12
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.12
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.13 | PATCH | Ensure file deletion events by users are collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_13
@ -193,104 +181,97 @@
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.14 | PATCH | Ensure events that modify the system's Mandatory Access Controls are collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_14
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.14
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.15 | PATCH | Ensure successful and unsuccessful attempts to use the chcon command are recorded"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_15
tags:
- level2-server
- level2- workstation
- automated
- patch
- auditd
- rule_4.1.3.15
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.16 | PATCH | Ensure successful and unsuccessful attempts to use the setfacl command are recorded"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_16
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.16
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.17 | PATCH | Ensure successful and unsuccessful attempts to use the chacl command are recorded"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_17
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.17
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.18 | PATCH | Ensure successful and unsuccessful attempts to use the usermod command are recorded"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_18
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.18
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.19 | PATCH | Ensure kernel module loading and unloading is collected"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_19
tags:
- level2-server
- level2-workstation
- automated
- patch
- auditd
- rule_4.1.3.19
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.20 | PATCH | Ensure the audit configuration is immutable"
set_fact:
ansible.builtin.set_fact:
update_audit_template: true
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:
ansible.builtin.debug:
msg:
- "Please run augenrules --load if you suspect there is a configuration that is not active"
when:
@ -304,7 +285,7 @@
- rule_4.1.3.21
- name: Auditd | 4.1.3 | Auditd controls updated
debug:
ansible.builtin.debug:
msg: "Auditd Controls handled in POST using template - updating /etc/auditd/rules.d/99_auditd.rules"
changed_when: false
when:

View file

@ -0,0 +1,178 @@
---
- name: |
"4.1.4.1 | PATCH | Ensure audit log files are mode 0640 or less permissive"
"4.1.4.2 | PATCH | Ensure only authorized users own audit log files"
"4.1.4.3 | PATCH | Ensure only authorized groups are assigned ownership of audit log files"
block:
- name: "4.1.4.1 | AUDIT | Ensure audit log files are mode 0640 or less permissive | discover file"
ansible.builtin.shell: grep ^log_file /etc/audit/auditd.conf | awk '{ print $NF }'
register: audit_logfile
changed_when: false
- name: |
"4.1.4.1 | PATCH | Ensure audit log files are mode 0640 or less permissive"
"4.1.4.2 | PATCH | Ensure only authorized users own audit log files"
"4.1.4.3 | PATCH | Ensure only authorized groups are assigned ownership of audit log files"
ansible.builtin.file:
path: "{{ audit_logfile.stdout }}"
mode: 0640
owner: root
group: root
when:
- rhel9cis_rule_4_1_4_1 or
rhel9cis_rule_4_1_4_2 or
rhel9cis_rule_4_1_4_3
tags:
- level2-server
- level2-workstation
- patch
- auditd
- rule_4.1.4.1
- rule_4.1.4.2
- rule_4.1.4.3
- name: "4.1.4.4 | PATCH | Ensure the audit log directory is 0750 or more restrictive"
block:
- name: "4.1.4.4 | AUDIT | Ensure the audit log directory is 0750 or more restrictive | get current permissions"
ansible.builtin.stat:
path: "{{ audit_logfile.stdout | dirname }}"
register: auditlog_dir
- name: "4.1.4.4 | PATCH | Ensure the audit log directory is 0750 or more restrictive | set"
ansible.builtin.file:
path: "{{ audit_logfile.stdout | dirname }}"
state: directory
mode: 0750
when: not auditlog_dir.stat.mode is match('07(0|5)0')
when:
- rhel9cis_rule_4_1_4_4
tags:
- level2-server
- level2-workstation
- patch
- auditd
- rule_4.1.4.4
- name: "4.1.4.5 | PATCH | Ensure audit configuration files are 640 or more restrictive"
ansible.builtin.file:
path: "{{ item.path }}"
mode: 0640
loop: "{{ auditd_conf_files.files }}"
loop_control:
label: "{{ item.path }}"
when:
- item.mode != '06(0|4)0'
- rhel9cis_rule_4_1_4_5
tags:
- level2-server
- level2-workstation
- patch
- auditd
- rule_4.1.4.5
- name: "4.1.4.6 | PATCH | Ensure audit configuration files are owned by root"
ansible.builtin.file:
path: "{{ item.path }}"
owner: root
loop: "{{ auditd_conf_files.files }}"
loop_control:
label: "{{ item.path }}"
when:
- rhel9cis_rule_4_1_4_6
tags:
- level2-server
- level2-workstation
- patch
- auditd
- rule_4.1.4.6
- name: "4.1.4.7 | PATCH | Ensure audit configuration files belong to group root"
ansible.builtin.file:
path: "{{ item.path }}"
group: root
loop: "{{ auditd_conf_files.files }}"
loop_control:
label: "{{ item.path }}"
when:
- rhel9cis_rule_4_1_4_7
tags:
- level2-server
- level2-workstation
- patch
- auditd
- rule_4.1.4.7
- name: "4.1.4.8 | PATCH | Ensure audit tools are 755 or more restrictive"
block:
- name: "4.1.4.8 | AUDIT | Get audit binary file stat | get current mode"
ansible.builtin.stat:
path: "{{ item }}"
register: "audit_bins"
loop:
- /sbin/auditctl
- /sbin/aureport
- /sbin/ausearch
- /sbin/autrace
- /sbin/auditd
- /sbin/augenrules
- name: "4.1.4.8 | PATCH | Ensure audit tools are 755 or more restrictive | set if required"
ansible.builtin.file:
path: "{{ item.item }}"
mode: 0750
loop: "{{ audit_bins.results }}"
loop_control:
label: "{{ item.item }}"
when: not item.stat.mode is match('07(0|5)0')
when:
- rhel9cis_rule_4_1_4_8
tags:
- level2-server
- level2-workstation
- patch
- auditd
- rule_4.1.4.8
- name: "4.1.4.9 | PATCH | Ensure audit tools are owned by root"
ansible.builtin.file:
path: "{{ item }}"
owner: root
group: root
loop:
- /sbin/auditctl
- /sbin/aureport
- /sbin/ausearch
- /sbin/autrace
- /sbin/auditd
- /sbin/augenrules
when:
- rhel9cis_rule_4_1_4_9
tags:
- level2-server
- level2-workstation
- patch
- auditd
- rule_4.1.4.9
- name: "4.1.4.10 | PATCH | Ensure audit tools belong to group root"
ansible.builtin.file:
path: "{{ item }}"
group: root
loop:
- /sbin/auditctl
- /sbin/aureport
- /sbin/ausearch
- /sbin/autrace
- /sbin/auditd
- /sbin/augenrules
when:
- rhel9cis_rule_4_1_4_10
tags:
- level2-server
- level2-workstation
- patch
- auditd
- rule_4.1.4.10

View file

@ -1,7 +1,7 @@
---
- name: "4.2.1.1 | PATCH | Ensure rsyslog installed"
package:
ansible.builtin.package:
name: rsyslog
state: present
when:
@ -10,13 +10,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- rsyslog
- rule_4.2.1.1
- name: "4.2.1.2 | PATCH | Ensure rsyslog Service is enabled"
service:
ansible.builtin.systemd:
name: rsyslog
enabled: true
when:
@ -24,39 +23,36 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- rsyslog
- rule_4.2.1.2
# This is counter to control 4.2.2.5??
- name: "4.2.1.3 | PATCH | Ensure journald is configured to send logs to rsyslog"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/systemd/journald.conf
regexp: "^#ForwardToSyslog=|^ForwardToSyslog="
line: ForwardToSyslog=yes
notify: Restart rsyslog
when:
- rhel9cis_rule_4_2_1_3
- rhel9cis_preferred_log_capture == "rsyslog"
- rhel9cis_syslog == "rsyslog"
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:
ansible.builtin.lineinfile:
path: /etc/rsyslog.conf
regexp: '^\$FileCreateMode'
line: '$FileCreateMode 0640'
notify: restart rsyslog
notify: Restart rsyslog
when:
- rhel9cis_rule_4_2_1_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- rsyslog
- rule_4.2.1.4
@ -64,22 +60,21 @@
- name: "4.2.1.5 | PATCH | Ensure logging is configured"
block:
- name: "4.2.1.5 | AUDIT | Ensure logging is configured | rsyslog current config message out"
command: cat /etc/rsyslog.conf
ansible.builtin.shell: cat /etc/rsyslog.conf
changed_when: false
failed_when: false
check_mode: false
register: rhel_08_4_2_1_5_audit
register: rhel_09_4_2_1_5_audit
- name: "4.2.1.5 | AUDIT | Ensure logging is configured | rsyslog current config message out"
debug:
ansible.builtin.debug:
msg:
- "These are the current logging configurations for rsyslog, please review:"
- "{{ rhel_08_4_2_1_5_audit.stdout_lines }}"
- "{{ rhel_09_4_2_1_5_audit.stdout_lines }}"
- name: "4.2.1.5 | PATCH | Ensure logging is configured | mail.* log setting"
blockinfile:
ansible.builtin.blockinfile:
path: /etc/rsyslog.conf
state: present
marker: "# {mark} MAIL LOG SETTINGS (ANSIBLE MANAGED)"
block: |
# mail logging additions to meet CIS standards
@ -88,11 +83,11 @@
mail.warning -/var/log/mail.warning
mail.err /var/log/mail.err
insertafter: '# Log all the mail messages in one place.'
notify: restart rsyslog
notify: Restart rsyslog
when: rhel9cis_rsyslog_ansiblemanaged
- name: "4.2.1.5 | PATCH | Ensure logging is configured | news.crit log setting"
blockinfile:
ansible.builtin.blockinfile:
path: /etc/rsyslog.conf
state: present
marker: "# {mark} NEWS LOG SETTINGS (ANSIBLE MANAGED)"
@ -101,11 +96,11 @@
news.crit -/var/log/news/news.crit
news.notice -/var/log/news/news.crit
insertafter: '# Save news errors of level crit and higher in a special file.'
notify: restart rsyslog
notify: Restart rsyslog
when: rhel9cis_rsyslog_ansiblemanaged
- name: "4.2.1.5 | PATCH | Ensure logging is configured | Misc. log setting"
blockinfile:
ansible.builtin.blockinfile:
path: /etc/rsyslog.conf
state: present
marker: "# {mark} MISC. LOG SETTINGS (ANSIBLE MANAGED)"
@ -115,11 +110,11 @@
*.crit /var/log/warn
*.*;mail.none;news.none /var/log/messages
insertafter: '#### RULES ####'
notify: restart rsyslog
notify: Restart rsyslog
when: rhel9cis_rsyslog_ansiblemanaged
- name: "4.2.1.5 | PATCH | Ensure logging is configured | Local log settings"
blockinfile:
ansible.builtin.blockinfile:
path: /etc/rsyslog.conf
state: present
marker: "#{mark} LOCAL LOG SETTINGS (ANSIBLE MANAGED)"
@ -131,10 +126,10 @@
local6,local7.* -/var/log/localmessages
*.emrg :omusrmsg:*
insertafter: '#### RULES ####'
notify: restart rsyslog
notify: Restart rsyslog
- name: "4.2.1.5 | PATCH | Ensure logging is configured | Auth Settings"
blockinfile:
ansible.builtin.blockinfile:
path: /etc/rsyslog.conf
state: present
marker: "#{mark} Auth SETTINGS (ANSIBLE MANAGED)"
@ -142,10 +137,10 @@
# Private settings to meet CIS standards
auth,authpriv.* /var/log/secure
insertafter: '#### RULES ####'
notify: restart rsyslog
notify: Restart rsyslog
- name: "4.2.1.5 | PATCH | Ensure logging is configured | Cron Settings"
blockinfile:
ansible.builtin.blockinfile:
path: /etc/rsyslog.conf
state: present
marker: "#{mark} Cron SETTINGS (ANSIBLE MANAGED)"
@ -153,37 +148,35 @@
# Cron settings to meet CIS standards
cron.* /var/log/cron
insertafter: '#### RULES ####'
notify: restart rsyslog
notify: Restart rsyslog
when:
- rhel9cis_rule_4_2_1_5
tags:
- level1-server
- level1-workstation
- manual
- patch
- rsyslog
- rule_4.2.1.5
- name: "4.2.1.6 | PATCH | Ensure rsyslog is configured to send logs to a remote log host"
blockinfile:
ansible.builtin.blockinfile:
path: /etc/rsyslog.conf
state: present
block: |
# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional
*.* @@{{ rhel9cis_remote_log_server }}
# target can be IP or FQDN
*.* action(type="omfwd" target="{{ rhel9cis_remote_log_host }}" port="{{ rhel9cis_remote_log_port }}" protocol="{{ rhel9cis_remote_log_protocol }}" action.resumeRetryCount="{{ rhel9cis_remote_log_retrycount }}" queue.type="LinkedList" queue.size="{{ rhel9cis_remote_log_queuesize }}")
insertafter: EOF
register: result
failed_when:
- result is failed
- result.rc != 257
notify: restart rsyslog
notify: Restart rsyslog
when:
- rhel9cis_rule_4_2_1_6
- rhel9cis_remote_log_server is defined
- rhel9cis_remote_log_server
tags:
- level1-server
- level1-workstation
- manual
- patch
- rsyslog
- rule_4.2.1.6
@ -191,12 +184,12 @@
- name: "4.2.1.7 | PATCH | Ensure rsyslog is not configured to recieve logs from a remote client"
block:
- name: "4.2.1.7 | PATCH | Ensure rsyslog is not configured to recieve logs from a remote client. | When not log host"
replace:
ansible.builtin.replace:
path: /etc/rsyslog.conf
regexp: '({{ item }})'
regexp: '{{ item }}'
replace: '#\1'
notify: restart rsyslog
with_items:
notify: Restart rsyslog
loop:
- '^(\$ModLoad imtcp)'
- '^(\$InputTCPServerRun)'
- '^(module\(load="imtcp"\))'
@ -204,23 +197,20 @@
when: not rhel9cis_system_is_log_server
- name: "4.2.1.7 | PATCH | Ensure rsyslog is not configured to recieve logs from a remote clients. | When log host"
replace:
ansible.builtin.replace:
path: /etc/rsyslog.conf
regexp: '^#(.*{{ item }}.*)'
replace: '\1'
notify: restart rsyslog
with_items:
notify: Restart rsyslog
loop:
- 'ModLoad imtcp'
- 'InputTCPServerRun'
- 'module\(load="imtcp"\)'
- 'input\(type="imtcp"'
when: rhel9cis_system_is_log_server
when:
- rhel9cis_rule_4_2_1_7
tags:
- level1-server
- level1-workstation
- automated
- patch
- rsyslog
- rule_4.2.1.7

View file

@ -1,7 +1,7 @@
---
- name: "4.2.2.1.1 | PATCH | Ensure systemd-journal-remote is installed"
package:
ansible.builtin.package:
name: systemd-journal-remote
state: present
when:
@ -15,12 +15,12 @@
- rule_4.2.2.1.1
- name: "4.2.2.1.2 | PATCH | Ensure systemd-journal-remote is configured"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/systemd/journal-upload.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
notify: restart systemd_journal_upload
with_items:
notify: Restart systemd_journal_upload
loop:
- { regexp: 'URL=', line: 'URL={{ rhel9cis_journal_upload_url }}'}
- { regexp: 'ServerKeyFile=', line: 'ServerKeyFile={{ rhel9cis_journal_upload_serverkeyfile }}'}
- { regexp: 'ServerCertificateFile=', line: 'ServerCertificateFile={{ rhel9cis_journal_servercertificatefile }}'}
@ -36,7 +36,7 @@
- rule_4.2.2.1.2
- name: "4.2.2.1.3 | PATCH | Ensure systemd-journal-remote is enabled"
systemd:
ansible.builtin.systemd:
name: systemd-journal-upload
state: started
enabled: true
@ -52,7 +52,7 @@
- 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:
ansible.builtin.systemd:
name: systemd-journal-remote.socket
state: stopped
enabled: false
@ -63,7 +63,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- journald
- rule_4.2.2.1.4
@ -71,75 +70,74 @@
- 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:
ansible.builtin.systemd:
name: systemd-journald
state: started
enabled: true
- name: "4.2.2.2 | AUDIT | Ensure journald service is enabled | Capture status"
shell: systemctl is-enabled systemd-journald.service
ansible.builtin.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:
ansible.builtin.debug:
msg:
- "Warning!! 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"
- name: "4.2.2.2 | AUDIT | Ensure journald service is enabled | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_4.2.2.2' ]"
warn_count: "{{ warn_count | int + 1 }}"
ansible.builtin.import_tasks: warning_facts.yml
when: "'static' not in rhel9cis_4_2_2_2_status.stdout"
vars:
warn_control_id: '4.2.2.2'
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:
ansible.builtin.lineinfile:
path: /etc/systemd/journald.conf
regexp: "^#Compress=|^Compress="
line: Compress=yes
notify: Restart systemd_journal_upload
when:
- rhel9cis_rule_4_2_2_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- journald
- rule_4.2.2.3
- name: "4.2.2.4 | PATCH | Ensure journald is configured to write logfiles to persistent disk"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/systemd/journald.conf
regexp: "^#Storage=|^Storage="
line: Storage=persistent
notify: Restart systemd_journal_upload
when:
- rhel9cis_rule_4_2_2_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- 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:
ansible.builtin.lineinfile:
path: /etc/systemd/journald.conf
regexp: "^ForwardToSyslog="
line: "#ForwardToSyslog=yes"
notify: restart systemd_journal_upload
notify: Restart systemd_journal_upload
when:
- rhel9cis_rule_4_2_2_5
tags:
@ -151,12 +149,12 @@
- rule_4.2.2.5
- name: "4.2.2.6 | PATCH | Ensure journald log rotation is configured per site policy"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/systemd/journald.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
notify: restart journald
with_items:
notify: Restart systemd_journal_upload
loop:
- { regexp: '^#SystemMaxUse=|^SystemMaxUse=', line: 'SystemMaxUse={{ rhel9cis_journald_systemmaxuse }}'}
- { regexp: '^#SystemKeepFree=|^SystemKeepFree=', line: 'SystemKeepFree={{ rhel9cis_journald_systemkeepfree }}' }
- { regexp: '^#RuntimeMaxUse=|^RuntimeMaxUse=', line: 'RuntimeMaxUse={{ rhel9cis_journald_runtimemaxuse }}'}
@ -175,35 +173,21 @@
- 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
ansible.builtin.stat:
path: /etc/tmpfiles.d/systemd.conf
register: rhel9cis_4_2_2_7_override
- 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 | Set live file"
ansible.builtin.set_fact:
systemd_conf_file: /etc/tmpfiles.d/systemd.conf
when: rhel9cis_4_2_2_7_override.stat.exists
- 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 | PATCH | Ensure journald default file permissions configured | Set permission"
ansible.builtin.lineinfile:
path: "{{ systemd_conf_file | default('/usr/lib/tmpfiles.d/systemd.conf') }}"
regexp: "^z \/var\/log\/journal\/%m\/system.journal (!?06(0|4)0) root"
line: 'z /var/log/journal/%m/system.journal 0640 root systemd-journal - -'
- name: "4.2.2.7 | AUDIT | Ensure journald default file permissions configured | Display file settings"
debug:
msg:
- "Warning!! Below are the current default settings for journald, please confirm they align with your site policies"
- "{{ (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) }}"
- name: "4.2.2.7 | AUDIT | Ensure journald default file permissions configured | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_4.2.2.7' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- rhel9cis_rule_4_2_2_7
tags:

View file

@ -1,15 +1,30 @@
---
- 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
block:
- name: "4.2.3 | AUDIT | Ensure permissions on all logfiles are configured | find files"
ansible.builtin.find:
paths: "/var/log"
file_type: file
recurse: true
register: logfiles
- name: "4.2.3 | PATCH | Ensure permissions on all logfiles are configured | change permissions"
ansible.builtin.file:
path: "{{ item.path }}"
mode: 0640
loop: "{{ logfiles.files }}"
loop_control:
label: "{{ item.path }}"
when:
- item.path != "/var/log/btmp"
- item.path != "/var/log/utmp"
- item.path != "/var/log/wtmp"
when:
- rhel9cis_rule_4_2_3
tags:
- level1-server
- level1-workstation
- automated
- patch
- logfiles
- rule_4.2.3

View file

@ -1,57 +1,55 @@
---
- name: "4.3.1 | PATCH | Ensure logrotate is installed"
package:
name: rsyslog-logrotate
state: present
when:
- rhel9cis_rule_4_3_1
tags:
- level1-server
- level1-workstation
- manual
- patch
- logrotate
- rule_4.3.1
- name: "4.3.2 | PATCH | Ensure logrotate is running and enabled"
systemd:
name: logrotate.timer
state: started
enabled: true
when:
- rhel9cis_rule_4_3_2
tags:
- level1-server
- level1-workstation
- manual
- patch
- logrotate
- rule_4.3.2
- name: "4.3.3 | PATCH | Ensure logrotate is configured"
- name: "4.3 | PATCH | Ensure logrotate is configured"
block:
- name: "4.3.3 | AUDIT | Ensure logrotate is configured | Get logrotate settings"
find:
paths: /etc/logrotate.d/
register: log_rotates
- name: "4.3 | PATCH | Ensure logrotate is configured | installed"
ansible.builtin.package:
name: rsyslog-logrotate
state: present
- name: "4.3.3 | PATCH | Ensure logrotate is configured"
replace:
path: "{{ item.path }}"
- name: "4.3 | PATCH | Ensure logrotate is configured | scheduled"
ansible.builtin.systemd:
name: logrotate.timer
state: started
enabled: true
- name: "4.3 | PATCH | Ensure logrotate is configured | set default conf"
ansible.builtin.replace:
path: "/etc/logrotate.conf"
regexp: '^(\s*)(daily|weekly|monthly|yearly)$'
replace: "\\1{{ rhel9cis_logrotate }}"
with_items:
- "{{ log_rotates.files }}"
- { path: "/etc/logrotate.conf" }
loop_control:
label: "{{ item.path }}"
- name: "4.3 | AUDIT | Ensure logrotate is configured | Get non default logrotate settings"
ansible.builtin.find:
paths: /etc/logrotate.d/
contains: '^(\s*)(?!{{ rhel9cis_logrotate }})(daily|weekly|monthly|yearly)$'
register: log_rotates
- name: "4.3 | AUDIT | Ensure logrotate is configured"
block:
- name: "4.3 | AUDIT | Ensure logrotate is configured | generate file list"
ansible.builtin.set_fact:
logrotate_non_def_conf: "{{ log_rotates.files | map(attribute='path') | join (', ') }}"
- name: "4.3 | AUDIT | Ensure logrotate is configured | List configured files"
ansible.builtin.debug:
msg: |
"Warning!! The following files are not covered by default logrotate settings ensure they match site policy"
"{{ logrotate_non_def_conf }}"
loop: "{{ log_rotates.files }}"
- name: "4.3 | AUDIT | Ensure logrotate is configured | Warning count"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '4.3'
when: log_rotates.matched > 0
when:
- rhel9cis_rule_4_3_3
- rhel9cis_rule_4_3
tags:
- level1-server
- level1-workstation
- manual
- patch
- logrotate
- rule_4.3.3
- rule_4.3

View file

@ -1,26 +1,29 @@
---
- name: "SECTION | 4.1 | Configure System Accounting (auditd)"
include_tasks: cis_4.1.1.x.yml
ansible.builtin.import_tasks: cis_4.1.1.x.yml
when:
- not system_is_container
- name: "SECTION | 4.1.2 | Configure Data Retention"
import_tasks: cis_4.1.2.x.yml
ansible.builtin.import_tasks: cis_4.1.2.x.yml
- name: "SECTION | 4.1.3 | Configure Auditd rules"
import_tasks: cis_4.1.3.x.yml
ansible.builtin.import_tasks: cis_4.1.3.x.yml
- name: "SECTION | 4.1.4 | Configure Audit files"
ansible.builtin.import_tasks: cis_4.1.4.x.yml
- name: "SECTION | 4.2 | Configure Logging"
import_tasks: cis_4.2.1.x.yml
ansible.builtin.import_tasks: cis_4.2.1.x.yml
when: rhel9cis_syslog == 'rsyslog'
- name: "SECTION | 4.2.2 | Configure journald"
import_tasks: cis_4.2.2.x.yml
ansible.builtin.import_tasks: cis_4.2.2.x.yml
when: rhel9cis_syslog == 'journald'
- name: "SECTION | 4.2.3 | Configure logile perms"
import_tasks: cis_4.2.3.yml
ansible.builtin.import_tasks: cis_4.2.3.yml
- name: "SECTION | 4.3 | Configure logrotate"
import_tasks: cis_4.3.yml
ansible.builtin.import_tasks: cis_4.3.yml

View file

@ -1,7 +1,7 @@
---
- name: "5.1.1 | PATCH | Ensure cron daemon is enabled"
service:
ansible.builtin.service:
name: crond
enabled: true
when:
@ -9,14 +9,13 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.1
- name: "5.1.2 | PATCH | Ensure permissions on /etc/crontab are configured"
file:
dest: /etc/crontab
ansible.builtin.file:
path: /etc/crontab
owner: root
group: root
mode: 0600
@ -25,14 +24,13 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.2
- name: "5.1.3 | PATCH | Ensure permissions on /etc/cron.hourly are configured"
file:
dest: /etc/cron.hourly
ansible.builtin.file:
path: /etc/cron.hourly
state: directory
owner: root
group: root
@ -42,14 +40,13 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.3
- name: "5.1.4 | PATCH | Ensure permissions on /etc/cron.daily are configured"
file:
dest: /etc/cron.daily
ansible.builtin.file:
path: /etc/cron.daily
state: directory
owner: root
group: root
@ -59,14 +56,13 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.4
- name: "5.1.5 | PATCH | Ensure permissions on /etc/cron.weekly are configured"
file:
dest: /etc/cron.weekly
ansible.builtin.file:
path: /etc/cron.weekly
state: directory
owner: root
group: root
@ -80,8 +76,8 @@
- rule_5.1.5
- name: "5.1.6 | PATCH | Ensure permissions on /etc/cron.monthly are configured"
file:
dest: /etc/cron.monthly
ansible.builtin.file:
path: /etc/cron.monthly
state: directory
owner: root
group: root
@ -91,13 +87,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- rule_5.1.6
- name: "5.1.7 | PATCH | Ensure permissions on /etc/cron.d are configured"
file:
dest: /etc/cron.d
ansible.builtin.file:
path: /etc/cron.d
state: directory
owner: root
group: root
@ -107,7 +102,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.7
@ -115,18 +109,18 @@
- name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users"
block:
- name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users | Remove cron.deny"
file:
dest: /etc/cron.deny
ansible.builtin.file:
path: /etc/cron.deny
state: absent
- name: "5.1.8 | PATCH | Ensure cron is restricted to authorized users | Check if cron.allow exists"
stat:
ansible.builtin.stat:
path: "/etc/cron.allow"
register: rhel9cis_5_1_8_cron_allow_state
- 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
ansible.builtin.file:
path: /etc/cron.allow
state: '{{ "file" if rhel9cis_5_1_8_cron_allow_state.stat.exists else "touch" }}'
owner: root
group: root
@ -136,7 +130,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.8
@ -144,18 +137,18 @@
- 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
ansible.builtin.file:
path: /etc/at.deny
state: absent
- name: "5.1.9 | PATCH | Ensure at is restricted to authorized users | Check if at.allow exists"
stat:
ansible.builtin.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
ansible.builtin.file:
path: /etc/at.allow
state: '{{ "file" if rhel9cis_5_1_9_at_allow_state.stat.exists else "touch" }}'
owner: root
group: root
@ -165,7 +158,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- cron
- rule_5.1.9

View file

@ -1,9 +1,8 @@
---
- name: "5.2.1 | Ensure permissions on /etc/ssh/sshd_config are configured"
file:
dest: /etc/ssh/sshd_config
state: file
ansible.builtin.file:
path: /etc/ssh/sshd_config
owner: root
group: root
mode: 0600
@ -12,7 +11,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- permissions
@ -21,7 +19,7 @@
- name: "5.2.2 | PATCH | Ensure permissions on SSH private host key files are configured"
block:
- name: "5.2.2 | AUDIT | Ensure permissions on SSH private host key files are configured | Find the SSH private host keys"
find:
ansible.builtin.find:
paths: /etc/ssh
patterns: 'ssh_host_*_key'
recurse: true
@ -29,13 +27,12 @@
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:
ansible.builtin.file:
path: "{{ item.path }}"
owner: root
group: root
mode: 0600
with_items:
- "{{ rhel9cis_5_2_2_ssh_private_host_key.files }}"
loop: "{{ rhel9cis_5_2_2_ssh_private_host_key.files }}"
loop_control:
label: "{{ item.path }}"
when:
@ -43,7 +40,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- permissions
@ -52,7 +48,7 @@
- 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:
ansible.builtin.find:
paths: /etc/ssh
patterns: 'ssh_host_*_key.pub'
recurse: true
@ -60,13 +56,12 @@
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:
ansible.builtin.file:
path: "{{ item.path }}"
owner: root
group: root
mode: 0644
with_items:
- "{{ rhel9cis_5_2_3_ssh_public_host_key.files }}"
loop: "{{ rhel9cis_5_2_3_ssh_public_host_key.files }}"
loop_control:
label: "{{ item.path }}"
when:
@ -74,7 +69,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.3
@ -82,52 +76,51 @@
- 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:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^AllowUsers"
line: AllowUsers {{ rhel9cis_sshd['allowusers'] }}
line: "AllowUsers {{ rhel9cis_sshd['allowusers'] }}"
validate: sshd -t -f %s
notify: restart sshd
notify: Restart sshd
when: "rhel9cis_sshd['allowusers']|default('') | length > 0"
- name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowgroups"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^AllowGroups"
line: AllowGroups {{ rhel9cis_sshd['allowgroups'] }}
line: "AllowGroups {{ rhel9cis_sshd['allowgroups'] }}"
validate: sshd -t -f %s
notify: restart sshd
notify: Restart sshd
when: "rhel9cis_sshd['allowgroups']|default('') | length > 0"
- name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denyusers"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^DenyUsers"
line: DenyUsers {{ rhel9cis_sshd['denyusers'] }}
line: "DenyUsers {{ rhel9cis_sshd['denyusers'] }}"
validate: sshd -t -f %s
notify: restart sshd
notify: Restart sshd
when: "rhel9cis_sshd['denyusers']|default('') | length > 0"
- name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denygroups"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^DenyGroups"
line: DenyGroups {{ rhel9cis_sshd['denygroups'] }}
line: "DenyGroups {{ rhel9cis_sshd['denygroups'] }}"
validate: sshd -t -f %s
notify: restart sshd
notify: Restart sshd
when: "rhel9cis_sshd['denygroups']|default('') | length > 0"
when:
- rhel9cis_rule_5_2_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.4
- name: "5.2.5 | PATCH | Ensure SSH LogLevel is appropriate"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#LogLevel|^LogLevel"
line: 'LogLevel {{ rhel9cis_ssh_loglevel }}'
@ -137,13 +130,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- sshs
- rule_5.2.5
- name: "5.2.6 | PATCH | Ensure SSH PAM is enabled"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#UsePAM|^UsePAM"
line: 'UsePAM yes'
@ -153,13 +145,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.6
- name: "5.2.7 | PATCH | Ensure SSH root login is disabled"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#PermitRootLogin|^PermitRootLogin"
line: 'PermitRootLogin no'
@ -169,13 +160,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.7
- name: "5.2.8 | PATCH | Ensure SSH HostbasedAuthentication is disabled"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#HostbasedAuthentication|^HostbasedAuthentication"
line: 'HostbasedAuthentication no'
@ -185,13 +175,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.8
- name: "5.2.9 | PATCH | Ensure SSH PermitEmptyPasswords is disabled"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#PermitEmptyPasswords|^PermitEmptyPasswords"
line: 'PermitEmptyPasswords no'
@ -201,13 +190,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.9
- name: "5.2.10 | PATCH | Ensure SSH PermitUserEnvironment is disabled"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#PermitUserEnvironment|^PermitUserEnvironment"
line: 'PermitUserEnvironment no'
@ -217,13 +205,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.10
- name: "5.2.11 | PATCH | Ensure SSH IgnoreRhosts is enabled"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#IgnoreRhosts|^IgnoreRhosts"
line: 'IgnoreRhosts yes'
@ -233,13 +220,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.11
- name: "5.2.12 | PATCH | Ensure SSH X11 forwarding is disabled"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#X11Forwarding|^X11Forwarding"
line: 'X11Forwarding no'
@ -249,13 +235,12 @@
tags:
- level2-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.12
- name: "5.2.13 | PATCH | Ensure SSH AllowTcpForwarding is disabled"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#AllowTcpForwarding|^AllowTcpForwarding"
line: 'AllowTcpForwarding no'
@ -265,7 +250,6 @@
tags:
- level2-server
- level2-workstation
- automated
- patch
- ssh
- rule_5.2.13
@ -273,31 +257,26 @@
- name: "5.2.14 | PATCH | Ensure system-wide crypto policy is not over-ridden"
block:
- name: "5.2.14 | AUDIT | Ensure system-wide crypto policy is not over-ridden"
shell: grep -i '^\s*CRYPTO_POLICY=' /etc/sysconfig/sshd
args:
warn: false
ansible.builtin.shell: grep -i '^\s*CRYPTO_POLICY=' /etc/sysconfig/sshd
changed_when: false
failed_when: ( ssh_crypto_discovery.rc not in [ 0, 1 ] )
register: ssh_crypto_discovery
- 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: false
notify: restart sshd
ansible.builtin.shell: sed -ri "s/^\s*(CRYPTO_POLICY\s*=.*)$/# \1/" /etc/sysconfig/sshd
notify: Restart sshd
when: ssh_crypto_discovery.stdout | length > 0
when:
- rhel9cis_rule_5_2_14
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.14
- name: "5.2.15 | PATCH | Ensure SSH warning banner is configured"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^Banner'
line: 'Banner /etc/issue.net'
@ -306,13 +285,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.15
- name: "5.2.16 | PATCH | Ensure SSH MaxAuthTries is set to 4 or less"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^(#)?MaxAuthTries \d'
line: 'MaxAuthTries 4'
@ -322,13 +300,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.16
- name: "5.2.17 | PATCH | Ensure SSH MaxStartups is configured"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#MaxStartups|^MaxStartups"
line: 'MaxStartups 10:30:60'
@ -338,13 +315,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.17
- name: "5.2.18 | PATCH | Ensure SSH MaxSessions is set to 10 or less"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#MaxSessions|^MaxSessions"
line: 'MaxSessions {{ rhel9cis_ssh_maxsessions }}'
@ -354,13 +330,12 @@
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:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#LoginGraceTime|^LoginGraceTime"
line: "LoginGraceTime {{ rhel9cis_sshd['logingracetime'] }}"
@ -370,7 +345,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.19
@ -378,14 +352,14 @@
- 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:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^ClientAliveInterval'
line: "ClientAliveInterval {{ rhel9cis_sshd['clientaliveinterval'] }}"
validate: sshd -t -f %s
- name: "5.2.20 | PATCH | Ensure SSH Idle Timeout Interval is configured | Ensure SSH ClientAliveCountMax set to <= 3"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^ClientAliveCountMax'
line: "ClientAliveCountMax {{ rhel9cis_sshd['clientalivecountmax'] }}"
@ -395,7 +369,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- ssh
- rule_5.2.20

View file

@ -1,7 +1,7 @@
---
- name: "5.3.1 | PATCH | Ensure sudo is installed"
package:
ansible.builtin.package:
name: sudo
state: present
when:
@ -9,13 +9,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- sudo
- rule_5.3.1
- name: "5.3.2 | PATCH | Ensure sudo commands use pty"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/sudoers
line: "Defaults use_pty"
validate: '/usr/sbin/visudo -cf %s'
@ -24,13 +23,12 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- sudo
- rule_5.3.2
- name: "5.3.3 | PATCH | Ensure sudo log file exists"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/sudoers
regexp: '^Defaults logfile='
line: 'Defaults logfile="{{ rhel9cis_sudolog_location }}"'
@ -40,43 +38,38 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- sudo
- rule_5.3.3
- name: "5.3.4 | PATCH | Ensure users must provide password for escalation"
replace:
ansible.builtin.replace:
path: "{{ item }}"
regexp: '^([^#|{% if system_is_ec2 %}ec2-user{% endif %}].*)NOPASSWD(.*)'
replace: '\1PASSWD\2'
validate: '/usr/sbin/visudo -cf %s'
with_items:
- "{{ rhel9cis_sudoers_files.stdout_lines }}"
loop: "{{ 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:
ansible.builtin.replace:
path: "{{ item }}"
regexp: '^([^#].*)!authenticate(.*)'
replace: '\1authenticate\2'
validate: '/usr/sbin/visudo -cf %s'
with_items:
- "{{ rhel9cis_sudoers_files.stdout_lines }}"
loop: "{{ rhel9cis_sudoers_files.stdout_lines }}"
when:
- rhel9cis_rule_5_3_5
tags:
- level1-server
- level1-workstation
- automated
- patch
- sudo
- rule_5.3.5
@ -84,13 +77,13 @@
- 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
ansible.builtin.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:
ansible.builtin.lineinfile:
path: /etc/sudoers
regexp: 'Defaults timestamp_timeout='
line: "Defaults timestamp_timeout={{ rhel9cis_sudo_timestamp_timeout }}"
@ -98,20 +91,18 @@
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:
ansible.builtin.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 }}"
loop: "{{ 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
@ -119,21 +110,21 @@
- 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:
ansible.builtin.lineinfile:
path: /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 }}"
ansible.builtin.user:
name: "{{ item }}"
groups: "{{ rhel9cis_sugroup | default('wheel') }}"
loop: "{{ rhel9cis_sugroup_users }}"
when:
- rhel9cis_rule_5_3_7
tags:
- level1-server
- level1-workstation
- automated
- patch
- sudo
- rule_5.3.7

View file

@ -3,22 +3,20 @@
- name: "5.4.1 | PATCH | Ensure custom authselect profile is used"
block:
- name: "5.4.1 | AUDIT | Ensure custom authselect profile is used | Gather profiles"
shell: 'authselect current | grep "Profile ID: custom/"'
ansible.builtin.shell: 'authselect current | grep "Profile ID: custom/"'
failed_when: false
changed_when: false
check_mode: false
register: rhel9cis_5_4_1_profiles
- name: "5.4.1 | AUDIT | Ensure custom authselect profile is used | Show profiles"
debug:
ansible.builtin.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: false
ansible.builtin.shell: authselect create-profile {{ rhel9cis_authselect['custom_profile_name'] }} -b {{ rhel9cis_authselect['default_file_to_copy'] }}
when: rhel9cis_authselect_custom_profile_create
when:
- rhel9cis_rule_5_4_1
@ -30,32 +28,58 @@
- authselect
- rule_5.4.1
- name: "5.4.2 | PATCH | Ensure authselect includes with-faillock"
- name: "5.4.2 | PATCH | Ensure authselect includes with-faillock | with auth select profile"
block:
- name: "5.4.2 | AUDIT | Ensure authselect includes with-faillock | Gather profiles and enabled features"
shell: "authselect current | grep with-faillock"
ansible.builtin.shell: "authselect current | grep with-faillock"
failed_when: false
changed_when: false
check_mode: false
register: rhel9cis_5_4_2_profiles_faillock
- name: "5.4.2 | AUDIT | Ensure authselect includes with-faillock| Show profiles"
debug:
- name: "5.4.2 | AUDIT | Ensure authselect includes with-faillock | Show profiles"
ansible.builtin.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: false
ansible.builtin.shell: "authselect select custom/{{ rhel9cis_authselect['custom_profile_name'] }} with-faillock"
when: rhel9cis_authselect_custom_profile_select
- name: 5.4.2 | PATCH | Ensure authselect includes with-faillock | not auth select profile"
ansible.builtin.lineinfile:
path: "/etc/pam.d/password-auth"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
insertbefore: "{{ item.before }}"
loop:
- { 'regexp': '^auth\s+required\s+pam_faillock.so preauth silent deny=.*unlock_time=.*', 'line': 'auth required pam_faillock.so preauth silent deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time }}', 'before':'^auth\s+sufficient\s+pam_unix.so try_first_pass'}
- { 'regexp': '^auth\s+required\s+pam_faillock.so authfail deny=.*unlock_time=.*', 'line': 'auth required pam_faillock.so authfail deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time }}', 'before':'^auth\s+required\s+pam_deny.so'}
- { 'regexp': '^account\s+required\s+pam_faillock.so', 'line': 'account required pam_faillock.so', 'before':'^account required pam_unix.so'}
when:
- rhel9cis_add_faillock_without_authselect
- rhel9cis_5_4_2_risks == 'ACCEPT'
- name: 5.4.2 | PATCH | Ensure authselect includes with-faillock | not auth select profile"
ansible.builtin.lineinfile:
path: "/etc/pam.d/system-auth"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
insertbefore: "{{ item.before | default(omit)}}"
insertafter: "{{ item.after | default(omit)}}"
loop:
- { 'regexp': '^auth\s+required\s+pam_faillock.so preauth silent deny=.*unlock_time=.*', 'line':'auth required pam_faillock.so preauth silent deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time }}', 'before':'^auth\s+sufficient\s+pam_unix.so try_first_pass'}
- { 'regexp': '^auth\s+required\s+pam_faillock.so authfail deny=.*unlock_time=.*', 'line': 'auth required pam_faillock.so authfail deny={{ rhel9cis_pam_faillock.deny }} unlock_time={{ rhel9cis_pam_faillock.unlock_time }}', 'before':'^auth\s+required\s+pam_deny.so'}
- { 'regexp': '^account\s+required\s+pam_faillock.so', 'line': 'account required pam_faillock.so', 'before':'^account required pam_unix.so'}
when:
- rhel9cis_add_faillock_without_authselect
- rhel9cis_5_4_2_risks == 'ACCEPT'
when:
- rhel9cis_rule_5_4_2
tags:
- level1-server
- level1-workstation
- automated
- patch
- authselect
- rule_5.4.2

View file

@ -1,25 +1,25 @@
---
- name: "5.5.1 | PATCH | "
- name: "5.5.1 | PATCH | Ensure password creation requirements are configured"
block:
- name: "5.5.1 | PATCH | Ensure password creation requirements are configured | Set pwquality config settings"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/security/pwquality.conf
regexp: ^{{ item.name }}
line: "{{ item.name }} = {{ item.value }}"
with_items:
loop:
- { name: minlen, value: "{{ rhel9cis_pam_password.minlen }}" }
- { name: minclass, value: "{{ rhel9cis_pam_password.minclass }}" }
- name: "5.5.1 | PATCH | Ensure password creation requirements are configured | Set system-auth retry settings"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
regexp: '^password\s*requisite\s*pam_pwquality.so'
line: "password requisite pam_pwquality.so try_first_pass local_users_only enforce_for_root retry=3"
insertbefore: '^#?password ?'
- name: "5.5.1 | PATCH | Ensure password creation requirements are configured | Set system-auth retry settings"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/pam.d/password-auth
regexp: '^password\s*requisite\s*pam_pwquality.so'
line: "password requisite pam_pwquality.so try_first_pass local_users_only enforce_for_root retry=3"
@ -32,12 +32,12 @@
- patch
- rule_5.5.1
- name: "5.5.2 | PATCH | Ensure system accounts are secured"
lineinfile:
- name: "5.5.2 | PATCH | Ensure lockout for failed password attempts is configured"
ansible.builtin.lineinfile:
path: /etc/security/faillock.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
with_items:
loop:
- { regexp: '^\s*deny\s*=\s*[1-5]\b', line: 'deny = 5' }
- { regexp: '^\s*unlock_time\s*=\s*(0|9[0-9][0-9]|[1-9][0-9][0-9][0-9]+)\b', line: 'unlock_time = 900' }
when:
@ -45,17 +45,17 @@
- name: "5.5.3 | PATCH | Ensure password reuse is limited"
block:
- name: "5.5.3 | PATCH | Ensure password reuse is limited | pwhistory"
lineinfile:
- name: "5.5.3 | PATCH | Ensure password reuse is limited | pwquality"
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
line: "password requisite pam_pwhistory.so try_first_pass local_users_only enforce_for_root retry=3 remember={{ rhel9cis_pam_faillock.remember }}"
insertafter: '^password\s*requisite\s*pam_pwquality.so'
- name: "5.5.3 | PATCH | Ensure password reuse is limited | pam_unix"
replace:
ansible.builtin.replace:
path: /etc/pam.d/system-auth
regexp: '^password\s*sufficient\s*pam_unix.so.*$'
replace: 'password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok remember={{ rhel9cis_pam_faillock.remember }}'
regexp: '^password\s*(sufficient|requisite|sufficient)\s*pam_unix.so.*$'
replace: 'password requisite pam_unix.so sha512 shadow try_first_pass use_authtok remember={{ rhel9cis_pam_faillock.remember }}'
when:
- rhel9cis_rule_5_5_3
tags:
@ -64,31 +64,31 @@
- patch
- rule_5.5.3
- name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512"
- name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 or yescrypt"
block:
- name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | libuser.conf"
replace:
ansible.builtin.replace:
path: /etc/libuser.conf
regexp: '^crypt_style\s*=\s*.*$'
replace: 'crypt_style = sha512'
- name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | login.defs"
replace:
ansible.builtin.replace:
path: /etc/login.defs
regexp: '^ENCRYPT_METHOD.*'
replace: 'ENCRYPT_METHOD SHA512'
- name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | password-auth"
replace:
ansible.builtin.replace:
path: /etc/pam.d/password-auth
regexp: '^password\s*sufficient\s*pam_unix.so.*$'
replace: 'password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok remember={{ rhel9cis_pam_faillock.remember }}'
- name: "5.5.4 | PATCH | Ensure password hashing algorithm is SHA-512 | system-auth"
replace:
ansible.builtin.replace:
path: /etc/pam.d/system-auth
regexp: '^password\s*sufficient\s*pam_unix.so.*$'
replace: 'password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok remember={{ rhel9cis_pam_faillock.remember }}'
replace: 'password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok remember={{ rhel9cis_pam_faillock.remember }}'
when:
- rhel9cis_rule_5_5_4
tags:

View file

@ -1,7 +1,7 @@
---
- name: "5.6.1.1 | PATCH | Ensure password expiration is 365 days or less"
lineinfile:
ansible.builtin.lineinfile:
path: /etc/login.defs
regexp: '^PASS_MAX_DAYS'
line: "PASS_MAX_DAYS {{ rhel9cis_pass['max_days'] }}"
@ -10,13 +10,12 @@
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:
ansible.builtin.lineinfile:
path: /etc/login.defs
regexp: '^PASS_MIN_DAYS'
line: "PASS_MIN_DAYS {{ rhel9cis_pass['min_days'] }}"
@ -25,13 +24,12 @@
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:
ansible.builtin.lineinfile:
path: /etc/login.defs
regexp: '^PASS_WARN_AGE'
line: "PASS_WARN_AGE {{ rhel9cis_pass['warn_age'] }}"
@ -40,7 +38,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- password
- rule_5.5.1.3
@ -48,32 +45,30 @@
- 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=
ansible.builtin.shell: useradd -D | grep INACTIVE={{ rhel9cis_inactivelock.lock_days }} | cut -f2 -d=
changed_when: false
failed_when: false
check_mode: false
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 }}
ansible.builtin.shell: 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: "awk -F: '/^[^#:]+:[^\\!\\*:]*:[^:]*:[^:]*:[^:]*:[^:]*:(\\s*|-1|3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):[^:]*:[^:]*\\s*$/ {print $1}' /etc/shadow"
ansible.builtin.shell: "awk -F: '/^[^#:]+:[^\\!\\*:]*:[^:]*:[^:]*:[^:]*:[^:]*:(\\s*|-1|3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):[^:]*:[^:]*\\s*$/ {print $1}' /etc/shadow"
changed_when: false
check_mode: false
register: rhel_8_5_6_1_4_user_list
register: rhel9cis_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 }}"
ansible.builtin.shell: chage --inactive {{ rhel9cis_inactivelock.lock_days }} "{{ item }}"
loop: "{{ rhel9cis_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
@ -81,46 +76,40 @@
- 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))
ansible.builtin.shell: echo $(($(date --utc --date "$1" +%s)/86400))
changed_when: false
failed_when: false
check_mode: false
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}'"
ansible.builtin.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: false
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:
ansible.builtin.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 | AUDIT | Ensure all users last password change date is in the past | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_5.6.1.5' ]"
warn_count: "{{ warn_count | int + 1 }}"
ansible.builtin.import_tasks: warning_facts.yml
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 }}
ansible.builtin.shell: passwd --expire {{ item }}
when:
- rhel9cis_5_6_1_5_user_list.stdout | length > 0
- rhel9cis_futurepwchgdate_autofix
with_items:
- "{{ rhel9cis_5_6_1_5_user_list.stdout_lines }}"
loop: "{{ rhel9cis_5_6_1_5_user_list.stdout_lines }}"
vars:
warn_control_id: '5.6.1.5'
when:
- rhel9cis_rule_5_6_1_5
tags:

View file

@ -3,11 +3,10 @@
- name: "5.6.2 | PATCH | Ensure system accounts are secured"
block:
- name: "5.6.2 | Ensure system accounts are secured | Set nologin"
user:
ansible.builtin.user:
name: "{{ item.id }}"
shell: /usr/sbin/nologin
with_items:
- "{{ rhel9cis_passwd }}"
loop: "{{ rhel9cis_passwd }}"
when:
- item.id != "root"
- item.id != "sync"
@ -21,11 +20,10 @@
label: "{{ item.id }}"
- name: "5.6.2 | PATCH | Ensure system accounts are secured | Lock accounts"
user:
ansible.builtin.user:
name: "{{ item.id }}"
password_lock: true
with_items:
- "{{ rhel9cis_passwd }}"
loop: "{{ rhel9cis_passwd }}"
when:
- item.id != "halt"
- item.id != "shutdown"
@ -42,37 +40,35 @@
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: true
mode: 0644
dest: "{{ item.dest }}"
ansible.builtin.blockinfile:
path: "{{ item.path }}"
state: "{{ item.state }}"
marker: "# {mark} CIS 5.6.3 ANSIBLE MANAGED"
create: true
mode: 0644
block: |
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') }}" }
loop:
- { path: "{{ rhel9cis_shell_session_timeout.file }}", state: present }
- { path: /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"
user:
ansible.builtin.user:
name: root
group: 0
when:
@ -80,7 +76,6 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- accounts
- rule_5.6.4
@ -88,7 +83,7 @@
- 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/login.defs pam_umask settings"
replace:
ansible.builtin.replace:
path: /etc/login.defs
regexp: "{{ item.regexp }}"
replace: "{{ item.replace }}"
@ -97,13 +92,13 @@
- { regexp: '(USERGROUPS_ENAB\s+)yes', replace: '\1 no' }
- name: "5.6.5 | PATCH | Ensure default user umask is 027 or more restrictive | Set umask for /etc/bashrc"
replace:
ansible.builtin.replace:
path: /etc/bashrc
regexp: '^(?i)(\s+UMASK|UMASK)\s0[0-2][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:
ansible.builtin.replace:
path: /etc/profile
regexp: '^(?i)(\s+UMASK|UMASK)\s0[0-2][0-6]'
replace: '\1 027'
@ -112,7 +107,19 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- accounts
- rule_5.6.5
- name: "5.6.6 | PATCH | Ensure root password is set"
ansible.builtin.debug:
msg: "The root password has been set as per the assert in early stages"
when:
- rhel9cis_rule_5_6_6
tags:
- level1-server
- level1-workstation
- patch
- accounts
- root
- rule_5.6.6

View file

@ -3,24 +3,24 @@
# Access, Authentication, and Authorization
- name: "SECTION | 5.1 | Configure time-based job schedulers"
import_tasks: cis_5.1.x.yml
ansible.builtin.import_tasks: cis_5.1.x.yml
- name: "SECTION | 5.2 | Configure SSH Server"
include_tasks: cis_5.2.x.yml
ansible.builtin.import_tasks: cis_5.2.x.yml
when:
- "'openssh-server' in ansible_facts.packages"
- name: "SECTION | 5.3 | Configure privilege escalation"
include_tasks: cis_5.3.x.yml
ansible.builtin.import_tasks: cis_5.3.x.yml
- name: "SECTION | 5.4 | Configure authselect"
import_tasks: cis_5.4.x.yml
ansible.builtin.import_tasks: cis_5.4.x.yml
- name: "SECTION | 5.5 | Configure PAM "
import_tasks: cis_5.5.x.yml
ansible.builtin.import_tasks: cis_5.5.x.yml
- name: "SECTION | 5.6.1.x | Shadow Password Suite Parameters"
import_tasks: cis_5.6.1.x.yml
ansible.builtin.import_tasks: cis_5.6.1.x.yml
- name: "SECTION | 5.6.x | Misc. User Account Settings"
import_tasks: cis_5.6.x.yml
ansible.builtin.import_tasks: cis_5.6.x.yml

View file

@ -1,72 +1,38 @@
---
- name: "6.1.1 | AUDIT | Audit system file permissions"
block:
- name: "6.1.1 | AUDIT | Audit system file permissions | Audit the packages"
shell: rpm -Va --nomtime --nosize --nomd5 --nolinkto
args:
warn: false
changed_when: false
failed_when: false
register: rhel9cis_6_1_1_packages_rpm
- name: "6.1.1 | AUDIT | Audit system file permissions | Create list and warning"
block:
- name: "6.1.1 | AUDIT | Audit system file permissions | Add file discrepancy list to system"
copy:
dest: "{{ rhel9cis_rpm_audit_file }}" # noqa template-instead-of-copy
content: "{{ rhel9cis_6_1_1_packages_rpm.stdout }}"
owner: root
group: root
mode: 0640
- 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 }}"
- name: "6.1.1 | AUDIT | Audit system file permissions | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.1.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_1_1_packages_rpm.stdout|length > 0
- 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
- name: "6.1.1 | PATCH | Ensure permissions on /etc/passwd are configured"
ansible.builtin.file:
path: /etc/passwd
owner: root
group: root
mode: 0644
when:
- rhel9cis_rule_6_1_1
tags:
- level2-server
- level2-workstation
- manual
- audit
- level1-server
- level1-workstation
- patch
- permissions
- rule_6.1.1
- 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: false
changed_when: false
failed_when: false
- name: "6.1.2 | PATCH | Ensure permissions on /etc/passwd- are configured"
ansible.builtin.file:
path: /etc/passwd-
owner: root
group: root
mode: 0644
when:
- rhel9cis_rule_6_1_2
tags:
- skip_ansible_lint
- level1-server
- level1-workstation
- automated
- patch
- stickybits
- permissons
- rule_1.1.21
- permissions
- rule_6.1.2
- name: "6.1.3 | PATCH | Ensure permissions on /etc/passwd are configured"
file:
dest: /etc/passwd
- name: "6.1.3 | PATCH | Ensure permissions on /etc/group are configured"
ansible.builtin.file:
path: /etc/group-
owner: root
group: root
mode: 0644
@ -75,46 +41,43 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- rule_6.1.3
- name: "6.1.4 | PATCH | Ensure permissions on /etc/shadow are configured"
file:
dest: /etc/shadow
- name: "6.1.4 | PATCH | Ensure permissions on /etc/group- are configured"
ansible.builtin.file:
path: /etc/group-
owner: root
group: root
mode: 0000
mode: 0644
when:
- rhel9cis_rule_6_1_4
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- permissionss
- rule_6.1.4
- name: "6.1.5 | PATCH | Ensure permissions on /etc/group are configured"
file:
dest: /etc/group-
- name: "6.1.5 | PATCH | Ensure permissions on /etc/shadow are configured"
ansible.builtin.file:
path: /etc/shadow
owner: root
group: root
mode: 0644
mode: 0000
when:
- rhel9cis_rule_6_1_5
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- rule_6.1.5
- name: "6.1.6 | PATCH | Ensure permissions on /etc/gshadow are configured"
file:
dest: /etc/gshadow
- name: "6.1.6 | PATCH | Ensure permissions on /etc/shadow- are configured"
ansible.builtin.file:
path: /etc/shadow-
owner: root
group: root
mode: 0000
@ -123,196 +86,216 @@
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- rule_6.1.6
- name: "6.1.7 | PATCH | Ensure permissions on /etc/passwd- are configured"
file:
dest: /etc/passwd-
- name: "6.1.7 | PATCH | Ensure permissions on /etc/gshadow are configured"
ansible.builtin.file:
path: /etc/gshadow
owner: root
group: root
mode: 0644
mode: 0000
when:
- rhel9cis_rule_6_1_7
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- rule_6.1.7
- name: "6.1.6 | PATCH | Ensure permissions on /etc/shadow- are configured"
file:
dest: /etc/shadow-
- name: "6.1.8 | PATCH | Ensure permissions on /etc/gshadow- are configured"
ansible.builtin.file:
path: /etc/gshadow-
owner: root
group: root
mode: 0000
when:
- rhel9cis_rule_6_1_6
- rhel9cis_rule_6_1_8
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissions
- rule_6.1.6
- rule_6.1.10
- name: "6.1.9 | PATCH | Ensure permissions on /etc/group- are configured"
file:
dest: /etc/group-
owner: root
group: root
mode: 0644
- name: "6.1.9 | PATCH | Ensure no world writable files exist"
block:
- name: "6.1.9 | AUDIT | Ensure no world writable files exist | Get list of world-writable files"
ansible.builtin.shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -0002
failed_when: false
changed_when: false
register: rhel_09_6_1_9_perms_results
- name: "6.1.9 | PATCH | Ensure no world writable files exist | Adjust world-writable files if they exist (Configurable)"
ansible.builtin.file:
path: '{{ item }}'
mode: o-w
state: touch
loop: "{{ rhel_09_6_1_9_perms_results.stdout_lines }}"
when:
- rhel_09_6_1_9_perms_results.stdout_lines is defined
- rhel9cis_no_world_write_adjust
when:
- rhel9cis_rule_6_1_9
tags:
- level1-server
- level1-workstation
- automated
- patch
- permissionss
- files
- permissions
- rule_6.1.9
- name: "6.1.10 | PATCH | Ensure permissions on /etc/gshadow- are configured"
file:
dest: /etc/gshadow-
owner: root
group: root
mode: 0000
- name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist"
block:
- name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | Finding all unowned files or directories"
ansible.builtin.shell: find "{{ item.mount }}" -xdev -nouser
changed_when: false
failed_when: false
check_mode: false
register: rhel_09_6_1_10_audit
loop: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.mount }}"
when: item['device'].startswith('/dev') and not 'bind' in item['options']
- name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | Displaying any unowned files or directories"
ansible.builtin.debug:
msg: "Warning !! Manual intervention is required -- missing owner on items in {{ item.item.mount }}: {{ item.stdout_lines | join(', ') }}"
loop: "{{ rhel_09_6_1_10_audit.results }}"
when:
- item.stdout_lines is defined
- item.stdout_lines | length > 0
- name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | warning"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '6.1.10'
when:
- item.stdout_lines is defined
- item.stdout_lines | length > 0
when:
- rhel9cis_rule_6_1_10
tags:
- level1-server
- level1-workstation
- automated
- patch
- audit
- files
- permissions
- rule_6.1.10
- name: "6.1.11 | PATCH | Ensure no world writable files exist"
- name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist"
block:
- 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
- name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | Finding all ungrouped files or directories"
ansible.builtin.shell: find "{{ item.mount }}" -xdev -nogroup
check_mode: false
failed_when: false
changed_when: false
register: rhel_08_6_1_11_perms_results
register: rhel_09_6_1_11_audit
loop: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.mount }}"
when: item['device'].startswith('/dev') and not 'bind' in item['options']
- name: "6.1.11 | 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"
- name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | Displaying all ungrouped files or directories"
ansible.builtin.debug:
msg: "Warning !! Manual intervention is required -- missing group on items in {{ item.item.mount }}: {{ item.stdout_lines | join(', ') }}"
loop: "{{ rhel_09_6_1_11_audit.results }}"
when:
- rhel_08_6_1_11_perms_results.stdout is not defined
- item.stdout_lines is defined
- item.stdout_lines | length > 0
- 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 }}"
- name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | warning"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '6.1.11'
when:
- rhel_08_6_1_11_perms_results.stdout_lines is defined
- rhel9cis_no_world_write_adjust
- item.stdout_lines is defined
- item.stdout_lines | length > 0
when:
- rhel9cis_rule_6_1_11
tags:
- level1-server
- level1-workstation
- automated
- patch
- audit
- files
- permissions
- rule_6.1.11
- name: "6.1.12 | AUDIT | Ensure no unowned files or directories exist"
block:
- 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
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 | AUDIT | Ensure no unowned files or directories exist | Displaying any unowned files or directories"
debug:
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
- name: "6.1.12 | PATCH | Ensure sticky bit is set on all world-writable directories"
ansible.builtin.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
changed_when: false
failed_when: false
when:
- rhel9cis_rule_6_1_12
tags:
- level1-server
- level1-workstation
- automated
- audit
- files
- permissions
- rule_6.1.12
- patch
- stickybits
- permissons
- rule_1.1.21
- name: "6.1.13 | AUDIT | Ensure no ungrouped files or directories exist"
- name: "6.1.13 | AUDIT | Audit SUID executables"
block:
- 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
- name: "6.1.13 | AUDIT | Audit SUID executables | Find all SUID executables"
ansible.builtin.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_08_6_1_13_audit
with_items: "{{ ansible_mounts }}"
register: rhel_09_6_1_13_perms_results
loop: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.mount }}"
when: item['device'].startswith('/dev') and not 'bind' in item['options']
- name: "6.1.13 | AUDIT | Ensure no ungrouped files or directories exist | Displaying all ungrouped files or directories"
debug:
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 }}"
- name: "6.1.13 | AUDIT | Audit SUID executables | Alert SUID executables exist"
ansible.builtin.debug:
msg: "Warning!! Manual intervention is required -- SUID set on items in {{ item.item.mount }}: {{ item.stout_lines | join(', ') }}"
loop: "{{ rhel_09_6_1_13_perms_results.stdout_lines }}"
when:
- item.stdout_lines is defined
- item.stdout_lines | length > 0
- rhel_09_6_1_13_perms_results.stdout is defined
- name: "6.1.13 | AUDIT | Audit SUID executables | Alert SUID executables exist | warning"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '6.1.13'
when:
- rhel_09_6_1_13_perms_results.stdout is defined
when:
- rhel9cis_rule_6_1_13
tags:
- level1-server
- level1-workstation
- automated
- manual
- audit
- files
- permissions
- rule_6.1.13
- name: "6.1.14 | AUDIT | Audit SUID executables"
- name: "6.1.14 | AUDIT | Audit SGID executables"
block:
- 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
- name: "6.1.14 | AUDIT | Audit SGID executables | Find all SGID executables"
ansible.builtin.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_14_perms_results
with_items: "{{ ansible_mounts }}"
register: rhel_09_6_1_14_perms_results
loop: "{{ ansible_mounts }}"
loop_control:
label: "{{ item.mount }}"
- name: "6.1.14 | AUDIT | Audit SUID executables | Alert no SUID executables exist"
debug:
msg: "Good news! We have not found any SUID executable files on your system"
failed_when: false
changed_when: false
- name: "6.1.14 | AUDIT | Audit SGID executables | Alert SGID executables exist"
ansible.builtin.debug:
msg: "Manual intervention is required -- SGID set on items in {{ item.item.mount }}: {{ item.stout_lines | join(', ') }}"
loop: "{{ rhel_09_6_1_14_perms_results.stdout_lines }}"
when:
- rhel_08_6_1_14_perms_results.stdout is not defined
- rhel_09_6_1_14_perms_results.stdout is defined
- name: "6.1.14 | 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_08_6_1_14_perms_results.stdout_lines }}"
- name: "6.1.14 | AUDIT | Audit SGID executables| warning"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '6.1.14'
when:
- rhel_08_6_1_14_perms_results.stdout is defined
- rhel_09_6_1_14_perms_results.stdout is defined
when:
- rhel9cis_rule_6_1_14
tags:
@ -323,37 +306,41 @@
- files
- rule_6.1.14
- name: "6.1.15 | AUDIT | Audit SGID executables"
- name: "6.1.15 | AUDIT | Audit system file permissions"
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
- name: "6.1.15 | AUDIT | Audit system file permissions | Audit the packages"
ansible.builtin.shell: rpm -Va --nomtime --nosize --nomd5 --nolinkto
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
register: rhel9cis_6_1_15_packages_rpm
- 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
- name: "6.1.15 | AUDIT | Audit system file permissions | Create list and warning"
block:
- name: "6.1.15 | AUDIT | Audit system file permissions | Add file discrepancy list to system"
ansible.builtin.copy:
dest: "{{ rhel9cis_rpm_audit_file }}" # noqa template-instead-of-copy
content: "{{ rhel9cis_6_1_15_packages_rpm.stdout }}"
owner: root
group: root
mode: 0640
- name: "6.1.15 | AUDIT | Audit system file permissions | Message out alert for package descrepancies"
ansible.builtin.debug:
msg: |
"Warning!! You have some package descrepancies issues.
The file list can be found in {{ rhel9cis_rpm_audit_file }}"
- name: "6.1.15 | AUDIT | Audit system file permissions | warning count"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '6.1.15'
when: rhel9cis_6_1_15_packages_rpm.stdout|length > 0
when:
- rhel9cis_rule_6_1_15
tags:
- level1-server
- level1-workstation
- level2-server
- level2-workstation
- manual
- audit
- files
- permissions
- rule_6.1.15

View file

@ -1,511 +1,451 @@
---
- 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 }}"
- name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords"
block:
- name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords | discover"
ansible.builtin.shell: awk -F':' '($2 != "x" ) { print $1 " is not set to shadowed passwords "}' /etc/passwd
changed_when: false
register: shadow_passwd
- name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords | Output"
ansible.builtin.debug:
msg: |
- "Warning!! Below are the accounts that do not have shadowed passwords set"
- "{{ shadow_passwd.stdout_line }}"
when: shadow_passwd.stdout | length > 0
- name: "6.2.1 | AUDIT | Ensure accounts in /etc/passwd use shadowed passwords | warning fact"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '6.2.1'
when: shadow_passwd.stdout | length >= 1
when:
- empty_password_accounts.rc
- rhel9cis_rule_6_2_1
tags:
- level1-server
- level1-workstation
- automated
- patch
- accounts
- rule_6.2.1
- 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 | length == 0
- 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 | length >= 1
- name: "6.2.2 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.2.2' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_2_2_passwd_gid_check.stdout | length >= 1
- name: "6.2.2 | PATCH | Ensure password fields are not empty"
ansible.builtin.shell: passwd -l {{ item }}
changed_when: false
failed_when: false
loop: "{{ empty_password_accounts.stdout_lines }}"
when:
- empty_password_accounts.rc
- rhel9cis_rule_6_2_2
tags:
- level1-server
- level1-workstation
- automated
- audit
- patch
- accounts
- groups
- rule_6.2.2
- name: "6.2.3 | AUDIT Ensure no duplicate UIDs exist"
- name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group"
block:
- 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"
- name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Check /etc/passwd entries"
ansible.builtin.shell: pwck -r | grep 'no group' | awk '{ gsub("[:\47]",""); print $2}'
changed_when: false
failed_when: false
register: rhel9cis_6_2_3_user_uid_check
check_mode: false
register: rhel9cis_6_2_3_passwd_gid_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 | length == 0
- name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Print warning about users with invalid GIDs missing GID entries in /etc/group"
ansible.builtin.debug:
msg: "Warning!! The following users have non-existent GIDs (Groups): {{ rhel9cis_6_2_3_passwd_gid_check.stdout_lines | join (', ') }}"
when: rhel9cis_6_2_3_passwd_gid_check.stdout | length >= 1
- 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 | length >= 1
- name: "6.2.3 | AUDIT| Ensure no duplicate UIDs exist | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.2.3' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_2_3_user_uid_check.stdout | length >= 1
- name: "6.2.3 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | warning count"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '6.2.3'
when: rhel9cis_6_2_3_passwd_gid_check.stdout | length >= 1
when:
- rhel9cis_rule_6_2_3
tags:
- level1-server
- level1-workstation
- automated
- audit
- accounts
- users
- rule_6.2.3
- groups
- rule_6.2.2
- name: "6.2.4 | AUDIT | Ensure no duplicate GIDs exist"
- name: "6.2.4 | AUDIT Ensure no duplicate UIDs 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"
- name: "6.2.4 | AUDIT | Ensure no duplicate UIDs exist | Check for duplicate UIDs"
ansible.builtin.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_4_user_user_check
register: rhel9cis_6_2_4_user_uid_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 | length == 0
- 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 | length >= 1
- name: "6.2.4 | AUDIT | Ensure no duplicate GIDs exist | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.2.4' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_2_4_user_user_check.stdout | length >= 1
- name: "6.2.4 | AUDIT | Ensure no duplicate UIDs exist | Print warning about users with duplicate UIDs"
ansible.builtin.debug:
msg: "Warning!! The following users have UIDs that are duplicates: {{ rhel9cis_6_2_4_user_uid_check.stdout_lines }}"
when: rhel9cis_6_2_4_user_uid_check.stdout | length >= 1
- name: "6.2.4 | AUDIT| Ensure no duplicate UIDs exist | warning count"
ansible.builtin.import_tasks: warning_facts.yml
when: rhel9cis_6_2_4_user_uid_check.stdout | length >= 1
vars:
warn_control_id: '6.2.4'
when:
- rhel9cis_rule_6_2_4
tags:
- level1-server
- level1-workstation
- automated
- audit
- accounts
- groups
- users
- rule_6.2.4
- name: "6.2.5 | AUDIT | Ensure no duplicate user names exist"
- name: "6.2.5 | AUDIT | Ensure no duplicate GIDs 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"
- name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist | Check for duplicate GIDs"
ansible.builtin.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_5_user_username_check
register: rhel9cis_6_2_5_user_user_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 | length == 0
- name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist | Print warning about users with duplicate GIDs"
ansible.builtin.debug:
msg: "Warning!! The following groups have duplicate GIDs: {{ rhel9cis_6_2_5_user_user_check.stdout_lines }}"
when: rhel9cis_6_2_5_user_user_check.stdout | length >= 1
- 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 | length >= 1
- name: "6.2.5 | AUDIT | Ensure no duplicate GIDs exist | warning count"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '6.2.5'
when: rhel9cis_6_2_5_user_user_check.stdout_lines | length >= 1
- name: "6.2.5 | AUDIT | Ensure no duplicate user names exist | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.2.5' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_2_5_user_username_check.stdout | length >= 1
when:
- rhel9cis_rule_6_2_5
tags:
- level1-server
- level1-workstation
- automated
- audit
- accounts
- users
- groups
- rule_6.2.5
- name: "6.2.6 | AUDIT |Ensure no duplicate group names exist"
- name: "6.2.6 | AUDIT | Ensure no duplicate user 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'
- name: "6.2.6 | AUDIT | Ensure no duplicate user names exist | Check for duplicate User Names"
ansible.builtin.shell: "pwck -r | awk -F: '{if ($1 in users) print $1 ; else users[$1]}' /etc/passwd"
changed_when: false
failed_when: false
check_mode: false
register: rhel9cis_6_2_6_group_group_check
register: rhel9cis_6_2_6_user_username_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 user names exist | Print warning about users with duplicate User Names"
ansible.builtin.debug:
msg: "Warning!! The following user names are duplicates: {{ rhel9cis_6_2_6_user_username_check.stdout_lines }}"
when: rhel9cis_6_2_6_user_username_check.stdout | length >= 1
- 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
- name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.2.6' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_2_6_group_group_check.stdout is not defined
- name: "6.2.6 | AUDIT | Ensure no duplicate user names exist | warning count"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '6.2.6'
when: rhel9cis_6_2_6_user_username_check.stdout | length >= 1
when:
- rhel9cis_rule_6_2_6
tags:
- level1-server
- level1-workstation
- automated
- audit
- accounts
- groups
- users
- rule_6.2.6
- name: "6.2.7 | PATCH | Ensure root PATH Integrity"
- name: "6.2.7 | AUDIT | Ensure no duplicate group names exist"
block:
- name: "6.2.7 | AUDIT | Ensure root PATH Integrity | Determine empty value"
shell: 'echo $PATH | grep ::'
- name: "6.2.7 | AUDIT | Ensure no duplicate group names exist | Check for duplicate group names"
ansible.builtin.shell: 'getent passwd | cut -d: -f1 | sort -n | uniq -d'
changed_when: false
failed_when: rhel9cis_6_2_7_path_colon.rc == 0
failed_when: false
check_mode: false
register: rhel9cis_6_2_7_path_colon
register: rhel9cis_6_2_7_group_group_check
- name: "6.2.7 | AUDIT | Ensure root PATH Integrity | Determin colon end"
shell: 'echo $PATH | grep :$'
changed_when: false
failed_when: rhel9cis_6_2_7_path_colon_end.rc == 0
check_mode: false
register: rhel9cis_6_2_7_path_colon_end
- name: "6.2.7 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names"
ansible.builtin.debug:
msg: "Warning!! The following group names are duplicates: {{ rhel9cis_6_2_7_group_group_check.stdout_lines }}"
when: rhel9cis_6_2_7_group_group_check.stdout is not defined
- 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'"
changed_when: false
failed_when: '"." in rhel9cis_6_2_7_dot_in_path.stdout_lines'
check_mode: false
register: rhel9cis_6_2_7_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: {{ 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.7 | PATCH | Ensure root PATH Integrity | Determine rights and owner"
file: >
path='{{ item }}'
follow=yes
state=directory
owner=root
mode='o-w,g-w'
with_items: "{{ rhel9cis_6_2_7_dot_in_path.stdout_lines }}"
- name: "6.2.7 | AUDIT | Ensure no duplicate group names exist | warning count"
ansible.builtin.import_tasks: warning_facts.yml
vars:
warn_control_id: '6.2.7'
when: rhel9cis_6_2_7_group_group_check.stdout is not defined
when:
- rhel9cis_rule_6_2_7
tags:
- level1-server
- level1-workstation
- automated
- patch
- paths
- audit
- accounts
- groups
- rule_6.2.7
- 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 }}"
- name: "6.2.8 | PATCH | Ensure root PATH Integrity"
block:
- name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Get root paths"
ansible.builtin.shell: sudo -Hiu root env | grep '^PATH' | cut -d= -f2
changed_when: false
register: rhel9cis_6_2_8_root_paths
- name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Get root paths"
ansible.builtin.shell: sudo -Hiu root env | grep '^PATH' | cut -d= -f2 | tr ":" "\n"
changed_when: false
register: rhel9cis_6_2_8_root_paths_split
- name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Set fact"
ansible.builtin.set_fact:
root_paths: "{{ rhel9cis_6_2_8_root_paths.stdout }}"
- name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for empty dirs"
ansible.builtin.shell: 'echo {{ root_paths }} | grep -q "::" && echo "roots path contains a empty directory (::)"'
changed_when: false
failed_when: root_path_empty_dir.rc not in [ 0, 1 ]
register: root_path_empty_dir
- name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for trailing ':'"
ansible.builtin.shell: '{{ root_paths }} | cut -d= -f2 | grep -q ":$" && echo "roots path contains a trailing (:)"'
changed_when: false
failed_when: root_path_trailing_colon.rc not in [ 0, 1 ]
register: root_path_trailing_colon
- name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for owner and permissions"
block:
- name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Check for owner and permissions"
ansible.builtin.stat:
path: "{{ item }}"
register: root_path_perms
loop: "{{ rhel9cis_6_2_8_root_paths_split.stdout_lines }}"
- name: "6.2.8 | AUDIT | Ensure root PATH Integrity | Set permissions"
ansible.builtin.file:
path: "{{ item.stat.path }}"
state: directory
owner: root
group: root
mode: "0755"
follow: false
loop: "{{ root_path_perms.results }}"
loop_control:
label: "{{ item }}"
when:
- item.stat.exists
- item.stat.isdir
- item.stat.pw_name != 'root' or item.stat.gr_name != 'root' or item.stat.woth or item.stat.wgrp
when:
- rhel9cis_uid_zero_accounts_except_root.rc
- rhel9cis_rule_6_2_8
tags:
- level1-server
- level1-workstation
- automated
- patch
- accounts
- users
- paths
- rule_6.2.8
- name: "6.2.9 | PATCH | Ensure all users' home directories exist"
block:
- name: "6.2.9 | AUDIT | Ensure all users' home directories exist"
stat:
path: "{{ item }}"
register: rhel_08_6_2_9_audit
with_items: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int ) | selectattr('uid', '<=', max_int_uid | int ) | map(attribute='dir') | list }}"
- 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_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_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.9 | PATCH | Ensure all users' home directories exist"
file:
path: "{{ item.0 }}"
recurse: true
mode: a-st,g-w,o-rwx
register: rhel_08_6_2_9_patch
when:
- not ansible_check_mode
- item.1.exists
with_together:
- "{{ 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.9 | PATCH | Ensure all users' home directories exist"
acl:
path: "{{ item.0 }}"
default: true
state: present
recursive: true
etype: "{{ item.1.etype }}"
permissions: "{{ item.1.mode }}"
when:
- not system_is_container
with_nested:
- "{{ (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
mode: rx
- etype: other
mode: '0'
- name: "6.2.9 | PATCH | Ensure root is the only UID 0 account"
ansible.builtin.shell: passwd -l {{ item }}
changed_when: false
failed_when: false
loop: "{{ rhel9cis_uid_zero_accounts_except_root.stdout_lines }}"
when:
- rhel9cis_uid_zero_accounts_except_root.rc
- rhel9cis_rule_6_2_9
tags:
- level1-server
- level1-workstation
- automated
- patch
- accounts
- users
- rule_6.2.9
- name: "6.2.10 | PATCH | Ensure local interactive user home directories exist"
block:
- name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Create dir if absent"
ansible.builtin.file:
path: "{{ item.dir }}"
state: directory
owner: "{{ item.id }}"
group: "{{ item.gid }}"
register: rhel_09_6_2_10_home_dir
loop: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int ) | selectattr('uid', '<=', max_int_uid | int ) | list }}"
loop_control:
label: "{{ item.id }}"
- name: "6.2.10 | PATCH | Ensure users own their home directories"
file:
path: "{{ item.dir }}"
owner: "{{ item.id }}"
state: directory
with_items: "{{ rhel9cis_passwd }}"
loop_control:
label: "{{ rhel9cis_passwd_label }}"
# set default ACLs so the homedir has an effective umask of 0027
- name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Set group ACL"
ansible.posix.acl:
path: "{{ item }}"
default: true
etype: group
permissions: rx
state: present
loop: "{{ interactive_users_home.stdout_lines }}"
when: not system_is_container
- name: "6.2.10 | PATCH | Ensure local interactive user home directories exist | Set other ACL"
ansible.posix.acl:
path: "{{ item }}"
default: true
etype: other
permissions: 0
state: present
loop: "{{ interactive_users_home.stdout_lines }}"
when: not system_is_container
when:
- item.uid >= min_int_uid | int
- item.id != 'nobody'
- (item.id != 'tss' and item.dir != '/dev/null')
- rhel9cis_rule_6_2_10
tags:
- skip_ansible_lint # settings found on 6_2_7
- level1-server
- level1-workstation
- automated
- patch
- users
- rule_6.2.10
- name: "6.2.11 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
block:
- name: "6.2.11 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive"
stat:
path: "{{ item }}"
with_items: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int) | selectattr('uid', '<=', max_int_uid | int) | map(attribute='dir') | list }}"
register: rhel_08_6_2_11_audit
- 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_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_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.11 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
file:
path: "{{ item.0 }}"
recurse: true
mode: a-st,g-w,o-rwx
register: rhel_08_6_2_11_patch
when:
- not ansible_check_mode
- item.1.exists
with_together:
- "{{ 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.11 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
acl:
path: "{{ item.0 }}"
default: true
state: present
recursive: true
etype: "{{ item.1.etype }}"
permissions: "{{ item.1.mode }}"
when:
- not system_is_container
with_nested:
- "{{ (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
mode: rx
- etype: other
mode: '0'
- name: "6.2.11 | PATCH | Ensure local interactive users own their home directories"
ansible.builtin.file:
path: "{{ item.dir }}"
owner: "{{ item.id }}"
state: directory
loop: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int ) | selectattr('uid', '<=', max_int_uid | int ) | list }}"
loop_control:
label: "{{ item.id }}"
when:
- item.uid >= min_int_uid | int
- item.id != 'nobody'
- (item.id != 'tss' and item.dir != '/dev/null')
- item.shell != '/sbin/nologin'
- rhel9cis_rule_6_2_11
tags:
- level1-server
- level1-workstation
- automated
- patch
- users
- permissions
- rule_6.2.11
- name: "6.2.12 | PATCH | Ensure users' dot files are not group or world-writable"
- name: "6.2.12 | PATCH | Ensure local interactive user home directories are mode 750 or more restrictive"
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 local interactive user home directories are mode 750 or more restrictive | get stat"
ansible.builtin.stat:
path: "{{ item }}"
register: rhel_09_6_2_12_home_dir_perms
loop: "{{ interactive_users_home.stdout_lines }}"
- 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"
- name: "6.2.12 | PATCH | Ensure local interactive user home directories are mode 750 or more restrictive | amend if needed"
ansible.builtin.file:
path: "{{ item.stat.path }}"
state: directory
mode: "0750"
loop: "{{ rhel_09_6_2_12_home_dir_perms.results }}"
loop_control:
label: "{{ item }}"
when:
- rhel9cis_6_2_12_audit.stdout is not defined
- item.stat.mode > '0750'
- 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
# set default ACLs so the homedir has an effective umask of 0027
- name: "6.2.12 | PATCH | Ensure local interactive user home directories are mode 750 or more restrictive | Set group ACL"
ansible.posix.acl:
path: "{{ item }}"
default: true
etype: group
permissions: rx
state: present
loop: "{{ interactive_users_home.stdout_lines }}"
when: not system_is_container
- name: "6.2.12 | PATCH | Ensure local interactive user home directories are mode 750 or more restrictive | Set other ACL"
ansible.posix.acl:
path: "{{ item }}"
default: true
etype: other
permissions: 0
state: present
loop: "{{ interactive_users_home.stdout_lines }}"
when: not system_is_container
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
- name: "6.2.13 | PATCH | Ensure no local interactive user has .netrc files"
ansible.builtin.file:
path: "{{ item }}/.netrc"
state: absent
loop: "{{ interactive_users_home.stdout_lines }}"
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:
path: "~{{ item }}/.forward"
- name: "6.2.14 | PATCH | Ensure no local interactive user has .forward files"
ansible.builtin.file:
path: "{{ item }}/.forward"
state: absent
with_items:
- "{{ users.stdout_lines }}"
loop: "{{ interactive_users_home.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:
path: "~{{ item }}/.netrc"
- name: "6.2.15 | PATCH | Ensure no local interactive user has .rhosts files"
ansible.builtin.file:
path: "~{{ item }}/.rhosts"
state: absent
with_items:
- "{{ users.stdout_lines }}"
loop: "{{ interactive_users_home.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:
path: "~{{ item }}/.rhosts"
state: absent
with_items: "{{ users.stdout_lines }}"
- name: "6.2.16 | PATCH | Ensure local interactive user dot files are not group or world writable"
block:
- name: "6.2.16 | AUDIT | Ensure local interactive user dot files are not group or world writable | Check for files"
ansible.builtin.find:
path: /home
depth: 3
patterns: ".*"
hidden: true
recurse: true
file_type: file
register: user_dot_files
- name: "6.2.16 | AUDIT | Ensure local interactive user dot files are not group or world writable | update permissions"
ansible.builtin.file:
path: "{{ item.path }}"
mode: go-w
loop: "{{ user_dot_files.files }}"
loop_control:
label: "{{ item.path }}"
when:
- rhel9cis_rule_6_2_16
tags:
- level1-server
- level1-workstation
- automated
- patch
- users
- files
- permissions
- rule_6.2.16

View file

@ -1,7 +1,7 @@
---
- name: "SECTION | 6.1 | System File Permissions"
import_tasks: cis_6.1.x.yml
ansible.builtin.import_tasks: cis_6.1.x.yml
- name: "SECTION | 6.2 | User and Group Settings"
import_tasks: cis_6.2.x.yml
ansible.builtin.import_tasks: cis_6.2.x.yml

20
tasks/warning_facts.yml Normal file
View file

@ -0,0 +1,20 @@
---
# This task is used to create variables used in giving a warning summary for manual tasks
# that need attention
#
# The warn_control_list and warn_count vars start life in vars/main.yml but get updated
# as the tasks that have a warning complete
#
# Those two variables are used in the tasks/main.yml to display a list of warnings
#
# warn_control_id is set within the task itself and has the control ID as the value
#
# warn_control_list is the main variable to be used and is a list made up of the warn_control_ids
#
# warn_count the main variable for the number of warnings and each time a warn_control_id is added
# the count increases by a value of 1
- name: "{{ warn_control_id }} | AUDIT | Set fact for manual task warning."
ansible.builtin.set_fact:
warn_control_list: "{{ warn_control_list }} [{{ warn_control_id }}]"
warn_count: "{{ warn_count | int + 1 }}"

View file

@ -3,7 +3,7 @@
## metadata for benchmark
## metadata for Audit benchmark
benchmark_version: '2.0.0'
benchmark_version: '1.0.0'
# Set if genuine RHEL (subscription manager check) not for derivatives e.g. CentOS
# If run via script this is discovered and set
@ -44,7 +44,6 @@ rhel9cis_set_boot_pass: {{ rhel9cis_set_boot_pass }}
# 1.1.1 Disable unused filesystems
rhel9cis_rule_1_1_1_1: {{ rhel9cis_rule_1_1_1_1 }}
rhel9cis_rule_1_1_1_2: {{ rhel9cis_rule_1_1_1_2 }}
rhel9cis_rule_1_1_1_3: {{ rhel9cis_rule_1_1_1_3 }}
# 1.1.2 Configure /tmp
rhel9cis_rule_1_1_2_1: {{ rhel9cis_rule_1_1_2_1 }}
rhel9cis_rule_1_1_2_2: {{ rhel9cis_rule_1_1_2_2 }}
@ -54,7 +53,6 @@ rhel9cis_rule_1_1_2_4: {{ rhel9cis_rule_1_1_2_4 }}
rhel9cis_rule_1_1_3_1: {{ rhel9cis_rule_1_1_3_1 }}
rhel9cis_rule_1_1_3_2: {{ rhel9cis_rule_1_1_3_2 }}
rhel9cis_rule_1_1_3_3: {{ rhel9cis_rule_1_1_3_3 }}
rhel9cis_rule_1_1_3_4: {{ rhel9cis_rule_1_1_3_4 }}
# 1.1.4 Configure /var/tmp
rhel9cis_rule_1_1_4_1: {{ rhel9cis_rule_1_1_4_1 }}
rhel9cis_rule_1_1_4_2: {{ rhel9cis_rule_1_1_4_2 }}
@ -74,28 +72,25 @@ rhel9cis_rule_1_1_6_4: {{ rhel9cis_rule_1_1_6_4 }}
rhel9cis_rule_1_1_7_1: {{ rhel9cis_rule_1_1_7_1 }}
rhel9cis_rule_1_1_7_2: {{ rhel9cis_rule_1_1_7_2 }}
rhel9cis_rule_1_1_7_3: {{ rhel9cis_rule_1_1_7_3 }}
rhel9cis_rule_1_1_7_4: {{ rhel9cis_rule_1_1_7_4 }}
rhel9cis_rule_1_1_7_5: {{ rhel9cis_rule_1_1_7_5 }}
# 1.1.8 Configure /dev/shm
rhel9cis_rule_1_1_8_1: {{ rhel9cis_rule_1_1_8_1 }}
rhel9cis_rule_1_1_8_2: {{ rhel9cis_rule_1_1_8_2 }}
rhel9cis_rule_1_1_8_3: {{ rhel9cis_rule_1_1_8_3 }}
# 1.9 autofs
rhel9cis_rule_1_1_8_4: {{ rhel9cis_rule_1_1_8_4 }}
# 1.9 usb-storage
rhel9cis_rule_1_1_9: {{ rhel9cis_rule_1_1_9 }}
# 1.10 usb-storage
rhel9cis_rule_1_1_10: {{ rhel9cis_rule_1_1_10 }}
# 1.2 Configure Software Updates
rhel9cis_rule_1_2_1: {% if ansible_distribution == "RedHat" %}True{% else %}False{% endif %} # Only run if Redhat and Subscribed
rhel9cis_rule_1_2_1: {{ rhel9cis_rule_1_2_1 }}
rhel9cis_rule_1_2_2: {{ rhel9cis_rule_1_2_2 }}
rhel9cis_rule_1_2_3: {{ rhel9cis_rule_1_2_3 }}
rhel9cis_rule_1_2_4: {{ rhel9cis_rule_1_2_4 }}
# 1.3 Filesystem Integrity Checking
rhel9cis_rule_1_3_1: {{ rhel9cis_rule_1_3_1 }}
rhel9cis_rule_1_3_2: {{ rhel9cis_rule_1_3_2 }}
rhel9cis_rule_1_3_3: {{ rhel9cis_rule_1_3_3 }}
# 1.4 Secure Boot Settings
rhel9cis_rule_1_4_1: {{ rhel9cis_rule_1_4_1 }}
rhel9cis_rule_1_4_2: {{ rhel9cis_rule_1_4_2 }}
rhel9cis_rule_1_4_3: {{ rhel9cis_rule_1_4_3 }}
# 1.5 Additional Process Hardening
rhel9cis_rule_1_5_1: {{ rhel9cis_rule_1_5_1 }}
rhel9cis_rule_1_5_2: {{ rhel9cis_rule_1_5_2 }}
@ -108,6 +103,7 @@ rhel9cis_rule_1_6_1_4: {{ rhel9cis_rule_1_6_1_4 }}
rhel9cis_rule_1_6_1_5: {{ rhel9cis_rule_1_6_1_5 }}
rhel9cis_rule_1_6_1_6: {{ rhel9cis_rule_1_6_1_6 }}
rhel9cis_rule_1_6_1_7: {{ rhel9cis_rule_1_6_1_7 }}
rhel9cis_rule_1_6_1_8: {{ rhel9cis_rule_1_6_1_8 }}
# 1.7 Command Line Warning Banners
rhel9cis_rule_1_7_1: {{ rhel9cis_rule_1_7_1 }}
rhel9cis_rule_1_7_2: {{ rhel9cis_rule_1_7_2 }}
@ -121,6 +117,11 @@ rhel9cis_rule_1_8_2: {{ rhel9cis_rule_1_8_2 }}
rhel9cis_rule_1_8_3: {{ rhel9cis_rule_1_8_3 }}
rhel9cis_rule_1_8_4: {{ rhel9cis_rule_1_8_4 }}
rhel9cis_rule_1_8_5: {{ rhel9cis_rule_1_8_5 }}
rhel9cis_rule_1_8_6: {{ rhel9cis_rule_1_8_6 }}
rhel9cis_rule_1_8_7: {{ rhel9cis_rule_1_8_7 }}
rhel9cis_rule_1_8_8: {{ rhel9cis_rule_1_8_8 }}
rhel9cis_rule_1_8_9: {{ rhel9cis_rule_1_8_9 }}
rhel9cis_rule_1_8_10: {{ rhel9cis_rule_1_8_10 }}
# 1.9 Ensure updates, patches, and additional security software are installed
rhel9cis_rule_1_9: {{ rhel9cis_rule_1_9 }}
# Ensure system-wide crypto policy is not legacy
@ -151,24 +152,19 @@ rhel9cis_rule_2_2_15: {{ rhel9cis_rule_2_2_15 }}
rhel9cis_rule_2_2_16: {{ rhel9cis_rule_2_2_16 }}
rhel9cis_rule_2_2_17: {{ rhel9cis_rule_2_2_17 }}
rhel9cis_rule_2_2_18: {{ rhel9cis_rule_2_2_18 }}
rhel9cis_rule_2_2_19: {{ rhel9cis_rule_2_2_19 }}
rhel9cis_rule_2_2_20: {{ rhel9cis_rule_2_2_20 }}
# 2.3 service clients
rhel9cis_rule_2_3_1: {{ rhel9cis_rule_2_3_1 }}
rhel9cis_rule_2_3_2: {{ rhel9cis_rule_2_3_2 }}
rhel9cis_rule_2_3_3: {{ rhel9cis_rule_2_3_3 }}
rhel9cis_rule_2_3_4: {{ rhel9cis_rule_2_3_4 }}
rhel9cis_rule_2_3_5: {{ rhel9cis_rule_2_3_5 }}
rhel9cis_rule_2_3_6: {{ rhel9cis_rule_2_3_6 }}
rhel9cis_rule_2_4: true # todo
rhel9cis_rule_2_4: true
# Section 3 rules
# 3.1 Disable unused network protocols and devices
rhel9cis_rule_3_1_1: {{ rhel9cis_rule_3_1_1 }}
rhel9cis_rule_3_1_2: {{ rhel9cis_rule_3_1_2 }}
rhel9cis_rule_3_1_3: {{ rhel9cis_rule_3_1_3 }}
rhel9cis_rule_3_1_4: {{ rhel9cis_rule_3_1_4 }}
# 3.2 Network Parameters (Host Only)
rhel9cis_rule_3_2_1: {{ rhel9cis_rule_3_2_1 }}
rhel9cis_rule_3_2_2: {{ rhel9cis_rule_3_2_2 }}
@ -185,11 +181,7 @@ rhel9cis_rule_3_3_9: {{ rhel9cis_rule_3_3_9 }}
# 3.4.1 Configure firewalld
rhel9cis_rule_3_4_1_1: {{ rhel9cis_rule_3_4_1_1 }}
rhel9cis_rule_3_4_1_2: {{ rhel9cis_rule_3_4_1_2 }}
rhel9cis_rule_3_4_1_3: {{ rhel9cis_rule_3_4_1_3 }}
rhel9cis_rule_3_4_1_4: {{ rhel9cis_rule_3_4_1_4 }}
rhel9cis_rule_3_4_1_5: {{ rhel9cis_rule_3_4_1_5 }}
rhel9cis_rule_3_4_1_6: {{ rhel9cis_rule_3_4_1_6 }}
rhel9cis_rule_3_4_1_7: {{ rhel9cis_rule_3_4_1_7 }}
# 3.4.1 Configure nftables
rhel9cis_rule_3_4_2_1: {{ rhel9cis_rule_3_4_2_1 }}
rhel9cis_rule_3_4_2_2: {{ rhel9cis_rule_3_4_2_2 }}
@ -198,10 +190,7 @@ rhel9cis_rule_3_4_2_4: {{ rhel9cis_rule_3_4_2_4 }}
rhel9cis_rule_3_4_2_5: {{ rhel9cis_rule_3_4_2_5 }}
rhel9cis_rule_3_4_2_6: {{ rhel9cis_rule_3_4_2_6 }}
rhel9cis_rule_3_4_2_7: {{ rhel9cis_rule_3_4_2_7 }}
rhel9cis_rule_3_4_2_8: {{ rhel9cis_rule_3_4_2_8 }}
rhel9cis_rule_3_4_2_9: {{ rhel9cis_rule_3_4_2_9 }}
rhel9cis_rule_3_4_2_10: {{ rhel9cis_rule_3_4_2_10 }}
rhel9cis_rule_3_4_2_11: {{ rhel9cis_rule_3_4_2_11 }}
# Section 4 rules
# 4.1 Configure System Accounting
@ -238,6 +227,18 @@ rhel9cis_rule_4_1_3_19: {{ rhel9cis_rule_4_1_3_19 }}
rhel9cis_rule_4_1_3_20: {{ rhel9cis_rule_4_1_3_20 }}
rhel9cis_rule_4_1_3_21: {{ rhel9cis_rule_4_1_3_21 }}
# 4.1.4 Configure auditd file Access
rhel9cis_rule_4_1_4_1: {{ rhel9cis_rule_4_1_4_1 }}
rhel9cis_rule_4_1_4_2: {{ rhel9cis_rule_4_1_4_2 }}
rhel9cis_rule_4_1_4_3: {{ rhel9cis_rule_4_1_4_3 }}
rhel9cis_rule_4_1_4_4: {{ rhel9cis_rule_4_1_4_4 }}
rhel9cis_rule_4_1_4_5: {{ rhel9cis_rule_4_1_4_5 }}
rhel9cis_rule_4_1_4_6: {{ rhel9cis_rule_4_1_4_6 }}
rhel9cis_rule_4_1_4_7: {{ rhel9cis_rule_4_1_4_7 }}
rhel9cis_rule_4_1_4_8: {{ rhel9cis_rule_4_1_4_8 }}
rhel9cis_rule_4_1_4_9: {{ rhel9cis_rule_4_1_4_9 }}
rhel9cis_rule_4_1_4_10: {{ rhel9cis_rule_4_1_4_10 }}
# 4.2.1 Configure rsyslog
rhel9cis_rule_4_2_1_1: {{ rhel9cis_rule_4_2_1_1 }}
rhel9cis_rule_4_2_1_2: {{ rhel9cis_rule_4_2_1_2 }}
@ -262,9 +263,8 @@ rhel9cis_rule_4_2_2_7: {{ rhel9cis_rule_4_2_2_7 }}
rhel9cis_rule_4_2_3: {{ rhel9cis_rule_4_2_3 }}
# 4.3 Logrotate
rhel9cis_rule_4_3_1: {{ rhel9cis_rule_4_3_1 }}
rhel9cis_rule_4_3_2: {{ rhel9cis_rule_4_3_2 }}
rhel9cis_rule_4_3_3: {{ rhel9cis_rule_4_3_3 }}
rhel9cis_rule_4_3: {{ rhel9cis_rule_4_3 }}
# Section 5
# Authentication and Authorization
@ -331,6 +331,7 @@ rhel9cis_rule_5_6_2: {{ rhel9cis_rule_5_6_2 }}
rhel9cis_rule_5_6_3: {{ rhel9cis_rule_5_6_3 }}
rhel9cis_rule_5_6_4: {{ rhel9cis_rule_5_6_4 }}
rhel9cis_rule_5_6_5: {{ rhel9cis_rule_5_6_5 }}
rhel9cis_rule_5_6_6: {{ rhel9cis_rule_5_6_6 }}
# Section 6
# 6 System Maintenance
@ -386,17 +387,21 @@ rhel9cis_warning_banner: {{ rhel9cis_warning_banner }}
# aide setup via - cron, timer
rhel9_aide_scan: cron
# 1.8 Gnome Desktop
rhel9cis_dconf_db_name: {{ rhel9cis_dconf_db_name }}
rhel9cis_screensaver_idle_delay: {{ rhel9cis_screensaver_idle_delay }} # Set max value for idle-delay in seconds (between 1 and 900)
rhel9cis_screensaver_lock_delay: {{ rhel9cis_screensaver_lock_delay }} # Set max value for lock-delay in seconds (between 0 and 5)
# Section 2
## 2.2 Special Purposes
# Set to 'true' if X Windows is needed in your environment
rhel9cis_xwindows_required: false
### Service configuration booleans set true to keep service
rhel9cis_xinetd_server: {{ rhel9cis_xinetd_server }}
rhel9cis_avahi_server: {{ rhel9cis_avahi_server }}
rhel9cis_cups_server: {{ rhel9cis_cups_server }}
rhel9cis_dhcp_server: {{ rhel9cis_dhcp_server }}
rhel9cis_dns_server: {{ rhel9cis_dns_server }}
rhel9cis_ftp_server: {{ rhel9cis_ftp_server }}
rhel9cis_dnsmasq_server: {{ rhel9cis_dnsmasq_server }}
rhel9cis_vsftpd_server: {{ rhel9cis_vsftpd_server }}
rhel9cis_tftp_server: {{ rhel9cis_tftp_server }}
rhel9cis_httpd_server: {{ rhel9cis_httpd_server }}
@ -406,7 +411,6 @@ rhel9cis_imap_server: {{ rhel9cis_imap_server }}
rhel9cis_samba_server: {{ rhel9cis_samba_server }}
rhel9cis_squid_server: {{ rhel9cis_squid_server }}
rhel9cis_snmp_server: {{ rhel9cis_snmp_server }}
rhel9cis_nis_server: {{ rhel9cis_nis_server }}
rhel9cis_telnet_server: {{ rhel9cis_telnet_server }}
rhel9cis_is_mail_server: {{ rhel9cis_is_mail_server }}
@ -421,12 +425,10 @@ rhel9cis_use_rsync_server: {{ rhel9cis_use_rsync_server }}
rhel9cis_use_rsync_service: {{ rhel9cis_use_rsync_service }}
#### 2.3 Service clients
rhel9cis_ypbind_required: {{ rhel9cis_ypbind_required }}
rhel9cis_rsh_required: {{ rhel9cis_rsh_required }}
rhel9cis_talk_required: {{ rhel9cis_talk_required }}
rhel9cis_telnet_required: {{ rhel9cis_telnet_required }}
rhel9cis_openldap_clients_required: {{ rhel9cis_openldap_clients_required }}
rhel9cis_tftp_client: {{ rhel9cis_tftp_client }}
rhel9cis_ftp_client: {{ rhel9cis_ftp_client }}
# Section 3
@ -441,9 +443,9 @@ rhel9cis_is_router: {{ rhel9cis_is_router }}
rhel9cis_firewall: {{ rhel9cis_firewall }}
##### firewalld
rhel9cis_default_zone: {{ rhel9cis_default_zone }}
rhel9cis_firewalld_nftables_state: {{ rhel9cis_firewalld_nftables_state }} # Note if absent removes the firewalld pkg dependancy
#### nftables
rhel9cis_nftables_firewalld_state: {{ rhel9cis_nftables_firewalld_state }}
rhel9cis_nft_tables_autonewtable: {{ rhel9cis_nft_tables_autonewtable }}
rhel9cis_nft_tables_tablename: {{ rhel9cis_nft_tables_tablename }}
rhel9cis_nft_tables_autochaincreate: {{ rhel9cis_nft_tables_autochaincreate }}
@ -451,8 +453,18 @@ rhel9cis_nft_tables_autochaincreate: {{ rhel9cis_nft_tables_autochaincreate }}
# Section 4
## Set if host is a logserver
rhel9cis_remote_log_server: {{ rhel9cis_remote_log_server }}
# Remote logserver settings
rhel9cis_remote_log_host: {{ rhel9cis_remote_log_host }}
rhel9cis_remote_log_port: {{ rhel9cis_remote_log_port }}
rhel9cis_remote_log_protocol: {{ rhel9cis_remote_log_protocol }}
rhel9cis_remote_log_retrycount: {{ rhel9cis_remote_log_retrycount }}
rhel9cis_remote_log_queuesize: {{ rhel9cis_remote_log_queuesize }}
## syslog
rhel9cis_syslog: {{ rhel9cis_preferred_log_capture }}
rhel9cis_syslog: {{ rhel9cis_syslog }}
# Section 5
## 5.2.4 Note the following to understand precedence and layout

View file

@ -0,0 +1,7 @@
# Audit Tools
/sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512
/sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512
/sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512
/sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512
/sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512
/sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512

View file

@ -0,0 +1,9 @@
## Ansible controlled file
# Added as part of CIS
# provided by MindPointGroup LLC
# Lock desktop media-handling automount setting
/org/gnome/desktop/media-handling/automount
# Lock desktop media-handling automount-open
/org/gnome/desktop/media-handling/automount-open

View file

@ -0,0 +1,6 @@
## Ansible controlled file
# Added as part of CIS
# provided by MindPointGroup LLC
# Lock desktop media-handling settings
/org/gnome/desktop/media-handling/autorun-never

View file

@ -0,0 +1,7 @@
## Ansible controlled file
# Added as part of CIS
# provided by MindPointGroup LLC
[org/gnome/desktop/media-handling]
automount=false
automount-open=false

View file

@ -0,0 +1,6 @@
## Ansible controlled file
# Added as part of CIS
# provided by MindPointGroup LLC
[org/gnome/desktop/media-handling]
autorun-never=true

View file

@ -0,0 +1,17 @@
## Ansible controlled file
# Added as part of CIS
# provided by MindPointGroup LLC
# Specify the dconf path
[org/gnome/desktop/session]
# Number of seconds of inactivity before the screen goes blank
# Set to 0 seconds if you want to deactivate the screensaver.
idle-delay=uint32 {{ rhel9cis_screensaver_idle_delay }}
# Specify the dconf path
[org/gnome/desktop/screensaver]
# Number of seconds after the screen is blank before locking the screen
lock-delay=uint32 {{ rhel9cis_screensaver_lock_delay }}

View file

@ -0,0 +1,9 @@
## Ansible controlled file
# Added as part of CIS
# provided by MindPointGroup LLC
# Lock desktop screensaver idle-delay setting
/org/gnome/desktop/session/idle-delay
# Lock desktop screensaver lock-delay setting
/org/gnome/desktop/screensaver/lock-delay

View file

@ -0,0 +1,7 @@
## Ansible controlled file
# Added as part of CIS
# provided by MindPointGroup LLC
[org/gnome/login-screen]
banner-message-enable=true
banner-message-text="{{ rhel9cis_warning_banner }}"

View file

@ -1,12 +1,12 @@
---
# vars file for RHEL9-CIS
min_ansible_version: 2.9.4
min_ansible_version: 2.10.1
rhel9cis_allowed_crypto_policies:
- 'DEFAULT'
- 'FUTURE'
- 'FIPS'
# Used to control warning summary
control_number: ""
warn_control_list: ""
warn_count: 0