The journald system may store log files in volatile memory or locally on disk.
If the logs are only stored in volatile memory they will we lost upon reboot.
Rationale
Log files contain valuable data and need to be persistent to aid in possible investigations.
- name: Ensure journald is configured to write log files to persistent disk - Search
for a section in files
ansible.builtin.find:
paths: '{{item.path}}'
patterns: '{{item.pattern}}'
contains: ^\s*\[Journal\]
read_whole_file: true
use_regex: true
register: systemd_dropin_files_with_section
loop:
- path: '{{ ''/etc/systemd/journald.conf'' | dirname }}'
pattern: '{{ ''/etc/systemd/journald.conf'' | basename | regex_escape }}'
- path: /etc/systemd/journald.conf.d
pattern: .*\.conf
when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- journald_storage
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Ensure journald is configured to write log files to persistent disk - 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}}'
when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- journald_storage
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Ensure journald is configured to write log files to persistent disk - Add
missing configuration to correct section
ini_file:
path: '{{item}}'
section: Journal
option: Storage
value: persistent
state: present
no_extra_spaces: true
when:
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- count_of_systemd_dropin_files_with_section | int > 0
loop: '{{systemd_dropin_files_with_section.results | sum(attribute=''files'', start=[])
| map(attribute=''path'') | list }}'
tags:
- journald_storage
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Ensure journald is configured to write log files to persistent disk - Add
configuration to new remediation file
ini_file:
path: /etc/systemd/journald.conf.d/complianceascode_hardening.conf
section: Journal
option: Storage
value: persistent
state: present
no_extra_spaces: true
create: true
when:
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- count_of_systemd_dropin_files_with_section | int == 0
tags:
- journald_storage
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation - Shell Script
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
found=false
# set value in all files if they contain section or key
for f in $(echo -n "/etc/systemd/journald.conf.d/complianceascode_hardening.conf /etc/systemd/journald.conf.d/*.conf /etc/systemd/journald.conf"); do
if [ ! -e "$f" ]; then
continue
fi
# find key in section and change value
if grep -qzosP "[[:space:]]*\[Journal\]([^\n\[]*\n+)+?[[:space:]]*Storage" "$f"; then
sed -i "s/Storage[^(\n)]*/Storage=persistent/" "$f"
found=true
# find section and add key = value to it
elif grep -qs "[[:space:]]*\[Journal\]" "$f"; then
sed -i "/[[:space:]]*\[Journal\]/a Storage=persistent" "$f"
found=true
fi
done
# if section not in any file, append section with key = value to FIRST file in files parameter
if ! $found ; then
file=$(echo "/etc/systemd/journald.conf.d/complianceascode_hardening.conf /etc/systemd/journald.conf.d/*.conf /etc/systemd/journald.conf" | cut -f1 -d ' ')
mkdir -p "$(dirname "$file")"
echo -e "[Journal]\nStorage=persistent" >> "$file"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi