diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index ebe4325..68da340 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -2,14 +2,14 @@ # 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" + - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | refresh" set_fact: sysctl_update: true flush_ipv6_route: true - - name: "3.1.1 | PATCH | Verify if IPv6 is enabled on the system" + - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | disable" debug: msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-disable_ipv6.conf" when: @@ -24,72 +24,49 @@ - 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 - when: - - rhel9cis_rule_3_1_2 - tags: - - level2-server - - level2-workstation - - automated - - patch - - sctp - - 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 - when: - - rhel9cis_rule_3_1_3 - tags: - - level2-server - - level2-workstation - - automated - - dccp - - patch - - rule_3.1.3 - -- name: "3.1.4 | PATCH | Ensure wireless interfaces are disabled" +- name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled" block: - - name: "3.1.4 | AUDIT | Ensure wireless interfaces are disabled | Check if nmcli command is available" + - name: "3.1.2 | 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" + - name: "3.1.2 | 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" + - name: "3.1.2 | 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 + - rhel9cis_rule_3_1_2 tags: - level1-server - - automated - patch - wireless - - rule_3.1.4 + - rule_3.1.2 + +- name: "3.1.3 | PATCH | Ensure TIPC is disabled" + template: + src: "etc/modprobe.d/modprobe.conf.j2" + dest: "/etc/modprobe.d/{{ item }}.conf" + mode: "0600" + owner: root + group: root + with_items: + - tipc + when: + - rhel9cis_rule_3_1_3 + tags: + - level2-server + - level2-workstation + - patch + - tipc + - rule_3.1.3 diff --git a/tasks/section_3/cis_3.2.x.yml b/tasks/section_3/cis_3.2.x.yml index 6e07c55..708deb8 100644 --- a/tasks/section_3/cis_3.2.x.yml +++ b/tasks/section_3/cis_3.2.x.yml @@ -28,7 +28,6 @@ tags: - level1-server - level1-workstation - - automated - sysctl - patch - rule_3.2.1 @@ -48,7 +47,6 @@ tags: - level1-server - level1-workstation - - automated - patch - sysctl - rule_3.2.2 diff --git a/tasks/section_3/cis_3.3.x.yml b/tasks/section_3/cis_3.3.x.yml index b78593e..84363e7 100644 --- a/tasks/section_3/cis_3.3.x.yml +++ b/tasks/section_3/cis_3.3.x.yml @@ -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 diff --git a/tasks/section_3/cis_3.4.1.x.yml b/tasks/section_3/cis_3.4.1.x.yml index d43dfe6..9498c97 100644 --- a/tasks/section_3/cis_3.4.1.x.yml +++ b/tasks/section_3/cis_3.4.1.x.yml @@ -1,153 +1,54 @@ --- -- name: "3.4.1.1 | PATCH | Ensure firewalld is installed" +- name: "3.4.1.1 | PATCH | Ensure nftables is installed" 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" + - name: "3.4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | nftables" systemd: name: "{{ item }}" masked: true with_items: - - iptables - - ip6tables - when: item in ansible_facts.packages + - 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" + systemd: + name: "{{ item }}" + masked: true + with_items: + - 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 | {{ rhel9cis_firewall }} started and enabled" + systemd: + name: "{{ rhel9cis_firewall }}" + enabled: true + state: started - - name: "3.4.1.2 | PATCH | Ensure iptables-services not installed with firewalld | remove iptables-services pkg " - package: - name: iptables-services - state: absent - when: 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 diff --git a/tasks/section_3/cis_3.4.2.yml b/tasks/section_3/cis_3.4.2.yml new file mode 100644 index 0000000..7fc873e --- /dev/null +++ b/tasks/section_3/cis_3.4.2.yml @@ -0,0 +1,301 @@ +--- + +- 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" + 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" + command: firewall-cmd --set-default-zone="{{ rhel9cis_default_zone }}" + when: + - firewalld_zone_set.rc != 0 + when: + - rhel9cis_firewall == "firewalld" + - rhel9cis_rule_3_4_2_1 + tags: + - level1-server + - level1-workstation + - patch + - firewalld + - rule_3.4.2.1 + +- 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" + 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" + 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" + debug: + msg: + - "Warning!! You currently have no nft tables, please review your setup" + - 'Use the command "nft create table inet " 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" + set_fact: + control_number: "{{ control_number }} + [ 'rule_3.4.2.2' ]" + warn_count: "{{ warn_count | int + 1 }}" + 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" + 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_2 + tags: + - level1-server + - level1-workstation + - patch + - nftables + - rule_3.4.2.2 + +- name: "3.4.2.3 | PATCH | Ensure nftables base chains exist" + block: + - name: "3.4.2.3 | AUDIT | Ensure nftables base chains exist | Get current chains for INPUT" + shell: nft list ruleset | grep 'hook input' + changed_when: false + failed_when: false + register: rhel9cis_3_4_2_3_input_chains + + - name: "3.4.2.3 | AUDIT | Ensure nftables base chains exist | Get current chains for FORWARD" + shell: nft list ruleset | grep 'hook forward' + changed_when: false + failed_when: false + register: rhel9cis_3_4_2_3_forward_chains + + - name: "3.4.2.3 | 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_3_output_chains + + - name: "3.4.2.3 | AUDIT | Ensure nftables base chains exist | Display chains for review" + debug: + msg: + - "Below are the current INPUT chains" + - "{{ rhel9cis_3_4_2_3_input_chains.stdout_lines }}" + - "Below are the current FORWARD chains" + - "{{ rhel9cis_3_4_2_3_forward_chains.stdout_lines }}" + - "Below are teh current OUTPUT chains" + - "{{ rhel9cis_3_4_2_3_output_chains.stdout_lines }}" + when: not rhel9cis_nft_tables_autochaincreate + + - name: "3.4.2.3 | PATCH | Ensure nftables base chains exist | Create chains if needed" + shell: "{{ item }}" + failed_when: false + with_items: + - nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" input { type filter hook input priority 0 \; } + - nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" forward { type filter hook forward priority 0 \; } + - nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" output { type filter hook output priority 0 \; } + when: rhel9cis_nft_tables_autochaincreate + when: + - rhel9cis_firewall == "nftables" + - rhel9cis_rule_3_4_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" + 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" + 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" + 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" + 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" + 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" + 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_firewall_zone }}" + permanent: yes + immediate: yes + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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" + 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 + - patch + - nftables + - rule_3.4.2.6 + +- name: "3.4.2.7 | PATCH | Ensure nftables default deny firewall policy" + block: + - name: "3.4.2.7 | 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_7_inputpolicy + + - name: "3.4.2.7 | 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_7_forwardpolicy + + - name: "3.4.2.7 | 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_7_outputpolicy + + - name: "3.4.2.7 | 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_7_sshallowcheck + + - name: "3.4.2.7 | 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_7_sshallowcheck.stdout' + + - name: "3.4.2.7 | 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_7_inputpolicy.stdout' + + - name: "3.4.2.7 | 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_7_forwardpolicy.stdout' + + - name: "3.4.2.7 | 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_7_outputpolicy.stdout' + when: + - rhel9cis_firewall == "nftables" + - rhel9cis_rule_3_4_2_7 + tags: + - level1-server + - level1-workstation + - patch + - nftables + - rule_3.4.2.7