content icon indicating copy to clipboard operation
content copied to clipboard

Improve handling of rsyslog files permissions fix wildcard path

Open yuumasato opened this issue 3 years ago • 5 comments

Description:

  • Resubmitting #8726 with:
    • 2 more test scenarios for hidden and missing config files.
    • A small change in OVAL to ignore hidden config files.

Rationale:

  • Should fix https://bugzilla.redhat.com/show_bug.cgi?id=2075384

yuumasato avatar Aug 10 '22 14:08 yuumasato

Start a new ephemeral environment with changes proposed in this pull request:

rhel8 (from CTF) Environment (using Fedora as testing environment) Open in Gitpod

Fedora Testing Environment Open in Gitpod

Oracle Linux 8 Environment Open in Gitpod

github-actions[bot] avatar Aug 10 '22 14:08 github-actions[bot]

This datastream diff is auto generated by the check Compare DS/Generate Diff

Click here to see the full diff
bash remediation for rule 'xccdf_org.ssgproject.content_rule_rsyslog_files_permissions' differs:
--- old datastream
+++ new datastream
@@ -6,12 +6,15 @@
 RSYSLOG_ETC_CONFIG="/etc/rsyslog.conf"
 # * And also the log file paths listed after rsyslog's $IncludeConfig directive
 # (store the result into array for the case there's shell glob used as value of IncludeConfig)
-readarray -t RSYSLOG_INCLUDE_CONFIG < <(grep -e "\$IncludeConfig[[:space:]]\+[^[:space:];]\+" /etc/rsyslog.conf | cut -d ' ' -f 2)
-readarray -t RSYSLOG_INCLUDE < <(awk '/)/{f=0} /include\(/{f=1} f{nf=gensub("^(include\\(|\\s*)file=\"(\\S+)\".*","\\2",1); if($0!=nf){print nf}}' /etc/rsyslog.conf)
+readarray -t OLD_INC < <(grep -e "\$IncludeConfig[[:space:]]\+[^[:space:];]\+" /etc/rsyslog.conf | cut -d ' ' -f 2)
+readarray -t RSYSLOG_INCLUDE_CONFIG < <(for INCPATH in "${OLD_INC[@]}"; do eval printf '%s\\n' "${INCPATH}"; done)
+readarray -t NEW_INC < <(awk '/)/{f=0} /include\(/{f=1} f{nf=gensub("^(include\\(|\\s*)file=\"(\\S+)\".*","\\2",1); if($0!=nf){print nf}}' /etc/rsyslog.conf)
+readarray -t RSYSLOG_INCLUDE < <(for INCPATH in "${NEW_INC[@]}"; do eval printf '%s\\n' "${INCPATH}"; done)
 
 # Declare an array to hold the final list of different log file paths
 declare -a LOG_FILE_PATHS
 
+# Array to hold all rsyslog config entries
 RSYSLOG_CONFIGS=()
 RSYSLOG_CONFIGS=("${RSYSLOG_ETC_CONFIG}" "${RSYSLOG_INCLUDE_CONFIG[@]}" "${RSYSLOG_INCLUDE[@]}")
 
@@ -19,15 +22,26 @@
 # RSYSLOG_CONFIGS may contain globs such as 
 # /etc/rsyslog.d/*.conf /etc/rsyslog.d/*.frule
 # So, loop over the entries in RSYSLOG_CONFIGS and use find to get the list of included files.
-RSYSLOG_FILES=()
+RSYSLOG_CONFIG_FILES=()
 for ENTRY in "${RSYSLOG_CONFIGS[@]}"
 do
- mapfile -t FINDOUT < <(find "$(dirname "${ENTRY}")" -maxdepth 1 -name "$(basename "${ENTRY}")")
- RSYSLOG_FILES+=("${FINDOUT[@]}")
+ # If directory, rsyslog will search for config files in recursively.
+ # However, files in hidden sub-directories or hidden files will be ignored.
+ if [ -d "${ENTRY}" ]
+ then
+ readarray -t FINDOUT < <(find "${ENTRY}" -not -path '*/.*' -type f)
+ RSYSLOG_CONFIG_FILES+=("${FINDOUT[@]}")
+ elif [ -f "${ENTRY}" ]
+ then
+ RSYSLOG_CONFIG_FILES+=("${ENTRY}")
+ else
+ echo "Invalid include object: ${ENTRY}"
+ fi
 done
 
-# Check file and fix if needed.
-for LOG_FILE in "${RSYSLOG_FILES[@]}"
+# Browse each file selected above as containing paths of log files
+# ('/etc/rsyslog.conf' and '/etc/rsyslog.d/*.conf' in the default configuration)
+for LOG_FILE in "${RSYSLOG_CONFIG_FILES[@]}"
 do
 # From each of these files extract just particular log file path(s), thus:
 # * Ignore lines starting with space (' '), comment ('#"), or variable syntax ('$') characters,
