Improve handling of rsyslog files permissions fix wildcard path
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
Start a new ephemeral environment with changes proposed in this pull request:
rhel8 (from CTF) Environment (using Fedora as testing environment)
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:
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.
@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 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.

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: 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.