Store plain login banner text in XCCDF Value#14371
Open
jan-cerny wants to merge 8 commits intoComplianceAsCode:masterfrom
Open
Store plain login banner text in XCCDF Value#14371jan-cerny wants to merge 8 commits intoComplianceAsCode:masterfrom
jan-cerny wants to merge 8 commits intoComplianceAsCode:masterfrom
Conversation
|
Skipping CI for Draft Pull Request. |
6193d93 to
3092331
Compare
|
This datastream diff is auto generated by the check Click here to see the full diffbash remediation for rule 'xccdf_org.ssgproject.content_rule_banner_etc_issue' differs.
--- xccdf_org.ssgproject.content_rule_banner_etc_issue
+++ xccdf_org.ssgproject.content_rule_banner_etc_issue
@@ -1,8 +1,26 @@
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel-core; then
-login_banner_contents=$(echo "" | sed 's/\\n/\n/g')
-echo "$login_banner_contents" > /etc/issue
+read -r -d '' login_banner_text <<'EOF' || true
+
+EOF
+
+# Multiple regexes transform the banner regex into a usable banner
+# 0 - Remove anchors around the banner text
+login_banner_text=$(echo "$login_banner_text" | sed 's/^\^\(.*\)\$$/\1/g')
+# 1 - Keep only the first banners if there are multiple
+# (dod_banners contains the long and short banner)
+login_banner_text=$(echo "$login_banner_text" | sed 's/^(\(.*\.\)|.*)$/\1/g')
+# 2 - Add spaces ' '. (Transforms regex for "space or newline" into a " ")
+login_banner_text=$(echo "$login_banner_text" | sed 's/\[\\s\\n\]+/ /g')
+# 3 - Adds newlines. (Transforms "(?:\[\\n\]+|(?:\\n)+)" into "\n")
+login_banner_text=$(echo "$login_banner_text" | sed 's/(?:\[\\n\]+|(?:\\\\n)+)/\n/g')
+# 4 - Remove any leftover backslash. (From any parenthesis in the banner, for example).
+login_banner_text=$(echo "$login_banner_text" | sed 's/\\//g')
+formatted=$(echo "$login_banner_text" | fold -sw 80)
+cat <<EOF >/etc/issue
+$formatted
+EOF
else
>&2 echo 'Remediation is not applicable, nothing was done'
ansible remediation for rule 'xccdf_org.ssgproject.content_rule_banner_etc_issue' differs.
--- xccdf_org.ssgproject.content_rule_banner_etc_issue
+++ xccdf_org.ssgproject.content_rule_banner_etc_issue
@@ -13,18 +13,18 @@
- medium_severity
- no_reboot_needed
- unknown_strategy
-- name: XCCDF Value login_banner_contents # promote to variable
+- name: XCCDF Value login_banner_text # promote to variable
set_fact:
- login_banner_contents: !!str
+ login_banner_text: !!str
tags:
- always
- name: Modify the System Login Banner - Ensure Correct Banner
ansible.builtin.copy:
dest: /etc/issue
- content: |
- {{ login_banner_contents | replace('\n', '
- ') }}
+ content: '{{ login_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$",
+ "\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)",
+ "\n") | regex_replace("\\", "") | wordwrap() }}'
when: '"kernel-core" in ansible_facts.packages'
tags:
- CCE-80763-6
bash remediation for rule 'xccdf_org.ssgproject.content_rule_banner_etc_issue_net' differs.
--- xccdf_org.ssgproject.content_rule_banner_etc_issue_net
+++ xccdf_org.ssgproject.content_rule_banner_etc_issue_net
@@ -1,8 +1,26 @@
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel-core; then
-remote_login_banner_contents=$(echo "" | sed 's/\\n/\n/g')
-echo "$remote_login_banner_contents" > /etc/issue.net
+remote_login_banner_text=''
+
+
+# Multiple regexes transform the banner regex into a usable banner
+# 0 - Remove anchors around the banner text
+remote_login_banner_text=$(echo "$remote_login_banner_text" | sed 's/^\^\(.*\)\$$/\1/g')
+# 1 - Keep only the first banners if there are multiple
+# (dod_banners contains the long and short banner)
+remote_login_banner_text=$(echo "$remote_login_banner_text" | sed 's/^(\(.*\.\)|.*)$/\1/g')
+# 2 - Add spaces ' '. (Transforms regex for "space or newline" into a " ")
+remote_login_banner_text=$(echo "$remote_login_banner_text" | sed 's/\[\\s\\n\]+/ /g')
+# 3 - Adds newlines. (Transforms "(?:\[\\n\]+|(?:\\n)+)" into "\n")
+remote_login_banner_text=$(echo "$remote_login_banner_text" | sed 's/(?:\[\\n\]+|(?:\\\\n)+)/\n/g')
+# 4 - Remove any leftover backslash. (From any parenthesis in the banner, for example).
+remote_login_banner_text=$(echo "$remote_login_banner_text" | sed 's/\\//g')
+formatted=$(echo "$remote_login_banner_text" | fold -sw 80)
+
+cat <<EOF >/etc/issue.net
+$formatted
+EOF
else
>&2 echo 'Remediation is not applicable, nothing was done'
ansible remediation for rule 'xccdf_org.ssgproject.content_rule_banner_etc_issue_net' differs.
--- xccdf_org.ssgproject.content_rule_banner_etc_issue_net
+++ xccdf_org.ssgproject.content_rule_banner_etc_issue_net
@@ -9,18 +9,18 @@
- medium_severity
- no_reboot_needed
- unknown_strategy
-- name: XCCDF Value remote_login_banner_contents # promote to variable
+- name: XCCDF Value remote_login_banner_text # promote to variable
set_fact:
- remote_login_banner_contents: !!str
+ remote_login_banner_text: !!str
tags:
- always
- name: Modify the System Login Banner for Remote Connections - ensure correct banner
ansible.builtin.copy:
dest: /etc/issue.net
- content: |
- {{ remote_login_banner_contents | replace('\n', '
- ') }}
+ content: '{{ remote_login_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$",
+ "\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)",
+ "\n") | regex_replace("\\", "") | wordwrap() }}'
when: '"kernel-core" in ansible_facts.packages'
tags:
- CCE-86147-6
bash remediation for rule 'xccdf_org.ssgproject.content_rule_banner_etc_motd' differs.
--- xccdf_org.ssgproject.content_rule_banner_etc_motd
+++ xccdf_org.ssgproject.content_rule_banner_etc_motd
@@ -1,8 +1,26 @@
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel-core; then
-motd_banner_contents=$(echo "" | sed 's/\\n/\n/g')
-echo "$motd_banner_contents" > /etc/motd
+motd_banner_text=''
+
+
+# Multiple regexes transform the banner regex into a usable banner
+# 0 - Remove anchors around the banner text
+motd_banner_text=$(echo "$motd_banner_text" | sed 's/^\^\(.*\)\$$/\1/g')
+# 1 - Keep only the first banners if there are multiple
+# (dod_banners contains the long and short banner)
+motd_banner_text=$(echo "$motd_banner_text" | sed 's/^(\(.*\.\)|.*)$/\1/g')
+# 2 - Add spaces ' '. (Transforms regex for "space or newline" into a " ")
+motd_banner_text=$(echo "$motd_banner_text" | sed 's/\[\\s\\n\]+/ /g')
+# 3 - Adds newlines. (Transforms "(?:\[\\n\]+|(?:\\n)+)" into "\n")
+motd_banner_text=$(echo "$motd_banner_text" | sed 's/(?:\[\\n\]+|(?:\\\\n)+)/\n/g')
+# 4 - Remove any leftover backslash. (From any parenthesis in the banner, for example).
+motd_banner_text=$(echo "$motd_banner_text" | sed 's/\\//g')
+formatted=$(echo "$motd_banner_text" | fold -sw 80)
+
+cat <<EOF >/etc/motd
+$formatted
+EOF
else
>&2 echo 'Remediation is not applicable, nothing was done'
ansible remediation for rule 'xccdf_org.ssgproject.content_rule_banner_etc_motd' differs.
--- xccdf_org.ssgproject.content_rule_banner_etc_motd
+++ xccdf_org.ssgproject.content_rule_banner_etc_motd
@@ -9,18 +9,18 @@
- medium_severity
- no_reboot_needed
- unknown_strategy
-- name: XCCDF Value motd_banner_contents # promote to variable
+- name: XCCDF Value motd_banner_text # promote to variable
set_fact:
- motd_banner_contents: !!str
+ motd_banner_text: !!str
tags:
- always
- name: Modify the System Message of the Day Banner - ensure correct banner
ansible.builtin.copy:
dest: /etc/motd
- content: |
- {{ motd_banner_contents | replace('\n', '
- ') }}
+ content: '{{ motd_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$",
+ "\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)",
+ "\n") | regex_replace("\\", "") | wordwrap() }}'
when: '"kernel-core" in ansible_facts.packages'
tags:
- CCE-83496-0
bash remediation for rule 'xccdf_org.ssgproject.content_rule_dconf_gnome_login_banner_text' differs.
--- xccdf_org.ssgproject.content_rule_dconf_gnome_login_banner_text
+++ xccdf_org.ssgproject.content_rule_dconf_gnome_login_banner_text
@@ -1,7 +1,24 @@
# Remediation is applicable only in certain platforms
if rpm --quiet -q gdm; then
-dconf_login_banner_contents=$(echo "" )
+login_banner_text=''
+
+# Multiple regexes transform the banner regex into a usable banner
+# 0 - Remove anchors around the banner text
+login_banner_text=$(echo "$login_banner_text" | sed 's/^\^\(.*\)\$$/\1/g')
+# 1 - Keep only the first banners if there are multiple
+# (dod_banners contains the long and short banner)
+login_banner_text=$(echo "$login_banner_text" | sed 's/^(\(.*\.\)|.*)$/\1/g')
+# 2 - Add spaces ' '. (Transforms regex for "space or newline" into a " ")
+login_banner_text=$(echo "$login_banner_text" | sed 's/\[\\s\\n\]+/ /g')
+# 3 - Adds newline "tokens". (Transforms "(?:\[\\n\]+|(?:\\n)+)" into "(n)*")
+login_banner_text=$(echo "$login_banner_text" | sed 's/(?:\[\\n\]+|(?:\\\\n)+)/(n)*/g')
+# 4 - Remove any leftover backslash. (From any parenthesis in the banner, for example).
+login_banner_text=$(echo "$login_banner_text" | sed 's/\\//g')
+# 5 - Removes the newline "token." (Transforms them into newline escape sequences "\n").
+# ( Needs to be done after 4, otherwise the escapce sequence will become just "n".
+login_banner_text=$(echo "$login_banner_text" | sed 's/(n)\*/\\n/g')
+
# Check for setting in any of the DConf db directories
# If files contain ibus or distro, ignore them.
# The assignment assumes that individual filenames don't contain :
@@ -28,7 +45,7 @@
printf '%s\n' "[org/gnome/login-screen]" >> ${DCONFFILE}
fi
-escaped_value="$(sed -e 's/\\/\\\\/g' <<< "'${dconf_login_banner_contents}'")"
+escaped_value="$(sed -e 's/\\/\\\\/g' <<< "'${login_banner_text}'")"
if grep -q "^\\s*banner-message-text\\s*=" "${DCONFFILE}"
then
sed -i "s/\\s*banner-message-text\\s*=\\s*.*/banner-message-text=${escaped_value}/g" "${DCONFFILE}"
ansible remediation for rule 'xccdf_org.ssgproject.content_rule_dconf_gnome_login_banner_text' differs.
--- xccdf_org.ssgproject.content_rule_dconf_gnome_login_banner_text
+++ xccdf_org.ssgproject.content_rule_dconf_gnome_login_banner_text
@@ -13,9 +13,9 @@
- medium_severity
- no_reboot_needed
- unknown_strategy
-- name: XCCDF Value dconf_login_banner_contents # promote to variable
+- name: XCCDF Value login_banner_text # promote to variable
set_fact:
- dconf_login_banner_contents: !!str
+ login_banner_text: !!str
tags:
- always
@@ -72,7 +72,9 @@
dest: /etc/dconf/db/gdm.d/00-security-settings
section: org/gnome/login-screen
option: banner-message-text
- value: '''{{ dconf_login_banner_contents }}'''
+ value: '''{{ login_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$",
+ "\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)",
+ "(n)*") | regex_replace("\\", "") | regex_replace("\(n\)\*", "\\n") }}'''
create: true
no_extra_spaces: true
register: result_ini |
3092331 to
512b77b
Compare
The correct text is "users".
These new variables will contain the actual text of the login banner. The variables will be used in multiple rules. They will be used only in remediations, not in OVALs. Using a variable will allow content users to specify the exact login banner text they want to have on the system, in contrast to specifying only regular expressions matching the text.
Use login_banner_contents variable in remediations in rule banner_etc_issue. Also, add test scenarios to test the ability to parametrize the rule with a custom banner text.
Use motd_banner_contents variable in remediations in rule banner_etc_motd.
Use remote_login_banner_contents variable in remediations in rule banner_etc_issue_net. Also, add test scenarios to test the ability to parametrize the rule with a custom banner text.
…nner_text Use dconf_login_banner_contents variable in remediations in rule dconf_gnome_login_banner_text.
0d70492 to
a992a54
Compare
Mab879
requested changes
Feb 12, 2026
Member
Mab879
left a comment
There was a problem hiding this comment.
Should the text in banner_etc_issue_cis_recommended.pass.sh be updated as well?
| # CIS doesn't enforce any specific content for login banners, but doesn't allow technical information. | ||
| # There is a generic content in case a remediation is necessary. | ||
| # How to generate banner, check https://complianceascode.readthedocs.io/en/latest/manual/developer/05_tools_and_utilities.html#generating-login-banner-regular-expressions | ||
| cis_banners: ^(Authorized[\s\n]+uses[\s\n]+only\.[\s\n]+All[\s\n]+activity[\s\n]+may[\s\n]+be[\s\n]+monitored[\s\n]+and[\s\n]+reported\.|^(?!.*(\\|fedora|rhel|sle|ubuntu)).*)$ |
Member
There was a problem hiding this comment.
Suggested change
| cis_banners: ^(Authorized[\s\n]+users[\s\n]+only\.[\s\n]+All[\s\n]+activity[\s\n]+may[\s\n]+be[\s\n]+monitored[\s\n]+and[\s\n]+reported\.|^(?!.*(\\|fedora|rhel|sle|ubuntu)).*)$ |
| rules: | ||
| - dconf_gnome_login_banner_text | ||
| - login_banner_text=dod_default | ||
| - dconf_login_banner_contents=cis_default |
Member
There was a problem hiding this comment.
Suggested change
| - dconf_login_banner_contents=cis_default | |
| - dconf_login_banner_contents=dod_default |
| Enter an appropriate login banner regular expression for your organization. | ||
| Using a regular expression is needed because some profiles (eg. STIG) allow multiple different banners. | ||
| This regular expression is used only in OVAL checks. | ||
| In remediations the motd_banner_contents variable is used instead. |
Member
There was a problem hiding this comment.
Suggested change
| In remediations the motd_banner_contents variable is used instead. | |
| In remediations the remote_login_banner_contents variable is used instead. |
| @@ -1,15 +1,15 @@ | |||
| # platform = multi_platform_rhel,multi_platform_fedora,multi_platform_ol,multi_platform_sle,multi_platform_slmicro,multi_platform_almalinux | |||
| # reboot = false | |||
Member
There was a problem hiding this comment.
Should we also change this multi platform all?
This is the closet line I can comment on.
| description: >- | ||
| Enter an appropriate login banner text for your organization. | ||
| This variable is used only in remediations. | ||
| In OVAL checks a regular expression specified in the login_banner_text variable is used instead. |
Member
There was a problem hiding this comment.
Suggested change
| In OVAL checks a regular expression specified in the login_banner_text variable is used instead. | |
| In OVAL checks a regular expression specified in the remote_login_banner_text variable is used instead. |
|
|
||
| login_banner_text="Some text before --[\s\n]+WARNING[\s\n]+--[\s\n]*This[\s\n]+system[\s\n]+is[\s\n]+for[\s\n]+the[\s\n]+use[\s\n]+of[\s\n]+authorized[\s\n]+users[\s\n]+only.[\s\n]+Individuals[\s\n]*using[\s\n]+this[\s\n]+computer[\s\n]+system[\s\n]+without[\s\n]+authority[\s\n]+or[\s\n]+in[\s\n]+excess[\s\n]+of[\s\n]+their[\s\n]*authority[\s\n]+are[\s\n]+subject[\s\n]+to[\s\n]+having[\s\n]+all[\s\n]+their[\s\n]+activities[\s\n]+on[\s\n]+this[\s\n]+system[\s\n]*monitored[\s\n]+and[\s\n]+recorded[\s\n]+by[\s\n]+system[\s\n]+personnel.[\s\n]+Anyone[\s\n]+using[\s\n]+this[\s\n]*system[\s\n]+expressly[\s\n]+consents[\s\n]+to[\s\n]+such[\s\n]+monitoring[\s\n]+and[\s\n]+is[\s\n]+advised[\s\n]+that[\s\n]*if[\s\n]+such[\s\n]+monitoring[\s\n]+reveals[\s\n]+possible[\s\n]+evidence[\s\n]+of[\s\n]+criminal[\s\n]+activity[\s\n]*system[\s\n]+personal[\s\n]+may[\s\n]+provide[\s\n]+the[\s\n]+evidence[\s\n]+of[\s\n]+such[\s\n]+monitoring[\s\n]+to[\s\n]+law[\s\n]*enforcement[\s\n]+officials. And some after." | ||
| expanded=$(echo "$login_banner_text" | sed 's/(\\\\\x27)\*/\\\x27/g;s/(\\\x27)\*//g;s/(\\\\\x27)/tamere/g;s/(\^\(.*\)\$|.*$/\1/g;s/\[\\s\\n\][+*]/ /g;s/\\//g;s/(n)\*/\\n/g;s/\x27/\\\x27/g;') | ||
| login_banner_contents="Some text before --[\s\n]+WARNING[\s\n]+--[\s\n]*This[\s\n]+system[\s\n]+is[\s\n]+for[\s\n]+the[\s\n]+use[\s\n]+of[\s\n]+authorized[\s\n]+users[\s\n]+only.[\s\n]+Individuals[\s\n]*using[\s\n]+this[\s\n]+computer[\s\n]+system[\s\n]+without[\s\n]+authority[\s\n]+or[\s\n]+in[\s\n]+excess[\s\n]+of[\s\n]+their[\s\n]*authority[\s\n]+are[\s\n]+subject[\s\n]+to[\s\n]+having[\s\n]+all[\s\n]+their[\s\n]+activities[\s\n]+on[\s\n]+this[\s\n]+system[\s\n]*monitored[\s\n]+and[\s\n]+recorded[\s\n]+by[\s\n]+system[\s\n]+personnel.[\s\n]+Anyone[\s\n]+using[\s\n]+this[\s\n]*system[\s\n]+expressly[\s\n]+consents[\s\n]+to[\s\n]+such[\s\n]+monitoring[\s\n]+and[\s\n]+is[\s\n]+advised[\s\n]+that[\s\n]*if[\s\n]+such[\s\n]+monitoring[\s\n]+reveals[\s\n]+possible[\s\n]+evidence[\s\n]+of[\s\n]+criminal[\s\n]+activity[\s\n]*system[\s\n]+personal[\s\n]+may[\s\n]+provide[\s\n]+the[\s\n]+evidence[\s\n]+of[\s\n]+such[\s\n]+monitoring[\s\n]+to[\s\n]+law[\s\n]*enforcement[\s\n]+officials. And some after." |
Member
There was a problem hiding this comment.
Should we use the dconf contents here?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description:
Allow users to specify a custom login banner text, including newlines.
To specify the login banner text, we currently use XCCDF Values which contain regular expressions. The remediations scripts "deregexify" the regexes, trying to get the actual text from the regular expressions. This is prone to problems and doesn't handle newlines well.
With this change, users will be able to specify the exact banner text as XCCDF Values in their tailoring files. The values will contain the exact plain text, including newlines and spaces.
The exact banner text from the new values will be used in remediations. This will mean that the contents of the banner files (
/etc/issue,/etc/motd) will be exactly as desired.OVAL checks will still use the regular expressions XCCDF Values. That is because we have some profiles where multiple different values are allowed (eg. STIG that allows 2 variants of the banner).
Rationale:
Users want to be able to create a custom login banner, special for their organization. They want to provide the banner text in their tailoring files. They expect that OpenSCAP scan will pass with their custom login banner and that remediation will insert the custom login banner instead of the default system banner.
Resolves: https://issues.redhat.com/browse/RHEL-118499
Review Hints: