From 6a532db9c82db46e878ac21d37a68a84449a939c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:46:28 +0000 Subject: [PATCH 01/15] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/adrienverge/yamllint.git: v1.32.0 → v1.33.0](https://github.com/adrienverge/yamllint.git/compare/v1.32.0...v1.33.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a7d62bb9..16c7c744 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -61,6 +61,6 @@ repos: - ansible-core>=2.10.1 - repo: https://github.com/adrienverge/yamllint.git - rev: v1.32.0 # or higher tag + rev: v1.33.0 # or higher tag hooks: - id: yamllint From 90b4cbbd757a4c87a4038290c38b053c5818a701 Mon Sep 17 00:00:00 2001 From: Will Szumski Date: Wed, 15 Nov 2023 16:47:59 +0000 Subject: [PATCH 02/15] Fix inject_facts_as_vars Also enabled testing of this in CI to prevent regressions. See: https://docs.ansible.com/ansible/2.9/reference_appendices/config.html#inject-facts-as-vars Signed-off-by: Will Szumski --- tasks/prelim.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 154d0a8e..61108164 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -29,7 +29,7 @@ - name: "PRELIM | Section 1.1 | Create list of mount points" ansible.builtin.set_fact: - mount_names: "{{ ansible_mounts | map(attribute='mount') | list }}" + mount_names: "{{ ansible_facts.mounts | map(attribute='mount') | list }}" tags: - always From f163a4fdb10f111c9dded934d54fab87dea7dc54 Mon Sep 17 00:00:00 2001 From: Will Szumski Date: Wed, 15 Nov 2023 17:09:31 +0000 Subject: [PATCH 03/15] Test ANSIBLE_INJECT_FACT_VARS: false Signed-off-by: Will Szumski --- .github/workflows/devel_pipeline_validation.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml index 39af625a..134973f1 100644 --- a/.github/workflows/devel_pipeline_validation.yml +++ b/.github/workflows/devel_pipeline_validation.yml @@ -125,6 +125,7 @@ env: ANSIBLE_HOST_KEY_CHECKING: "false" ANSIBLE_DEPRECATION_WARNINGS: "false" + ANSIBLE_INJECT_FACT_VARS: "false" # Remove test system - User secrets to keep if necessary From f5a7ff00cfac70587534dcd86626cb537f294ee3 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 20 Nov 2023 09:01:03 +0000 Subject: [PATCH 04/15] added validate to sshd tasks Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.2.x.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tasks/section_5/cis_5.2.x.yml b/tasks/section_5/cis_5.2.x.yml index d0f297b5..ed219bf3 100644 --- a/tasks/section_5/cis_5.2.x.yml +++ b/tasks/section_5/cis_5.2.x.yml @@ -79,6 +79,7 @@ path: /etc/ssh/sshd_config regexp: '^AllowUsers|^#AllowUsers' line: 'AllowUsers {{ ubtu22cis_sshd.allow_users }}' + validate: 'sshd -t -f %s' notify: restart sshd when: "ubtu22cis_sshd['allow_users']| default('') | length > 0 " @@ -87,6 +88,7 @@ path: /etc/ssh/sshd_config regexp: '^AllowGroups|^#AllowGroups' line: 'AllowGroups {{ ubtu22cis_sshd.allow_groups }}' + validate: 'sshd -t -f %s' notify: restart sshd when: "ubtu22cis_sshd['allow_groups']| default('') | length > 0" @@ -95,6 +97,7 @@ path: /etc/ssh/sshd_config regexp: '^DenyUsers|^#DenyUsers' line: 'DenyUsers {{ ubtu22cis_sshd.deny_users }} ' + validate: 'sshd -t -f %s' notify: restart sshd when: "ubtu22cis_sshd['deny_users']| default('') | length > 0" @@ -103,6 +106,7 @@ path: /etc/ssh/sshd_config regexp: '^DenyGroups|^#DenyGroups' line: 'DenyGroups {{ ubtu22cis_sshd.deny_groups }}' + validate: 'sshd -t -f %s' notify: restart sshd when: "ubtu22cis_sshd['deny_groups']| default('') | length > 0" when: @@ -121,6 +125,7 @@ regexp: '^LogLevel|^#LogLevel' line: 'LogLevel {{ ubtu22cis_sshd.log_level }}' insertafter: '^# Logging' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_5 @@ -138,6 +143,7 @@ regexp: '^UsePAM|^#UsePAM' line: 'UsePAM yes' insertafter: '^# and ChallengeResponseAuthentication' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_6 @@ -155,6 +161,7 @@ path: /etc/ssh/sshd_config regexp: '^PermitRootLogin|^#PermitRootLogin' line: 'PermitRootLogin no' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_7 @@ -171,6 +178,7 @@ path: /etc/ssh/sshd_config regexp: '^HostbasedAuthentication|^#HostbasedAuthentication' line: 'HostbasedAuthentication no' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_8 @@ -188,6 +196,7 @@ regexp: '^PermitEmptyPasswords|^#PermitEmptyPasswords' line: 'PermitEmptyPasswords no' insertafter: '# To disable tunneled clear text passwords' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_9 @@ -204,6 +213,7 @@ path: /etc/ssh/sshd_config regexp: '^PermitUserEnvironment|^#PermitUserEnvironment' line: 'PermitUserEnvironment no' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_10 @@ -220,6 +230,7 @@ path: /etc/ssh/sshd_config regexp: '^IgnoreRhosts|^#IgnoreRhosts' line: 'IgnoreRhosts yes' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_11 @@ -236,6 +247,7 @@ path: /etc/ssh/sshd_config regexp: '^X11Forwarding|^#X11Forwarding' line: 'X11Forwarding no' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_12 @@ -253,6 +265,7 @@ regexp: '^Ciphers|^#Ciphers' line: "Ciphers {{ ubtu22cis_sshd.ciphers | join(',') }}" insertafter: '^# Ciphers and keying' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_13 @@ -270,6 +283,7 @@ regexp: '^MACs|^#MACs' line: "MACs {{ ubtu22cis_sshd.macs | join(',') }}" insertafter: '^# Ciphers and keying' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_14 @@ -287,6 +301,7 @@ regexp: '^KexAlgorithms|^#KexAlgorithms' line: "KexAlgorithms {{ ubtu22cis_sshd.kex_algorithms | join(',') }}" insertafter: '^# Ciphers and keying' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_15 @@ -303,6 +318,7 @@ path: /etc/ssh/sshd_config regexp: '^AllowTcpForwarding|^#AllowTcpForwarding' line: 'AllowTcpForwarding no' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_16 @@ -320,6 +336,7 @@ regexp: '^Banner|^#Banner' line: Banner /etc/issue.net insertafter: '^# no default banner path' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_17 @@ -337,6 +354,7 @@ regexp: '^MaxAuthTries|^#MaxAuthTries' line: 'MaxAuthTries {{ ubtu22cis_sshd.max_auth_tries }}' insertafter: '^# Authentication' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_18 @@ -353,6 +371,7 @@ path: /etc/ssh/sshd_config regexp: '^MaxStartups|^#MaxStartups' line: 'MaxStartups 10:30:60' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_19 @@ -370,6 +389,7 @@ regexp: '^MaxSessions|^#MaxSessions' line: 'MaxSessions {{ ubtu22cis_sshd.max_sessions }}' insertafter: '^# Authentication' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_20 @@ -387,6 +407,7 @@ regexp: '^LoginGraceTime|^#LoginGraceTime' line: 'LoginGraceTime {{ ubtu22cis_sshd.login_grace_time }}' insertafter: '^# Authentication' + validate: 'sshd -t -f %s' notify: restart sshd when: - ubtu22cis_rule_5_2_21 @@ -403,6 +424,7 @@ path: /etc/ssh/sshd_config regexp: "{{ item.regexp }}" line: "{{ item.line }}" + validate: 'sshd -t -f %s' with_items: - { regexp: '^ClientAliveInterval|^#ClientAliveInterval', line: 'ClientAliveInterval {{ ubtu22cis_sshd.client_alive_interval }}' } - { regexp: '^ClientAliveCountMax|^#ClientAliveCountMax', line: 'ClientAliveCountMax {{ ubtu22cis_sshd.client_alive_count_max }}' } From f5a2802645bb4de6774ec60069dcbde3e7f9504c Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 20 Nov 2023 11:13:08 +0000 Subject: [PATCH 05/15] Additional config for audit only Signed-off-by: Mark Bolwell --- defaults/main.yml | 111 ++++++++----------------------- tasks/LE_audit_setup.yml | 20 ++++-- tasks/audit_only.yml | 30 +++++++++ tasks/main.yml | 15 ++++- tasks/post_remediation_audit.yml | 62 ++++++++--------- tasks/pre_remediation_audit.yml | 94 +++++++++++++------------- vars/audit.yml | 52 +++++++++++++++ 7 files changed, 207 insertions(+), 177 deletions(-) create mode 100644 tasks/audit_only.yml create mode 100644 vars/audit.yml diff --git a/defaults/main.yml b/defaults/main.yml index ea0943dd..b2190033 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -52,48 +52,42 @@ ubtu22cis_uses_root: false ### Settings for associated Audit role using Goss ### -# Note that there are also variable regarding the retrieval -# and configuration of Goss and the audit role at the end -# of this file. - -## Audit setup -# Audits are carried out using Goss. This variable -# determines whether execution of the role prepares for auditing -# by installing the required binary. +########################################## +### Goss is required on the remote host ### +## Refer to vars/auditd.yml for any other settings ## + +# Allow audit to setup the requirements including installing git (if option chosen and downloading and adding goss binary to system) setup_audit: false -## How to retrieve audit binary -# Options are copy or download, using either the path -# provided in variable `audit_conf_copy` for copying or -# the url given in variable `audit_files_url` for downloading. + +# enable audits to run - this runs the audit and get the latest content +run_audit: false + +# Only run Audit do not remediate +audit_only: false +# As part of audit_only +# This will enable files to be copied back to control node +capture_audit_files: false +# Path to copy the files to will create dir structure +audit_capture_files_dir: /some/location to copy to on control node + +# How to retrieve audit binary +# Options are copy or download - detailed settings at the bottom of this file +# you will need to access to either github or the file already dowmloaded get_audit_binary_method: download -## How to retrieve the audit role -# The role for auditing is maintained separately. -# This variable specifies the method of how to get the audit role -# onto the system. The options are as follows: -# - git: clone from git repository as specified in variable `audit_file_git` in -# the version specified by variable `audit_git_version` -# - copy: copy from path as specified in variable `audit_conf_copy` -# - download: Download from url as specified in variable `audit_files_url` +# how to get audit files onto host options +# options are git/copy/get_url other e.g. if you wish to run from already downloaded conf audit_content: git -## Enable audits to run -# This variable governs whether the audit using the -# separately maintained audit role using Goss -# is carried out. -run_audit: false - -## Resource-intensive Tests -# This variable governs whether resource-intensive audit tests are carried out +# Run heavy tests - some tests can have more impact on a system enabling these can have greater impact on a system audit_run_heavy_tests: true + # This variable specifies the timeout (in ms) for audit commands that # take a very long time: if a command takes too long to complete, # it will be forcefully terminated after the specified duration. -audit_cmd_timeout: 60000 +audit_cmd_timeout: 120000 -### -### End Audit Settings for associcated Audit role using Goss -### +### End Goss enablements #### ## Running role under chroot # Tweak role to run in a chroot, such as in a kickstart %post script. @@ -1058,56 +1052,3 @@ ubtu22cis_sgid_adjust: false # permissions on dot files. # Possible values are `true` and `false`. ubtu22cis_dotperm_ansiblemanaged: true - -## -## Audit Configuration Settings -## - -# The settings below configure the retrieval and usage of the -# Goss-based audit role associated with this role, and the Goss-tool -# itself. - -## Audit binary settings -audit_bin_version: - release: v0.4.0 - checksum: 'sha256:9cb37863d3d25e2af80cb5cf55198c0c115b2477724153ba9afd0a2e544cb46e' -audit_bin_path: /usr/local/bin/ -audit_bin: "{{ audit_bin_path }}goss" -audit_format: json - -# if get_audit_binary_method == download change accordingly -audit_bin_url: "https://github.com/goss-org/goss/releases/download/{{ audit_bin_version.release }}/goss-linux-amd64" - -# if get_audit_binary_method - 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 -# e.g copy from ansible control node to remote host -audit_bin_copy_location: /some/accessible/path - -## Goss Audit Benchmark file -# managed by the control audit_content -# git -audit_file_git: "https://github.com/ansible-lockdown/{{ benchmark }}-Audit.git" -audit_git_version: "benchmark-{{ benchmark_version }}" - -# archive or copy: -audit_conf_copy: "some path to copy from" - -# get_url: -audit_files_url: "some url maybe s3?" - -## Goss configuration information -# Where the goss configs and outputs are stored -audit_out_dir: '/opt' -# Where the goss audit configuration will be stored -audit_conf_dir: "{{ audit_out_dir }}/{{ benchmark }}-Audit" - -# If changed these can affect other products -pre_audit_outfile: "{{ audit_out_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_pre_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" -post_audit_outfile: "{{ audit_out_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_post_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" - -## The following should not need changing -audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_facts.hostname }}.yml" -audit_results: | - The pre remediation results are: {{ pre_audit_summary }}. - The post remediation results are: {{ post_audit_summary }}. - Full breakdown can be found in {{ audit_out_dir }} diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index c8222b8e..56ffbd6c 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -1,22 +1,34 @@ --- +- name: Pre Audit Setup | Set audit package name + block: + - name: Pre Audit Setup | Set audit package name | 64bit + ansible.builtin.set_fact: + audit_pkg_arch_name: AMD64 + when: ansible_machine == "x86_64" + + - name: Pre Audit Setup | Set audit package name | ARM64 + ansible.builtin.set_fact: + audit_pkg_arch_name: ARM64 + when: ansible_machine == "arm64" + - name: Pre Audit Setup | Download audit binary ansible.builtin.get_url: - url: "{{ audit_bin_url }}" + url: "{{ audit_bin_url }}{{ audit_pkg_arch_name }}" dest: "{{ audit_bin }}" owner: root group: root - checksum: "{{ audit_bin_version.checksum }}" + checksum: "{{ audit_bin_version[audit_pkg_arch_name + '_checksum'] }}" mode: '0555' when: - get_audit_binary_method == 'download' -- name: Pre Audit Setup | copy audit binary +- name: Pre Audit Setup | Copy audit binary ansible.builtin.copy: src: "{{ audit_bin_copy_location }}" dest: "{{ audit_bin }}" + mode: '0555' owner: root group: root - mode: '0555' when: - get_audit_binary_method == 'copy' diff --git a/tasks/audit_only.yml b/tasks/audit_only.yml new file mode 100644 index 00000000..66402632 --- /dev/null +++ b/tasks/audit_only.yml @@ -0,0 +1,30 @@ +--- + +- name: Audit_Only | Create local Directories for hosts + ansible.builtin.file: + mode: '0755' + path: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}" + recurse: true + state: directory + when: capture_audit_files + delegate_to: localhost + become: false + +- name: Audit_only | Get audits from systems and put in group dir + ansible.builtin.fetch: + dest: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}/" + flat: true + mode: '0644' + src: "{{ pre_audit_outfile }}" + when: capture_audit_files + +- name: Audit_only | Show Audit Summary + when: + - audit_only + ansible.builtin.debug: + msg: "The Audit results are: {{ pre_audit_summary }}." + +- name: Audit_only | Stop Playbook Audit Only selected + when: + - audit_only + ansible.builtin.meta: end_play diff --git a/tasks/main.yml b/tasks/main.yml index 093f9961..1bba0280 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -131,11 +131,20 @@ tags: - always -- name: Run pre-remediation audit - ansible.builtin.import_tasks: - file: pre_remediation_audit.yml +- name: Include audit specific variables + ansible.builtin.include_vars: audit.yml when: + - run_audit or audit_only + - setup_audit + tags: + - setup_audit - run_audit + +- name: Include pre-remediation audit tasks + ansible.builtin.import_tasks: pre_remediation_audit.yml + when: + - run_audit or audit_only + - setup_audit tags: - run_audit diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index b696092c..eb01bc75 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -1,18 +1,28 @@ --- +- name: Post Audit | Run post_remediation {{ benchmark }} audit + ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }}" + changed_when: true + environment: + AUDIT_BIN: "{{ audit_bin }}" + AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" + AUDIT_FILE: goss.yml + +- name: Post Audit | ensure audit files readable by users + ansible.builtin.file: + path: "{{ item }}" + mode: '0644' + state: file + loop: + - "{{ post_audit_outfile }}" + - "{{ pre_audit_outfile }}" + - name: Post Audit | Capture audit data if json format + when: + - audit_format == "json" block: - - - name: "Post Audit | Run post_remediation {{ benchmark }} audit" - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }}" - changed_when: true - environment: - AUDIT_BIN: "{{ audit_bin }}" - AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" - AUDIT_FILE: "goss.yml" - - - name: "Capture data {{ post_audit_outfile }}" - ansible.builtin.shell: "cat {{ post_audit_outfile }}" + - name: capture data {{ post_audit_outfile }} + ansible.builtin.shell: cat {{ post_audit_outfile }} register: post_audit changed_when: false @@ -20,37 +30,17 @@ ansible.builtin.set_fact: post_audit_summary: "{{ post_audit.stdout | from_json | json_query(summary) }}" vars: - summary: 'summary."summary-line"' - when: - - audit_format == "json" + summary: summary."summary-line" - name: Post Audit | Capture audit data if documentation format + when: + - audit_format == "documentation" block: - - - name: "Post Audit | Run post_remediation {{ benchmark }} audit" - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }} -f documentation" - changed_when: true - environment: - AUDIT_BIN: "{{ audit_bin }}" - AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" - AUDIT_FILE: "goss.yml" - - - name: "Post Audit | Capture data {{ post_audit_outfile }}" - ansible.builtin.shell: "tail -2 {{ post_audit_outfile }}" + - name: Post Audit | capture data {{ post_audit_outfile }} + ansible.builtin.shell: tail -2 {{ post_audit_outfile }} register: post_audit changed_when: false - name: Post Audit | Capture post-audit result ansible.builtin.set_fact: post_audit_summary: "{{ post_audit.stdout_lines }}" - when: - - audit_format == "documentation" - -- name: Post Audit | Ensure audit files readable by users - ansible.builtin.file: - path: "{{ item }}" - mode: '0644' - state: file - loop: - - "{{ post_audit_outfile }}" - - "{{ pre_audit_outfile }}" diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index 290170d6..258171a1 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -1,58 +1,58 @@ --- -- name: Audit Binary Setup | Setup the LE audit - ansible.builtin.include_tasks: - file: LE_audit_setup.yml +- name: Pre Audit Setup | Setup the LE audit when: - setup_audit tags: - setup_audit + ansible.builtin.include_tasks: LE_audit_setup.yml -- name: "Pre Audit Setup | Ensure {{ audit_conf_dir }} exists" +- name: Pre Audit Setup | Ensure {{ audit_conf_dir }} exists ansible.builtin.file: path: "{{ audit_conf_dir }}" state: directory mode: '0755' - name: Pre Audit Setup | If using git for content set up + when: + - audit_content == 'git' block: - name: Pre Audit Setup | Install git ansible.builtin.package: name: git state: present - when: "'git' not in ansible_facts.packages" - - name: Pre Audit Setup | retrieve audit content files from git + - name: Pre Audit Setup | Retrieve audit content files from git ansible.builtin.git: repo: "{{ audit_file_git }}" dest: "{{ audit_conf_dir }}" version: "{{ audit_git_version }}" - when: - - audit_content == 'git' -- name: Pre Audit Setup | copy to audit content files to server +- name: Pre Audit Setup | Copy to audit content files to server + when: + - audit_content == 'copy' ansible.builtin.copy: src: "{{ audit_local_copy }}" dest: "{{ audit_conf_dest }}" mode: preserve - when: - - audit_content == 'copy' -- name: Pre Audit Setup | unarchive audit content files on server +- name: Pre Audit Setup | Unarchive audit content files on server + when: + - audit_content == 'archived' ansible.builtin.unarchive: src: "{{ audit_conf_copy }}" dest: "{{ audit_conf_dir }}" - when: - - audit_content == 'archived' -- name: Pre Audit Setup | get audit content from url +- name: Pre Audit Setup | Get audit content from url + when: + - audit_content == 'get_url' ansible.builtin.get_url: url: "{{ audit_files_url }}" dest: "{{ audit_conf_dir }}" - when: - - audit_content == 'get_url' - name: Pre Audit Setup | Check Goss is available + when: + - run_audit block: - name: Pre Audit Setup | Check for goss file ansible.builtin.stat: @@ -60,34 +60,36 @@ register: goss_available - name: Pre Audit Setup | If audit ensure goss is available + when: + - not goss_available.stat.exists ansible.builtin.assert: - that: goss_available.stat.exists msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}" - when: - - run_audit - name: Pre Audit Setup | Copy ansible default vars values to test audit + tags: + - goss_template + - run_audit + when: + - run_audit ansible.builtin.template: src: ansible_vars_goss.yml.j2 dest: "{{ audit_vars_path }}" mode: '0600' - when: - - run_audit - tags: - - goss_template + +- name: Pre Audit | Run pre_remediation {{ benchmark }} audit + ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }}" + changed_when: true + environment: + AUDIT_BIN: "{{ audit_bin }}" + AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" + AUDIT_FILE: goss.yml - name: Pre Audit | Capture audit data if json format + when: + - audit_format == "json" block: - - name: "Pre Audit | Run pre_remediation {{ benchmark }} audit" - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }}" - changed_when: true - environment: - AUDIT_BIN: "{{ audit_bin }}" - AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" - AUDIT_FILE: "goss.yml" - - - name: "capture data {{ pre_audit_outfile }}" - ansible.builtin.shell: "cat {{ pre_audit_outfile }}" + - name: capture data {{ pre_audit_outfile }} + ansible.builtin.shell: cat {{ pre_audit_outfile }} register: pre_audit changed_when: false @@ -95,28 +97,22 @@ ansible.builtin.set_fact: pre_audit_summary: "{{ pre_audit.stdout | from_json | json_query(summary) }}" vars: - summary: 'summary."summary-line"' - when: - - audit_format == "json" + summary: summary."summary-line" - name: Pre Audit | Capture audit data if documentation format + when: + - audit_format == "documentation" block: - - - name: "Pre Audit | Run pre_remediation {{ benchmark }} audit" - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }} -f documentation" - changed_when: true - environment: - AUDIT_BIN: "{{ audit_bin }}" - AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" - AUDIT_FILE: "goss.yml" - - - name: "Pre Audit | capture data {{ pre_audit_outfile }} | documentation format" - ansible.builtin.shell: "tail -2 {{ pre_audit_outfile }}" + - name: Pre Audit | capture data {{ pre_audit_outfile }} | documentation format + ansible.builtin.shell: tail -2 {{ pre_audit_outfile }} register: pre_audit changed_when: false - name: Pre Audit | Capture pre-audit result | documentation format ansible.builtin.set_fact: pre_audit_summary: "{{ pre_audit.stdout_lines }}" + +- name: Audit_Only | Run Audit Only when: - - audit_format == "documentation" + - audit_only + ansible.builtin.import_tasks: audit_only.yml diff --git a/vars/audit.yml b/vars/audit.yml new file mode 100644 index 00000000..97d9b09b --- /dev/null +++ b/vars/audit.yml @@ -0,0 +1,52 @@ +--- + +#### Audit Configuration Settings #### + +# Timeout for those cmds that take longer to run where timeout set +audit_cmd_timeout: 120000 + +# if get_audit_binary_method == download change accordingly +audit_bin_url: "https://github.com/goss-org/goss/releases/download/{{ audit_bin_version.release }}/goss-linux-" + +## if get_audit_binary_method - 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 +## e.g copy from ansible control node to remote host +audit_bin_copy_location: /some/accessible/path + +### Goss Audit Benchmark file ### +## managed by the control audit_content +# git +audit_file_git: "https://github.com/ansible-lockdown/{{ benchmark }}-Audit.git" +audit_git_version: "benchmark-{{ benchmark_version }}" + +# archive or copy: +audit_conf_copy: "some path to copy from" + +# get_url: +audit_files_url: "some url maybe s3?" + +## Goss configuration information +# Where the goss configs and outputs are stored +audit_out_dir: '/opt' +# Where the goss audit configuration will be stored +audit_conf_dir: "{{ audit_out_dir }}/{{ benchmark }}-Audit" + +# If changed these can affect other products +pre_audit_outfile: "{{ audit_out_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_pre_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" +post_audit_outfile: "{{ audit_out_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_post_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" + +## The following should not need changing + +### Audit binary settings ### +audit_bin_version: + release: v0.4.4 + AMD64_checksum: 'sha256:1c4f54b22fde9d4d5687939abc2606b0660a5d14a98afcd09b04b793d69acdc5' +audit_bin_path: /usr/local/bin/ +audit_bin: "{{ audit_bin_path }}goss" +audit_format: json + +audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_facts.hostname }}.yml" +audit_results: | + The pre remediation results are: {{ pre_audit_summary }}. + The post remediation results are: {{ post_audit_summary }}. + Full breakdown can be found in {{ audit_out_dir }} From b03f94e768a95a0c3559a2f7bb1208d07bda5645 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 20 Nov 2023 14:08:31 +0000 Subject: [PATCH 06/15] updated var naming Signed-off-by: Mark Bolwell --- defaults/main.yml | 2 +- tasks/audit_only.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index b2190033..fab20b6d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -66,7 +66,7 @@ run_audit: false audit_only: false # As part of audit_only # This will enable files to be copied back to control node -capture_audit_files: false +fetch_audit_files: false # Path to copy the files to will create dir structure audit_capture_files_dir: /some/location to copy to on control node diff --git a/tasks/audit_only.yml b/tasks/audit_only.yml index 66402632..864f5bbe 100644 --- a/tasks/audit_only.yml +++ b/tasks/audit_only.yml @@ -6,7 +6,7 @@ path: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}" recurse: true state: directory - when: capture_audit_files + when: fetch_audit_files delegate_to: localhost become: false @@ -16,7 +16,7 @@ flat: true mode: '0644' src: "{{ pre_audit_outfile }}" - when: capture_audit_files + when: fetch_audit_files - name: Audit_only | Show Audit Summary when: From c60575a53003338e382f03fb23ec34e31972770f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 20 Nov 2023 16:32:32 +0000 Subject: [PATCH 07/15] removed the extra facts as all are captured Signed-off-by: Mark Bolwell --- tasks/main.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index 1bba0280..9124d732 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,17 +1,5 @@ --- -- name: Gather distribution info - # we need: - # - hardware for ansible_facts.mounts - # - platform for ansible_architecture (ansible internal) - # - virtual for ansible_facts.virtualization_type - ansible.builtin.setup: - gather_subset: distribution,hardware,platform,virtual,!all,!min - when: - - ansible_facts.distribution is not defined - tags: - - always - - name: Check OS version and family ansible.builtin.fail: msg: "This role can only be run against Ubuntu 22. {{ ansible_facts.distribution }} {{ ansible_facts.distribution_major_version }} is not supported." From f1d2565aa749b8f16d3fcd3b9c7c7cafe20e2427 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 20 Nov 2023 16:58:44 +0000 Subject: [PATCH 08/15] added debug for test Signed-off-by: Mark Bolwell --- tasks/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasks/main.yml b/tasks/main.yml index 9124d732..cb4f0e3e 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,5 +1,9 @@ --- +- name: debug ansible_machine + ansible.builtin.debug: + var: ansible_machine + - name: Check OS version and family ansible.builtin.fail: msg: "This role can only be run against Ubuntu 22. {{ ansible_facts.distribution }} {{ ansible_facts.distribution_major_version }} is not supported." From d4a47789e01524785b72ce9248f2e931dcf81b1e Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 20 Nov 2023 17:05:53 +0000 Subject: [PATCH 09/15] added non injected facts Signed-off-by: Mark Bolwell --- tasks/LE_audit_setup.yml | 4 ++-- tasks/main.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index 56ffbd6c..7ef94b4a 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -5,12 +5,12 @@ - name: Pre Audit Setup | Set audit package name | 64bit ansible.builtin.set_fact: audit_pkg_arch_name: AMD64 - when: ansible_machine == "x86_64" + when: ansible_facts.machine == "x86_64" - name: Pre Audit Setup | Set audit package name | ARM64 ansible.builtin.set_fact: audit_pkg_arch_name: ARM64 - when: ansible_machine == "arm64" + when: ansible_facts.machine == "arm64" - name: Pre Audit Setup | Download audit binary ansible.builtin.get_url: diff --git a/tasks/main.yml b/tasks/main.yml index cb4f0e3e..94db9259 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -2,7 +2,7 @@ - name: debug ansible_machine ansible.builtin.debug: - var: ansible_machine + var: ansible_facts.machine - name: Check OS version and family ansible.builtin.fail: From 2bfa448fc2e234174509b3a624624ccc239f7982 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Mon, 20 Nov 2023 17:11:23 +0000 Subject: [PATCH 10/15] removed debug Signed-off-by: Mark Bolwell --- tasks/main.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index 94db9259..9124d732 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,9 +1,5 @@ --- -- name: debug ansible_machine - ansible.builtin.debug: - var: ansible_facts.machine - - name: Check OS version and family ansible.builtin.fail: msg: "This role can only be run against Ubuntu 22. {{ ansible_facts.distribution }} {{ ansible_facts.distribution_major_version }} is not supported." From b3401b0d74fc600dd9e10b4dbdbcbd0311dd6fc4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 17:35:59 +0000 Subject: [PATCH 11/15] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/gitleaks/gitleaks: v8.18.0 → v8.18.1](https://github.com/gitleaks/gitleaks/compare/v8.18.0...v8.18.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 16c7c744..54e9449b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: args: [ '--baseline', '.config/.secrets.baseline' ] - repo: https://github.com/gitleaks/gitleaks - rev: v8.18.0 + rev: v8.18.1 hooks: - id: gitleaks args: ['--baseline-path', '.config/.gitleaks-report.json'] From 38b743beac759da5ba835e49b25474cdec6ca8eb Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 21 Nov 2023 09:44:18 +0000 Subject: [PATCH 12/15] tidy up variable locations Signed-off-by: Mark Bolwell --- defaults/main.yml | 11 +++++++++++ vars/audit.yml | 11 ----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index fab20b6d..878534cb 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -75,10 +75,21 @@ audit_capture_files_dir: /some/location to copy to on control node # you will need to access to either github or the file already dowmloaded get_audit_binary_method: download +## if get_audit_binary_method - 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 +## e.g copy from ansible control node to remote host +audit_bin_copy_location: /some/accessible/path + # how to get audit files onto host options # options are git/copy/get_url other e.g. if you wish to run from already downloaded conf audit_content: git +# archive or copy: +audit_conf_copy: "some path to copy from" + +# get_url: +audit_files_url: "some url maybe s3?" + # Run heavy tests - some tests can have more impact on a system enabling these can have greater impact on a system audit_run_heavy_tests: true diff --git a/vars/audit.yml b/vars/audit.yml index 97d9b09b..d6f50301 100644 --- a/vars/audit.yml +++ b/vars/audit.yml @@ -8,23 +8,12 @@ audit_cmd_timeout: 120000 # if get_audit_binary_method == download change accordingly audit_bin_url: "https://github.com/goss-org/goss/releases/download/{{ audit_bin_version.release }}/goss-linux-" -## if get_audit_binary_method - 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 -## e.g copy from ansible control node to remote host -audit_bin_copy_location: /some/accessible/path - ### Goss Audit Benchmark file ### ## managed by the control audit_content # git audit_file_git: "https://github.com/ansible-lockdown/{{ benchmark }}-Audit.git" audit_git_version: "benchmark-{{ benchmark_version }}" -# archive or copy: -audit_conf_copy: "some path to copy from" - -# get_url: -audit_files_url: "some url maybe s3?" - ## Goss configuration information # Where the goss configs and outputs are stored audit_out_dir: '/opt' From 229332140fb791faba38cf10c2fb8cb0ebf115c0 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 21 Nov 2023 10:01:26 +0000 Subject: [PATCH 13/15] updated Signed-off-by: Mark Bolwell --- Changelog.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Changelog.md b/Changelog.md index dd64ef53..dbd4df7d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,13 @@ ## Based on CIS V1.0.0 +### 1.0.8 + +- updated goss binary to 0.4.4 +- moved majority of audit variables to vars/audit.yml +- new function to enable audit_only using remediation +- removed some dupes in audit config + ### 1.0.7 Huge thanks to the discord community From f716f32a6dbe788a80a02326c00403f375cefe6b Mon Sep 17 00:00:00 2001 From: Jason Hendry Date: Tue, 14 Nov 2023 16:31:45 +1100 Subject: [PATCH 14/15] fix: #172 checks if ipv6.disable is present in GRUB_CMDLINE_LINUX before appending it to prevent duplication Signed-off-by: Jason Hendry --- tasks/section_3/cis_3.1.x.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index a708647b..2d9dcd94 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -11,13 +11,23 @@ register: ipv6disable_replaced notify: Grub update + - name: "3.1.1 | PATCH | Ensure system is checked to determine if IPv6 is enabled | Check grub cmdline linux" + ansible.builtin.shell: 'cat /etc/default/grub | grep ^GRUB_CMDLINE_LINUX' + changed_when: false + failed_when: false + check_mode: false + register: ubtu22cis_3_1_1_GRUB_CMDLINE_LINUX + when: ubtu22cis_ipv6_disable == 'grub' + - name: "3.1.1 | PATCH | Ensure system is checked to determine if IPv6 is enabled | Insert ipv6.disable if it doesn't exist" ansible.builtin.lineinfile: path: /etc/default/grub regexp: '^(GRUB_CMDLINE_LINUX=".*)"$' line: '\1 ipv6.disable=1"' backrefs: true - when: ipv6disable_replaced is not changed + when: + - ipv6disable_replaced is not changed + - "'ipv6.disable' not in ubtu22cis_3_1_1_GRUB_CMDLINE_LINUX.stdout" notify: Grub update - name: "3.1.1 | PATCH | Ensure system is checked to determine if IPv6 is enabled | Remove net.ipv6.conf.all.disable_ipv6" From 4e6755020986df30f554c8fcdea1eed63a4e70da Mon Sep 17 00:00:00 2001 From: Jason Hendry Date: Wed, 22 Nov 2023 13:52:22 +1100 Subject: [PATCH 15/15] style: fix yamllint and align command and variable name to other tasks that do the same thing. Signed-off-by: Jason Hendry --- tasks/section_3/cis_3.1.x.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index 2d9dcd94..73021427 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -12,11 +12,11 @@ notify: Grub update - name: "3.1.1 | PATCH | Ensure system is checked to determine if IPv6 is enabled | Check grub cmdline linux" - ansible.builtin.shell: 'cat /etc/default/grub | grep ^GRUB_CMDLINE_LINUX' + ansible.builtin.shell: grep "GRUB_CMDLINE_LINUX=" /etc/default/grub | cut -f2 -d'"' changed_when: false failed_when: false check_mode: false - register: ubtu22cis_3_1_1_GRUB_CMDLINE_LINUX + register: ubtu22cis_3_1_1_cmdline_settings when: ubtu22cis_ipv6_disable == 'grub' - name: "3.1.1 | PATCH | Ensure system is checked to determine if IPv6 is enabled | Insert ipv6.disable if it doesn't exist" @@ -26,8 +26,8 @@ line: '\1 ipv6.disable=1"' backrefs: true when: - - ipv6disable_replaced is not changed - - "'ipv6.disable' not in ubtu22cis_3_1_1_GRUB_CMDLINE_LINUX.stdout" + - ipv6disable_replaced is not changed + - "'ipv6.disable' not in ubtu22cis_3_1_1_cmdline_settings.stdout" notify: Grub update - name: "3.1.1 | PATCH | Ensure system is checked to determine if IPv6 is enabled | Remove net.ipv6.conf.all.disable_ipv6"