Skip to content

Commit

Permalink
Merge pull request #12054 from vojtapolasek/fix_template_systemd_dropin
Browse files Browse the repository at this point in the history
align template systemd_dropin_configuration
  • Loading branch information
marcusburghardt authored Jul 16, 2024
2 parents 69256fb + 4c5541b commit 8a8b6ba
Show file tree
Hide file tree
Showing 17 changed files with 143 additions and 104 deletions.
25 changes: 25 additions & 0 deletions docs/templates/template_reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,31 @@ The selected value can be changed in the profile (consult the actual variable fo

- Languages: Ansible, Bash, OVAL

#### systemd_dropin_configuration
- checks if a Systemd-style configuration exists either in the main file or in any file within specified dropin directory.
The remediation tries to modify already existing configuration.
If the correct section is found and the parameter exists, its value is changed to match the desired one.
If the section is found but the parameter does not exist, it is added to this section.
If none of inspected files contains the desired section a new file called complianceascode_hardening.conf within the dropin directory is created.
- parameters:
- **master_cfg_file** - the main configuration file to check, e.g. /etc/systemd/journald.conf

- **dropin_dir** - the respective dropin directory, e.g. the /etc/systemd/journald.conf.d directory when keeping to the example mentioned above

- **section** - the section of the Systemd file

- **param** - the parameter to be configured

- **value** - the value of the parameter

- **no_quotes** - if set to "true", the value will not be enclosed in quotes

- **missing_parameter_pass** - effective only in OVAL checks, if
set to `"false"` and the parameter is not present in the
configuration file, the OVAL check will return false (default value: `"false"`).

- Languages: Ansible, Bash, OVAL

#### systemd_mount_enabled
- Checks if a `systemd` mount unit is enabled

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ ocil: |-
template:
name: systemd_dropin_configuration
vars:
component: journald
master_cfg_file: /etc/systemd/journald.conf
dropin_dir: {{{ journald_conf_dir_path }}}
section: Journal
param: Compress
value: yes
no_quotes: 'true'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

# This scenario is a regression test for https://bugzilla.redhat.com/show_bug.cgi?id=2193169

echo "Compress='yes'" > "/etc/systemd/journald.conf"
echo -e "[Journal]\nCompress='yes'" > "/etc/systemd/journald.conf"
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ ocil: |-
template:
name: systemd_dropin_configuration
vars:
component: journald
master_cfg_file: /etc/systemd/journald.conf
dropin_dir: {{{ journald_conf_dir_path }}}
section: Journal
param: ForwardToSyslog
value: yes
no_quotes: 'true'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ ocil: |-
template:
name: systemd_dropin_configuration
vars:
component: journald
master_cfg_file: /etc/systemd/journald.conf
dropin_dir: {{{ journald_conf_dir_path }}}
section: Journal
param: Storage
value: persistent
no_quotes: 'true'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

# This scenario is a regression test for https://bugzilla.redhat.com/show_bug.cgi?id=2169857

echo "Storage='persistent'" > "/etc/systemd/journald.conf"
echo -e "[Journal]\nStorage='persistent'" > "/etc/systemd/journald.conf"
20 changes: 16 additions & 4 deletions shared/macros/10-bash.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -2097,7 +2097,7 @@ Example macro invocation(s)::
:type value: str

#}}
{{% macro bash_ensure_ini_config(files, section, key, value) -%}}
{{% macro bash_ensure_ini_config(files, section, key, value, no_quotes=true) -%}}
found=false

# set value in all files if they contain section or key
Expand All @@ -2108,12 +2108,20 @@ for f in $(echo -n "{{{ files }}}"); do

# find key in section and change value
if grep -qzosP "[[:space:]]*\[{{{ section }}}\]([^\n\[]*\n+)+?[[:space:]]*{{{ key }}}" "$f"; then
sed -i "s/{{{ key }}}[^(\n)]*/{{{ key }}} = {{{ value }}}/" "$f"
{{% if no_quotes %}}
sed -i "s/{{{ key }}}[^(\n)]*/{{{ key }}}={{{ value }}}/" "$f"
{{% else %}}
sed -i 's/{{{ key }}}[^(\n)]*/{{{ key }}}="{{{ value }}}"/' "$f"
{{% endif %}}
found=true

# find section and add key = value to it
elif grep -qs "[[:space:]]*\[{{{ section }}}\]" "$f"; then
sed -i "/[[:space:]]*\[{{{ section }}}\]/a {{{ key }}} = {{{ value }}}" "$f"
{{% if no_quotes %}}
sed -i "/[[:space:]]*\[{{{ section }}}\]/a {{{ key }}}={{{ value }}}" "$f"
{{% else %}}
sed -i '/[[:space:]]*\[{{{ section }}}\]/a {{{ key }}}="{{{ value }}}"' "$f"
{{% endif %}}
found=true
fi
done
Expand All @@ -2122,7 +2130,11 @@ done
if ! $found ; then
file=$(echo "{{{ files }}}" | cut -f1 -d ' ')
mkdir -p "$(dirname "$file")"
echo -e "[{{{ section }}}]\n{{{ key }}} = {{{ value }}}" >> "$file"
{{% if no_quotes %}}
echo -e "[{{{ section }}}]\n{{{ key }}}={{{ value }}}" >> "$file"
{{% else %}}
echo -e '[{{{ section }}}]\n{{{ key }}}="{{{ value }}}"' >> "$file"
{{% endif %}}
fi
{{%- endmacro %}}

Expand Down
4 changes: 3 additions & 1 deletion shared/macros/10-oval.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,8 @@ Generates the :code:`<affected>` tag for OVAL check using correct product platfo
:type path: str
:param dropin_dir: Path to the dropin directory
:type dropin_dir: str
:param section: optional section if the file has an ini-like format
:type section: str
:param parameter: The shell variable name.
:type parameter: str
:param value: The variable value WITHOUT QUOTES.
Expand All @@ -604,7 +606,7 @@ Generates the :code:`<affected>` tag for OVAL check using correct product platfo
:type missing_config_file_fail: bool
#}}

{{%- macro oval_check_dropin_file(path, dropin_dir, parameter='', value='', application='', no_quotes=false, missing_parameter_pass=false, multi_value=false, missing_config_file_fail=false) %}}
{{%- macro oval_check_dropin_file(path, dropin_dir, section='', parameter='', value='', application='', no_quotes=false, missing_parameter_pass=false, multi_value=false, missing_config_file_fail=false) %}}
<def-group>
{{%- set prefix_regex = "^[ \\t]*" -%}}
{{%- set separator_regex = '=' -%}}
Expand Down
80 changes: 43 additions & 37 deletions shared/templates/systemd_dropin_configuration/ansible.template
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,51 @@
# strategy = restrict
# complexity = low
# disruption = low
- name: Check for duplicate {{{ PARAM }}} values in master {{{ COMPONENT }}} configuration
ansible.builtin.lineinfile:
path: {{{ MASTER_CFG_FILE }}}
create: false
regexp: ^\s*{{{ PARAM }}}=
state: absent
check_mode: true
changed_when: false
register: dupes_master

- name: Deduplicate {{{ PARAM }}} values from {{{ COMPONENT }}} master configuration
ansible.builtin.lineinfile:
path: {{{ MASTER_CFG_FILE }}}
create: false
regexp: ^\s*{{{ PARAM }}}=
state: absent
when: dupes_master.found is defined and dupes_master.found > 1

- name: Collect all config {{{ COMPONENT }}} files which configure {{{ PARAM }}}
- name: "{{{ rule_title }}} - Search for a section in files"
ansible.builtin.find:
paths: {{{ DROPIN_DIR }}}
contains: ^[\s]*{{{ PARAM }}}=.*$
patterns: "*.conf"
register: {{{ COMPONENT }}}_{{{ PARAM }}}_dropin_config_files
paths: "{{item.path}}"
patterns: "{{item.pattern}}"
contains: '^\s*\[{{{ SECTION }}}\]'
read_whole_file: true
use_regex: true
register: systemd_dropin_files_with_section
loop:
- path: "{{ '{{{ MASTER_CFG_FILE }}}' | dirname }}"
pattern: "{{ '{{{ MASTER_CFG_FILE }}}' | basename | regex_escape }}"
- path: "{{{ DROPIN_DIR }}}"
pattern: '.*\.conf'

- name: Deduplicate values from {{{ COMPONENT }}} {{{ PARAM }}} dropin configuration
ansible.builtin.lineinfile:
path: "{{ item.path }}"
create: false
regexp: ^\s*{{{ PARAM }}}=
state: absent
loop: "{{ {{{ COMPONENT }}}_{{{ PARAM }}}_dropin_config_files.files }}"
- name: "{{{ rule_title }}} - Count number of files which contain the correct section"
ansible.builtin.set_fact:
count_of_systemd_dropin_files_with_section: "{{systemd_dropin_files_with_section.results | map(attribute='matched') | list | map('int') | sum}}"

- name: Insert correct line to {{{ COMPONENT }}} {{{ PARAM }}} configuration
ansible.builtin.lineinfile:
path: {{{ DROPIN_DIR }}}/oscap-remedy.conf
create: true
regexp: ^\s*{{{ PARAM }}}=
line: {{{ PARAM }}}={{{ VALUE }}}
- name: "{{{ rule_title }}} - Add missing configuration to correct section"
ini_file:
path: "{{item}}"
section: {{{ SECTION }}}
option: {{{ PARAM }}}
{{% if NO_QUOTES %}}
value: "{{{ VALUE }}}"
{{% else %}}
value: '"{{{ VALUE }}}"'
{{% endif %}}
state: present
insertbefore: ^# {{{ PARAM }}}
validate: bash -n %s
no_extra_spaces: true
when: count_of_systemd_dropin_files_with_section | int > 0
loop: "{{systemd_dropin_files_with_section.results | sum(attribute='files', start=[]) | map(attribute='path') | list }}"

- name: "{{{ rule_title }}} - Add configuration to new remediation file"
ini_file:
path: "{{{ DROPIN_DIR }}}/complianceascode_hardening.conf"
section: {{{ SECTION }}}
option: {{{ PARAM }}}
{{% if NO_QUOTES %}}
value: "{{{ VALUE }}}"
{{% else %}}
value: '"{{{ VALUE }}}"'
{{% endif %}}
state: present
no_extra_spaces: true
create: true
when: count_of_systemd_dropin_files_with_section | int == 0
47 changes: 7 additions & 40 deletions shared/templates/systemd_dropin_configuration/bash.template
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,10 @@
# complexity = low
# disruption = low

function remove_{{{ COMPONENT }}}_{{{ PARAM }}}_configuration {
local COMPONENT_PARAM_CONFIG
mapfile -t COMPONENT_PARAM_CONFIG < <(ls {{{ DROPIN_DIR }}}/*.conf)
COMPONENT_PARAM_CONFIG+=("{{{ MASTER_CFG_FILE }}}")

for f in "${COMPONENT_PARAM_CONFIG[@]}"
do
sed -i "/^\s*{{{ PARAM }}}\s*=\s*/d" "$f"
# make sure file has newline at the end
sed -i -e '$a\' "$f"
done
sed -i -e '$a\' "{{{ MASTER_CFG_FILE }}}"
}

function {{{ COMPONENT }}}_{{{ PARAM }}}_add_configuration {
local COMPONENT_PARAM_REMEDY_CFG
mkdir -p "{{{ DROPIN_DIR }}}"
COMPONENT_PARAM_REMEDY_CFG="{{{ DROPIN_DIR }}}/oscap-remedy.conf"

if [ ! -f "${COMPONENT_PARAM_REMEDY_CFG}" ] ; then
touch "${COMPONENT_PARAM_REMEDY_CFG}"
fi
cp "${COMPONENT_PARAM_REMEDY_CFG}" "${COMPONENT_PARAM_REMEDY_CFG}.bak"
# Insert before the line matching the regex '^#\s*Compress'.
line_number="$(LC_ALL=C grep -n "^#\s*{{{ PARAM }}}" "${COMPONENT_PARAM_REMEDY_CFG}.bak" | LC_ALL=C sed 's/:.*//g')"
if [ -z "$line_number" ]; then
# There was no match of '^#\s*{{{ PARAM }}}', insert at
# the end of the file.
printf '%s\n' "{{{ PARAM }}}={{{ VALUE }}}" >> "${COMPONENT_PARAM_REMEDY_CFG}"
else
head -n "$(( line_number - 1 ))" "${COMPONENT_PARAM_REMEDY_CFG}.bak" > "${COMPONENT_PARAM_REMEDY_CFG}"
printf '%s\n' "{{{ PARAM }}}={{{ VALUE }}}" >> "{{{ MASTER_CFG_FILE }}}"
tail -n "+$(( line_number ))" "${COMPONENT_PARAM_REMEDY_CFG}.bak" >> "${COMPONENT_PARAM_REMEDY_CFG}"
fi
# Clean up after ourselves.
rm "${COMPONENT_PARAM_REMEDY_CFG}.bak"
}

remove_{{{ COMPONENT }}}_{{{ PARAM }}}_configuration
{{{ COMPONENT }}}_{{{ PARAM }}}_add_configuration
{{{ bash_ensure_ini_config(
files=DROPIN_DIR+"/complianceascode_hardening.conf "+DROPIN_DIR+"/*.conf "+MASTER_CFG_FILE,
section=SECTION,
key=PARAM,
value=VALUE,
no_quotes=NO_QUOTES
) }}}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
oval_check_dropin_file(
path=MASTER_CFG_FILE,
dropin_dir=DROPIN_DIR,
section=SECTION,
parameter=PARAM,
value=VALUE,
no_quotes=NO_QUOTES,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#!/bin/bash
SECTION="{{{ SECTION }}}"
PARAM="{{{ PARAM }}}"
VALUE="{{{ VALUE }}}"
DROPIN_DIR="{{{ DROPIN_DIR }}}"
[ -d $DROPIN_DIR ] || mkdir -p $DROPIN_DIR
echo "$PARAM=$VALUE" >> "$DROPIN_DIR/ssg.conf"
{{% if NO_QUOTES %}}
echo -e "[$SECTION]\n$PARAM=$VALUE" > "$DROPIN_DIR/ssg.conf"
{{% else %}}
echo -e "[$SECTION]\n$PARAM=\"$VALUE\"" > "$DROPIN_DIR/ssg.conf"
{{% endif %}}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#!/bin/bash
SECTION="{{{ SECTION }}}"
PARAM="{{{ PARAM }}}"
VALUE="{{{ VALUE }}}"
MASTER_CFG_FILE="{{{ MASTER_CFG_FILE }}}"
echo "$PARAM=$VALUE" >> "$MASTER_CFG_FILE"
{{% if NO_QUOTES %}}
echo -e "[$SECTION]\n$PARAM=$VALUE" > "$MASTER_CFG_FILE"
{{% else %}}
echo -e "[$SECTION]\n$PARAM=\"$VALUE\"" > "$MASTER_CFG_FILE"
{{% endif %}}
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
#!/bin/bash
SECTION="{{{ SECTION }}}"
PARAM="{{{ PARAM }}}"
VALUE="{{{ VALUE }}}"
DROPIN_DIR="{{{ DROPIN_DIR }}}"
MASTER_CFG_FILE="{{{ MASTER_CFG_FILE }}}"
[ -d $DROPIN_DIR ] || mkdir -p $DROPIN_DIR
echo "$PARAM=$VALUE" >> "$DROPIN_DIR/ssg.conf"
echo "$PARAM=badval" >> "$DROPIN_DIR/gss.conf"
echo "$PARAM=foobarzoo" >> "$MASTER_CFG_FILE"
{{% if NO_QUOTES %}}
echo -e "[$SECTION]\n$PARAM=$VALUE" > "$DROPIN_DIR/ssg.conf"
echo -e "[$SECTION]\n$PARAM=badval" > "$DROPIN_DIR/gss.conf"
echo -e "[$SECTION]\n$PARAM=foobarzoo" > "$MASTER_CFG_FILE"
{{% else %}}
echo -e "[$SECTION]\n$PARAM=\"$VALUE\"" > "$DROPIN_DIR/ssg.conf"
echo -e "[$SECTION]\n$PARAM=\"badval\"" > "$DROPIN_DIR/gss.conf"
echo -e "[$SECTION]\n$PARAM=\"foobarzoo\"" > "$MASTER_CFG_FILE"
{{% endif %}}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#!/bin/bash
SECTION="{{{ SECTION }}}"
PARAM="{{{ PARAM }}}"
DROPIN_DIR="{{{ DROPIN_DIR }}}"
[ -d $DROPIN_DIR ] || mkdir -p $DROPIN_DIR
echo "$PARAM=badval" >> "$DROPIN_DIR/ssg.conf"
{{% if NO_QUOTES %}}
echo -e "[$SECTION]\n$PARAM=badval" > "$DROPIN_DIR/ssg.conf"
{{% else %}}
echo -e "[$SECTION]\n$PARAM=\"badval\"" > "$DROPIN_DIR/ssg.conf"
{{% endif %}}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/bin/bash
SECTION="{{{ SECTION }}}"
PARAM="{{{ PARAM }}}"
VALUE="{{{ VALUE }}}"
MASTER_CFG_FILE="{{{ MASTER_CFG_FILE }}}"
echo "$PARAM=badval" >> "$MASTER_CFG_FILE"
{{% if NO_QUOTES %}}
echo -e "[$SECTION]\n$PARAM=badval" > "$MASTER_CFG_FILE"
{{% else %}}
echo -e "[$SECTION]\n$PARAM=\"badval\"" > "$MASTER_CFG_FILE"
{{% endif %}}
Loading

0 comments on commit 8a8b6ba

Please sign in to comment.