@@ -44,7 +58,7 @@
 then
 NORMALIZED_CONFIG_FILE_LINES=$(sed -e "/^[#|$]/d" "${LOG_FILE}")
 LINES_WITH_PATHS=$(grep '[^/]*\s\+\S*/\S\+$' <<< "${NORMALIZED_CONFIG_FILE_LINES}")
- FILTERED_PATHS=$(sed -e 's/[^\/]*[[:space:]]*\([^:;[:space:]]*\)/\1/g' <<< "${LINES_WITH_PATHS}")
+ FILTERED_PATHS=$(awk '{if(NF>=2&&($2~/^\//||$2~/^-\//)){sub(/^-\//,"/",$2);print $2}}' <<< "${LINES_WITH_PATHS}")
 CLEANED_PATHS=$(sed -e "s/[\"')]//g; /\\/etc.*\.conf/d; /\\/dev\\//d" <<< "${FILTERED_PATHS}")
 MATCHED_ITEMS=$(sed -e "/^$/d" <<< "${CLEANED_PATHS}")
 # Since above sed command might return more than one item (delimited by newline), split the particular

ansible remediation for rule 'xccdf_org.ssgproject.content_rule_rsyslog_files_permissions' differs:
--- old datastream
+++ new datastream
@@ -20,7 +20,7 @@
 shell: |
 set -o pipefail
 grep -e '$IncludeConfig' {{ rsyslog_etc_config }} | cut -d ' ' -f 2 || true
- register: include_config_output
+ register: rsyslog_old_inc
 changed_when: false
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
@@ -40,7 +40,7 @@
 shell: |
 set -o pipefail
 grep -oP '^\s*include\s*\(\s*file.*' {{ rsyslog_etc_config }} |cut -d"\"" -f 2 || true
- register: include_files_output
+ register: rsyslog_new_inc
 changed_when: false
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
@@ -56,11 +56,32 @@
 - no_reboot_needed
 - rsyslog_files_permissions
 
+- name: Expand glob expressions
+ shell: |
+ set -o pipefail
+ eval printf '%s\\n' {{ item }}
+ register: include_config_output
+ loop: '{{ rsyslog_old_inc.stdout_lines + rsyslog_new_inc.stdout_lines }}'
+ when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
+ tags:
+ - CCE-80862-6
+ - NIST-800-53-AC-6(1)
+ - NIST-800-53-CM-6(a)
+ - PCI-DSS-Req-10.5.1
+ - PCI-DSS-Req-10.5.2
+ - configure_strategy
+ - low_complexity
+ - medium_disruption
+ - medium_severity
+ - no_reboot_needed
+ - rsyslog_files_permissions
+
 - name: List all config files
- shell: find "$(dirname "{{ item }}" )" -maxdepth 1 -name "$(basename "{{ item }}")"
- loop: '{{ include_config_output.stdout_lines + include_files_output.stdout_lines
+ shell: find {{ item }} -not -path "*/.*" -type f
+ loop: '{{ include_config_output.results|map(attribute=''stdout_lines'')|list|flatten
 }}'
 register: rsyslog_config_files
+ failed_when: false
 changed_when: false
 when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:

github-actions[bot] avatar Aug 10 '22 14:08 github-actions[bot]

Code Climate has analyzed commit e0e31fef and detected 0 issues on this pull request.

The test coverage on the diff in this pull request is 100.0% (50% is the threshold).

This pull request will bring the total coverage in the repository to 42.7% (0.0% change).

View more on Code Climate.

qlty-cloud-legacy[bot] avatar Aug 10 '22 14:08 qlty-cloud-legacy[bot]

@yuumasato Meanwhile this rule got an Ansible remediation which is not present in the PR's branch which probably causes the Automatus fail. Can you try to rebase this PR on the top of the latest upstream master branch and run automatus with --remediate-using ansible?

jan-cerny avatar Aug 10 '22 15:08 jan-cerny

@jan-cerny All test scenarios pass for me, on Bash and Ansible.

With the last commit, I think it s worth to mention that the Bash remediation prints some messages when running test scenario include_config_syntax_perms_0601.fail.sh.

Screenshot from 2022-08-10 22-00-55

This is happens because the globs don't evaluate to any file, and while in the Bash remediation we print a message, in the Ansible we simply ignore it.

yuumasato avatar Aug 10 '22 20:08 yuumasato

@yuumasato: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-aws-rhcos4-high 37e98ed3a86a0e56543132752c62982ff01cd3d9 link true /test e2e-aws-rhcos4-high

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

openshift-ci[bot] avatar Aug 10 '22 22:08 openshift-ci[bot]