diff --git a/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/bash/ubuntu.sh b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/bash/ubuntu.sh index 1e53e273926f..aed3541ccb6f 100644 --- a/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/bash/ubuntu.sh +++ b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/bash/ubuntu.sh @@ -1,19 +1,3 @@ # platform = multi_platform_ubuntu -TMPFILES_CONF="/usr/lib/tmpfiles.d/systemd.conf" - -if ! grep -q 'Z /var/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then - if grep -qP "^[zZ][+]*\s+\/var\/log\/journal" "$TMPFILES_CONF"; then - sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/var\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF" - fi - echo "Z /var/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF" -fi - -if ! grep -q 'Z /run/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then - if grep -qP "^[zZ][+]*\s+\/run\/log\/journal" "$TMPFILES_CONF"; then - sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/run\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF" - fi - echo "Z /run/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF" -fi - -systemd-tmpfiles --create +{{{ bash_set_journal_tmpfiles(2750) }}} diff --git a/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/rule.yml b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/rule.yml index 520a68e57725..75f01be89740 100644 --- a/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/rule.yml +++ b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/rule.yml @@ -21,13 +21,17 @@ severity: medium fixtext: | Configure the system to set the appropriate ownership to the directories - used by the systemd journal. Add or modify the following lines in the - "/usr/lib/tmpfiles.d/systemd.conf" file: + used by the systemd journal. + Create a drop-in file if it does not already exist with the following command:
- z /run/log/journal 2640 root systemd-journal - -
- z /var/log/journal 2640 root systemd-journal - -
+ $ sudo vi /etc/tmpfiles.d/zzz-systemd-stig.conf
- Restart the system for the changes to take effect.
+ Add or modify the following lines in the "/etc/tmpfiles.d/zzz-systemd-stig.conf" file:
+ + z /run/log/journal 0640 root systemd-journal - - + z /var/log/journal 0640 root systemd-journal - - ++ Note: Restart the system for the changes to take effect. template: name: file_groupowner diff --git a/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/correct_groupowner.pass.sh b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/correct_groupowner.pass.sh new file mode 100644 index 000000000000..eb8a569730ee --- /dev/null +++ b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/correct_groupowner.pass.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# platform = multi_platform_ubuntu + +getent group "systemd-journal" &>/dev/null || groupadd systemd-journal + +mkdir -p /run/log/journal /var/log/journal +chgrp -R systemd-journal /run/log/journal /var/log/journal diff --git a/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/incorrect_groupowner.fail.sh b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/incorrect_groupowner.fail.sh new file mode 100644 index 000000000000..db024eb599b4 --- /dev/null +++ b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/incorrect_groupowner.fail.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# platform = multi_platform_ubuntu + +getent group "systemd-journal" &>/dev/null || groupadd systemd-journal + +mkdir -p /run/log/journal /var/log/journal +mkdir -p /var/log/journal/wrong_group_dir +chgrp -R systemd-journal /run/log/journal /var/log/journal +chgrp -R nogroup /var/log/journal/wrong_group_dir diff --git a/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/nested_subdir_groupowner.fail.sh b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/nested_subdir_groupowner.fail.sh new file mode 100644 index 000000000000..a0b3c02fffcf --- /dev/null +++ b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/nested_subdir_groupowner.fail.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# platform = multi_platform_ubuntu + +getent group "systemd-journal" &>/dev/null || groupadd systemd-journal + +machine_id="$(cat /etc/machine-id)" +mkdir -p "/run/log/journal/${machine_id}/nested/deeper" +mkdir -p "/var/log/journal/${machine_id}/nested/deeper" + +chgrp nogroup "/run/log/journal/${machine_id}/nested/deeper" +chgrp nogroup "/var/log/journal/${machine_id}/nested/deeper" diff --git a/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/no_file.pass.sh b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/no_file.pass.sh new file mode 100644 index 000000000000..28147cf647dc --- /dev/null +++ b/linux_os/guide/system/logging/journald/dir_groupowner_system_journal/tests/no_file.pass.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# platform = multi_platform_ubuntu + +getent group "systemd-journal" &>/dev/null || groupadd systemd-journal + +mkdir -p /run/log/journal /var/log/journal +chgrp systemd-journal /run/log/journal /var/log/journal diff --git a/linux_os/guide/system/logging/journald/dir_owner_system_journal/bash/ubuntu.sh b/linux_os/guide/system/logging/journald/dir_owner_system_journal/bash/ubuntu.sh index 1e53e273926f..aed3541ccb6f 100644 --- a/linux_os/guide/system/logging/journald/dir_owner_system_journal/bash/ubuntu.sh +++ b/linux_os/guide/system/logging/journald/dir_owner_system_journal/bash/ubuntu.sh @@ -1,19 +1,3 @@ # platform = multi_platform_ubuntu -TMPFILES_CONF="/usr/lib/tmpfiles.d/systemd.conf" - -if ! grep -q 'Z /var/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then - if grep -qP "^[zZ][+]*\s+\/var\/log\/journal" "$TMPFILES_CONF"; then - sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/var\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF" - fi - echo "Z /var/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF" -fi - -if ! grep -q 'Z /run/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then - if grep -qP "^[zZ][+]*\s+\/run\/log\/journal" "$TMPFILES_CONF"; then - sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/run\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF" - fi - echo "Z /run/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF" -fi - -systemd-tmpfiles --create +{{{ bash_set_journal_tmpfiles(2750) }}} diff --git a/linux_os/guide/system/logging/journald/dir_owner_system_journal/rule.yml b/linux_os/guide/system/logging/journald/dir_owner_system_journal/rule.yml index 165d1ff7ac52..3eff30d1ee59 100644 --- a/linux_os/guide/system/logging/journald/dir_owner_system_journal/rule.yml +++ b/linux_os/guide/system/logging/journald/dir_owner_system_journal/rule.yml @@ -21,13 +21,14 @@ severity: medium fixtext: | Configure the system to set the appropriate ownership to the directories - used by the systemd journal. Add or modify the following lines in the - "/usr/lib/tmpfiles.d/systemd.conf" file: + used by the systemd journal. + Create the drop-in file "/etc/tmpfiles.d/zzz-systemd-stig.conf" with the + following content:
- z /run/log/journal 2640 root systemd-journal - -
- z /var/log/journal 2640 root systemd-journal - -
+ z /run/log/journal 0640 root systemd-journal - -
+ z /var/log/journal 0640 root systemd-journal - -
- Restart the system for the changes to take effect.
+ Note: Restart the system for these settings to take effect.
template:
name: file_owner
diff --git a/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/correct_owner.pass.sh b/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/correct_owner.pass.sh
new file mode 100644
index 000000000000..5c43a2066188
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/correct_owner.pass.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+mkdir -p /run/log/journal /var/log/journal
+chown -R root /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/incorrect_owner.fail.sh b/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/incorrect_owner.fail.sh
new file mode 100644
index 000000000000..0cf5454912c1
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/incorrect_owner.fail.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+useradd testuser_123
+
+mkdir -p /run/log/journal /var/log/journal
+mkdir -p /run/log/journal/wrong_owner_dir
+chown -R testuser_123 /run/log/journal/wrong_owner_dir
diff --git a/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/nested_subdir_owner.fail.sh b/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/nested_subdir_owner.fail.sh
new file mode 100644
index 000000000000..a295133eb506
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/nested_subdir_owner.fail.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+id testuser_123 &>/dev/null || useradd testuser_123
+
+machine_id="$(cat /etc/machine-id)"
+mkdir -p "/run/log/journal/${machine_id}/nested/deeper"
+mkdir -p "/var/log/journal/${machine_id}/nested/deeper"
+
+chown testuser_123 "/run/log/journal/${machine_id}/nested/deeper"
+chown testuser_123 "/var/log/journal/${machine_id}/nested/deeper"
diff --git a/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/no_file.pass.sh b/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/no_file.pass.sh
new file mode 100644
index 000000000000..3010d85c3d68
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_owner_system_journal/tests/no_file.pass.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+mkdir -p /run/log/journal /var/log/journal
+chown root /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/bash/ubuntu.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/bash/ubuntu.sh
index 1e53e273926f..aed3541ccb6f 100644
--- a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/bash/ubuntu.sh
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/bash/ubuntu.sh
@@ -1,19 +1,3 @@
# platform = multi_platform_ubuntu
-TMPFILES_CONF="/usr/lib/tmpfiles.d/systemd.conf"
-
-if ! grep -q 'Z /var/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then
- if grep -qP "^[zZ][+]*\s+\/var\/log\/journal" "$TMPFILES_CONF"; then
- sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/var\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF"
- fi
- echo "Z /var/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF"
-fi
-
-if ! grep -q 'Z /run/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then
- if grep -qP "^[zZ][+]*\s+\/run\/log\/journal" "$TMPFILES_CONF"; then
- sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/run\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF"
- fi
- echo "Z /run/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF"
-fi
-
-systemd-tmpfiles --create
+{{{ bash_set_journal_tmpfiles(2750) }}}
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/rule.yml b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/rule.yml
index c09b608e3749..590f637cca8a 100644
--- a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/rule.yml
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/rule.yml
@@ -18,16 +18,21 @@ rationale: |-
severity: medium
fixtext: |
- Configure the system to set the appropriate permissions to the files and directories
- used by the systemd journal:
- Add or modify the following lines in the "/etc/tmpfiles.d/systemd.conf" file:
+ Configure the system to set the appropriate permissions to the directories
+ used by the systemd journal.
+ Create a drop-in file, if it does not already exist with the following command:
+ + $ sudo vi /etc/tmpfiles.d/zzz-systemd-stig.conf ++ Add or modify the following lines in the "/etc/tmpfiles.d/zzz-systemd-stig.conf" file:
z /run/log/journal 2750 root systemd-journal - -
Z /run/log/journal/%m ~2750 root systemd-journal - -
z /var/log/journal 2750 root systemd-journal - -
z /var/log/journal/%m 2750 root systemd-journal - -
+ z /var/log/journal/%m/system.journal 2750 root systemd-journal - -
- Restart the system for the changes to take effect.
+ Note: Restart the system for these settings to take effect.
template:
name: file_permissions
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/correct_permissions.pass.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/correct_permissions.pass.sh
new file mode 100644
index 000000000000..e5a0c28d7872
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/correct_permissions.pass.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+mkdir -p /run/log/journal /var/log/journal
+find /run/log/journal /var/log/journal -type d -exec chmod 2750 {} \;
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/lenient_permissions.fail.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/lenient_permissions.fail.sh
new file mode 100644
index 000000000000..4c768d32faf6
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/lenient_permissions.fail.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+mkdir -p /run/log/journal /var/log/journal
+mkdir -p /run/log/journal/loose_dir
+chmod 777 /run/log/journal/loose_dir
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/nested_subdir_permissions.fail.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/nested_subdir_permissions.fail.sh
new file mode 100644
index 000000000000..1330b8b5ca38
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/nested_subdir_permissions.fail.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+machine_id="$(cat /etc/machine-id)"
+
+mkdir -p "/run/log/journal/${machine_id}/nested/deeper"
+mkdir -p "/var/log/journal/${machine_id}/nested/deeper"
+
+chmod 2755 "/run/log/journal/${machine_id}/nested"
+chmod 2777 "/run/log/journal/${machine_id}/nested/deeper"
+chmod 2755 "/var/log/journal/${machine_id}/nested"
+chmod 2777 "/var/log/journal/${machine_id}/nested/deeper"
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/no_file.pass.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/no_file.pass.sh
new file mode 100644
index 000000000000..343bdc845422
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/no_file.pass.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+mkdir -p /run/log/journal /var/log/journal
+rm -rf /run/log/journal/* /var/log/journal/*
+chmod 2750 /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/stricter_permissions.pass.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/stricter_permissions.pass.sh
new file mode 100644
index 000000000000..f9535d422b01
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/stricter_permissions.pass.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+mkdir -p /run/log/journal /var/log/journal
+find /run/log/journal /var/log/journal -type d -exec chmod 0700 {} \;
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_early_filename_precedence.fail.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_early_filename_precedence.fail.sh
new file mode 100644
index 000000000000..753e3ddbb17b
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_early_filename_precedence.fail.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+# Precedence dimension: FILE NAME ordering.
+#
+# Configuration files are read from /etc/tmpfiles.d, /run/tmpfiles.d and
+# /usr/lib/tmpfiles.d and are sorted by file name regardless of the directory
+# they live in. Because z/Z entries adjust permissions of existing inodes, every
+# matching entry is applied and the one applied last wins. A drop-in that sorts
+# *before* the vendor systemd.conf is therefore overridden by it.
+#
+# Place a hardening drop-in under a name that sorts before "systemd.conf" so it
+# loses against the vendor entry, together with a loose drop-in that sorts after
+# it. The remediation writes "zzz-systemd-stig.conf", which sorts last and wins.
+mkdir -p /etc/tmpfiles.d
+cat > /etc/tmpfiles.d/00-journal-hardening.conf <<'EOF'
+z /run/log/journal 2750 root systemd-journal - -
+z /var/log/journal 2750 root systemd-journal - -
+EOF
+
+mkdir -p /run/log/journal /var/log/journal
+chmod 2755 /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_hardened_dropin.pass.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_hardened_dropin.pass.sh
new file mode 100644
index 000000000000..817ef90d5af2
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_hardened_dropin.pass.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+# Precedence dimension: correctly ordered drop-in (positive case).
+#
+# A drop-in that sorts after the vendor systemd.conf and repeats the vendor line
+# types and paths wins, because for z/Z entries every matching entry is applied
+# and the entry applied last takes effect. Non-recursive "z" entries are applied
+# after recursive "Z" entries, which is why the plain "z" lines are required in
+# addition to the recursive ones.
+mkdir -p /etc/tmpfiles.d
+cat > /etc/tmpfiles.d/zzz-systemd-stig.conf <<'EOF'
+z /run/log/journal ~2750 root systemd-journal - -
+Z /run/log/journal ~2750 root systemd-journal - -
+z /run/log/journal/%m ~2750 root systemd-journal - -
+z /var/log/journal ~2750 root systemd-journal - -
+Z /var/log/journal ~2750 root systemd-journal - -
+z /var/log/journal/%m ~2750 root systemd-journal - -
+EOF
+
+mkdir -p /run/log/journal /var/log/journal
+chmod 2755 /run/log/journal /var/log/journal
+systemd-tmpfiles --create
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_late_filename_precedence.fail.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_late_filename_precedence.fail.sh
new file mode 100644
index 000000000000..91a2789c66bf
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_late_filename_precedence.fail.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+# Precedence dimension: FILE NAME ordering, drop-in sorting AFTER the drop-in
+# written by the remediation.
+#
+# Because z/Z entries are applied to already existing inodes, systemd-tmpfiles
+# applies every matching entry and the entry applied last wins. A drop-in that
+# sorts after "zzz-systemd-stig.conf" would therefore be applied last and would
+# reset the journal directories back to a too permissive mode. The remediation
+# neutralizes conflicting journal entries in the other drop-ins.
+mkdir -p /etc/tmpfiles.d
+cat > /etc/tmpfiles.d/zzzz-late-override.conf <<'EOF'
+z /run/log/journal 2755 root systemd-journal - -
+z /var/log/journal 2755 root systemd-journal - -
+EOF
+
+mkdir -p /run/log/journal /var/log/journal
+chmod 2755 /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_line_type_precedence.fail.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_line_type_precedence.fail.sh
new file mode 100644
index 000000000000..5a027fb91119
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_line_type_precedence.fail.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+# Precedence dimension: LINE TYPE.
+#
+# systemd ships /usr/lib/tmpfiles.d/systemd.conf with a non-recursive
+# "z /run/log/journal 2755" entry. For z/Z lines systemd-tmpfiles applies every
+# matching entry instead of de-duplicating them, and non-recursive "z" lines are
+# applied after recursive "Z" lines. A drop-in that only carries recursive "Z"
+# lines is therefore overridden by the vendor "z" entry and the directories stay
+# at 2755. The remediation must emit matching "z" lines as well.
+#
+# Re-create the vendor situation and leave a drop-in that only uses "Z".
+mkdir -p /etc/tmpfiles.d
+cat > /etc/tmpfiles.d/zzz-systemd-stig.conf <<'EOF'
+Z /run/log/journal ~2750 root systemd-journal - -
+Z /var/log/journal ~2750 root systemd-journal - -
+EOF
+
+mkdir -p /run/log/journal /var/log/journal
+chmod 2755 /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_runtime_dropin_precedence.fail.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_runtime_dropin_precedence.fail.sh
new file mode 100644
index 000000000000..dcd489304e0a
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/tmpfiles_runtime_dropin_precedence.fail.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+# Precedence dimension: CONFIGURATION DIRECTORY.
+#
+# Configuration is read from /etc/tmpfiles.d, /run/tmpfiles.d and
+# /usr/lib/tmpfiles.d, and the files of all three directories are sorted
+# together by file name. A loose entry dropped into /run/tmpfiles.d under a name
+# that sorts last is therefore applied after the hardened entry.
+mkdir -p /run/tmpfiles.d
+cat > /run/tmpfiles.d/zzzzz-runtime-override.conf <<'EOF'
+z /run/log/journal 2777 root systemd-journal - -
+z /var/log/journal 2777 root systemd-journal - -
+EOF
+
+mkdir -p /run/log/journal /var/log/journal
+chmod 2777 /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/vendor_conf_precedence.fail.sh b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/vendor_conf_precedence.fail.sh
new file mode 100644
index 000000000000..e31aab16b269
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/dir_permissions_system_journal/tests/vendor_conf_precedence.fail.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+# Precedence dimension: VENDOR configuration in /usr/lib/tmpfiles.d.
+#
+# systemd ships /usr/lib/tmpfiles.d/systemd.conf, which contains
+# z /run/log/journal 2755 root systemd-journal - -
+# z /var/log/journal 2755 root systemd-journal - -
+# z /var/log/journal/%m 2755 root systemd-journal - -
+# so a stock system ends up with the too permissive mode 2755 as soon as
+# systemd-tmpfiles runs. The vendor file must not be edited, the hardened
+# entries have to be shipped in a drop-in that is applied after it.
+#
+# Reproduce the stock state and remove any hardening drop-in.
+rm -f /etc/tmpfiles.d/zzz-systemd-stig.conf
+
+mkdir -p /run/log/journal /var/log/journal
+find /run/log/journal /var/log/journal -type d -exec chmod 2755 {} \;
diff --git a/linux_os/guide/system/logging/journald/file_groupowner_system_journal/bash/ubuntu.sh b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/bash/ubuntu.sh
index 1e53e273926f..aed3541ccb6f 100644
--- a/linux_os/guide/system/logging/journald/file_groupowner_system_journal/bash/ubuntu.sh
+++ b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/bash/ubuntu.sh
@@ -1,19 +1,3 @@
# platform = multi_platform_ubuntu
-TMPFILES_CONF="/usr/lib/tmpfiles.d/systemd.conf"
-
-if ! grep -q 'Z /var/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then
- if grep -qP "^[zZ][+]*\s+\/var\/log\/journal" "$TMPFILES_CONF"; then
- sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/var\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF"
- fi
- echo "Z /var/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF"
-fi
-
-if ! grep -q 'Z /run/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then
- if grep -qP "^[zZ][+]*\s+\/run\/log\/journal" "$TMPFILES_CONF"; then
- sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/run\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF"
- fi
- echo "Z /run/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF"
-fi
-
-systemd-tmpfiles --create
+{{{ bash_set_journal_tmpfiles(2750) }}}
diff --git a/linux_os/guide/system/logging/journald/file_groupowner_system_journal/rule.yml b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/rule.yml
index d8bc652448b0..6951dc08d6a3 100644
--- a/linux_os/guide/system/logging/journald/file_groupowner_system_journal/rule.yml
+++ b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/rule.yml
@@ -1,6 +1,5 @@
documentation_complete: true
-
title: 'Verify Group Who Owns the system journal'
description: |-
@@ -24,7 +23,6 @@ rationale: |-
messages to unauthorized personnel or their designated representatives.
{{%- else %}}
RHCOS must protect system journal file from any type of unauthorized access by setting file group ownership.
-
{{%- endif %}}
identifiers:
@@ -35,12 +33,15 @@ severity: medium
fixtext: |
{{%- if 'ubuntu' in product %}}
Configure the system to set the appropriate group-ownership to the files
- used by the systemd journal:
- Add or modify the following lines in the "/etc/tmpfiles.d/systemd.conf" file:
+ used by the systemd journal.
+ Create the drop-in file "/etc/tmpfiles.d/zzz-systemd-stig.conf" with the
+ following content:
+ Z /run/log/journal/%m ~0640 root systemd-journal - -
+ z /var/log/journal/%m 0640 root systemd-journal - -
z /var/log/journal/%m/system.journal 0640 root systemd-journal - -
- Restart the system for the changes to take effect.
+ Note: Restart the system for these settings to take effect.
{{%- endif %}}
references:
@@ -56,15 +57,15 @@ template:
vars:
{{%- if 'ubuntu' in product %}}
filepath:
- - /run/log/journal/
- - /var/log/journal/
+ - /run/log/journal/
+ - /var/log/journal/
+ file_regex:
+ - ^.*$
+ - ^.*$
recursive: 'true'
- file_regex: ^.*$
gid_or_name: systemd-journal
-
{{%- else %}}
filepath: ^/var/log/journal/.*/system.journal$
gid_or_name: systemd-journal
filepath_is_regex: "true"
-
{{%- endif %}}
diff --git a/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/correct_groupowner.pass.sh b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/correct_groupowner.pass.sh
new file mode 100644
index 000000000000..a225278c7ec5
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/correct_groupowner.pass.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+getent group "systemd-journal" &>/dev/null || groupadd systemd-journal
+
+mkdir -p /run/log/journal /var/log/journal
+touch /var/log/journal/system.journal
+touch /run/log/journal/system.journal
+chgrp -R systemd-journal /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/incorrect_groupowner.fail.sh b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/incorrect_groupowner.fail.sh
new file mode 100644
index 000000000000..5a1625e39305
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/incorrect_groupowner.fail.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+getent group "systemd-journal" &>/dev/null || groupadd systemd-journal
+
+mkdir -p /run/log/journal
+touch /run/log/journal/system.journal
+chgrp nogroup /run/log/journal/system.journal
diff --git a/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/nested_file_groupowner.fail.sh b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/nested_file_groupowner.fail.sh
new file mode 100644
index 000000000000..dff9f02c9726
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/nested_file_groupowner.fail.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+getent group "systemd-journal" &>/dev/null || groupadd systemd-journal
+
+machine_id="$(cat /etc/machine-id)"
+mkdir -p "/run/log/journal/${machine_id}/nested/deeper"
+mkdir -p "/var/log/journal/${machine_id}/nested/deeper"
+
+touch "/run/log/journal/${machine_id}/nested/deeper/user-1000.journal"
+touch "/var/log/journal/${machine_id}/nested/deeper/user-1000.journal"
+chgrp nogroup "/run/log/journal/${machine_id}/nested/deeper/user-1000.journal"
+chgrp nogroup "/var/log/journal/${machine_id}/nested/deeper/user-1000.journal"
diff --git a/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/no_file.pass.sh b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/no_file.pass.sh
new file mode 100644
index 000000000000..28147cf647dc
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_groupowner_system_journal/tests/no_file.pass.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+getent group "systemd-journal" &>/dev/null || groupadd systemd-journal
+
+mkdir -p /run/log/journal /var/log/journal
+chgrp systemd-journal /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/file_owner_system_journal/bash/ubuntu.sh b/linux_os/guide/system/logging/journald/file_owner_system_journal/bash/ubuntu.sh
index 1e53e273926f..aed3541ccb6f 100644
--- a/linux_os/guide/system/logging/journald/file_owner_system_journal/bash/ubuntu.sh
+++ b/linux_os/guide/system/logging/journald/file_owner_system_journal/bash/ubuntu.sh
@@ -1,19 +1,3 @@
# platform = multi_platform_ubuntu
-TMPFILES_CONF="/usr/lib/tmpfiles.d/systemd.conf"
-
-if ! grep -q 'Z /var/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then
- if grep -qP "^[zZ][+]*\s+\/var\/log\/journal" "$TMPFILES_CONF"; then
- sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/var\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF"
- fi
- echo "Z /var/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF"
-fi
-
-if ! grep -q 'Z /run/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then
- if grep -qP "^[zZ][+]*\s+\/run\/log\/journal" "$TMPFILES_CONF"; then
- sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/run\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF"
- fi
- echo "Z /run/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF"
-fi
-
-systemd-tmpfiles --create
+{{{ bash_set_journal_tmpfiles(2750) }}}
diff --git a/linux_os/guide/system/logging/journald/file_owner_system_journal/rule.yml b/linux_os/guide/system/logging/journald/file_owner_system_journal/rule.yml
index 95db4b7555cf..dce8db8ba8c6 100644
--- a/linux_os/guide/system/logging/journald/file_owner_system_journal/rule.yml
+++ b/linux_os/guide/system/logging/journald/file_owner_system_journal/rule.yml
@@ -1,6 +1,5 @@
documentation_complete: true
-
title: 'Verify Owner on the system journal'
description: |-
@@ -34,12 +33,15 @@ severity: medium
fixtext: |
{{%- if 'ubuntu' in product %}}
Configure the system to set the appropriate ownership to the files
- used by the systemd journal:
- Add or modify the following lines in the "/etc/tmpfiles.d/systemd.conf" file:
+ used by the systemd journal.
+ Create the drop-in file "/etc/tmpfiles.d/zzz-systemd-stig.conf" with the
+ following content:
+ Z /run/log/journal/%m ~0640 root systemd-journal - -
+ z /var/log/journal/%m 0640 root systemd-journal - -
z /var/log/journal/%m/system.journal 0640 root systemd-journal - -
- Restart the system for the changes to take effect.
+ Note: Restart the system for these settings to take effect.
{{%- endif %}}
references:
@@ -55,15 +57,15 @@ template:
vars:
{{%- if 'ubuntu' in product %}}
filepath:
- - /run/log/journal/
- - /var/log/journal/
+ - /run/log/journal/
+ - /var/log/journal/
+ file_regex:
+ - ^.*$
+ - ^.*$
recursive: 'true'
- file_regex: ^.*$
uid_or_name: '0'
-
{{%- else %}}
filepath: ^/var/log/journal/.*/system.journal$
uid_or_name: '0'
filepath_is_regex: "true"
-
{{%- endif %}}
diff --git a/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/correct_owner.pass.sh b/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/correct_owner.pass.sh
new file mode 100644
index 000000000000..232a9197f2b8
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/correct_owner.pass.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+mkdir -p /run/log/journal /var/log/journal
+# Create dummy journal files so the recursive file ownership check has
+# something to scan, and make everything owned by root.
+touch /var/log/journal/system.journal
+touch /run/log/journal/system.journal
+chown -R root /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/incorrect_owner.fail.sh b/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/incorrect_owner.fail.sh
new file mode 100644
index 000000000000..ae6f5e0fa86e
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/incorrect_owner.fail.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+useradd testuser_123
+
+mkdir -p /run/log/journal
+# Create a dummy journal file owned by a user other than root so the
+# recursive file ownership check fails.
+touch /run/log/journal/system.journal
+chown testuser_123 /run/log/journal/system.journal
diff --git a/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/nested_file_owner.fail.sh b/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/nested_file_owner.fail.sh
new file mode 100644
index 000000000000..52f4fcbc3ab3
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/nested_file_owner.fail.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+id testuser_123 &>/dev/null || useradd testuser_123
+
+machine_id="$(cat /etc/machine-id)"
+mkdir -p "/run/log/journal/${machine_id}/nested/deeper"
+mkdir -p "/var/log/journal/${machine_id}/nested/deeper"
+
+touch "/run/log/journal/${machine_id}/nested/deeper/user-1000.journal"
+touch "/var/log/journal/${machine_id}/nested/deeper/user-1000.journal"
+chown testuser_123 "/run/log/journal/${machine_id}/nested/deeper/user-1000.journal"
+chown testuser_123 "/var/log/journal/${machine_id}/nested/deeper/user-1000.journal"
diff --git a/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/no_file.pass.sh b/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/no_file.pass.sh
new file mode 100644
index 000000000000..cd4ec1d9cce4
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_owner_system_journal/tests/no_file.pass.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+# Create the journal directories (root-owned) but leave them empty so the
+# recursive file ownership scan finds nothing to flag (PASS, not
+# NOTAPPLICABLE).
+mkdir -p /run/log/journal /var/log/journal
+chown root /run/log/journal /var/log/journal
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/bash/ubuntu.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/bash/ubuntu.sh
index 1e53e273926f..aed3541ccb6f 100644
--- a/linux_os/guide/system/logging/journald/file_permissions_system_journal/bash/ubuntu.sh
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/bash/ubuntu.sh
@@ -1,19 +1,3 @@
# platform = multi_platform_ubuntu
-TMPFILES_CONF="/usr/lib/tmpfiles.d/systemd.conf"
-
-if ! grep -q 'Z /var/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then
- if grep -qP "^[zZ][+]*\s+\/var\/log\/journal" "$TMPFILES_CONF"; then
- sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/var\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF"
- fi
- echo "Z /var/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF"
-fi
-
-if ! grep -q 'Z /run/log/journal ~2750 root systemd-journal - -' "$TMPFILES_CONF"; then
- if grep -qP "^[zZ][+]*\s+\/run\/log\/journal" "$TMPFILES_CONF"; then
- sed -i --follow-symlinks "s/\(^[zZ][+]*\)\(\s\+\/run\/log\/journal.*\)/# \1\2/" "$TMPFILES_CONF"
- fi
- echo "Z /run/log/journal ~2750 root systemd-journal - -" >>"$TMPFILES_CONF"
-fi
-
-systemd-tmpfiles --create
+{{{ bash_set_journal_tmpfiles(2750) }}}
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/rule.yml b/linux_os/guide/system/logging/journald/file_permissions_system_journal/rule.yml
index 7ff0f057ac5b..76c9ecf85e89 100644
--- a/linux_os/guide/system/logging/journald/file_permissions_system_journal/rule.yml
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/rule.yml
@@ -31,13 +31,18 @@ severity: medium
fixtext: |
{{%- if 'ubuntu' in product %}}
- Configure the system to set the appropriate permissions to the files and directories
- used by the systemd journal:
- Add or modify the following lines in the "/etc/tmpfiles.d/systemd.conf" file:
+ Configure the system to set the appropriate permissions to the files
+ used by the systemd journal.
+ Create the drop-in file "/etc/tmpfiles.d/zzz-systemd-stig.conf" with the following
+ content:
- z /var/log/journal/%m/system.journal 0640 root systemd-journal - -
+ z /run/log/journal 2750 root systemd-journal - -
+ Z /run/log/journal/%m ~2750 root systemd-journal - -
+ z /var/log/journal 2750 root systemd-journal - -
+ z /var/log/journal/%m 2750 root systemd-journal - -
+ z /var/log/journal/%m/system.journal 2750 root systemd-journal - -
- Restart the system for the changes to take effect.
+ Note: Restart the system for these settings to take effect.
{{%- endif %}}
references:
@@ -55,14 +60,13 @@ template:
filepath:
- /run/log/journal/
- /var/log/journal/
+ file_regex:
+ - ^.*$
+ - ^.*$
recursive: 'true'
- file_regex: ^.*$
filemode: '0640'
-
{{%- else %}}
filepath: ^/var/log/journal/.*/system.journal$
filemode: '0640'
filepath_is_regex: "true"
-
{{%- endif %}}
-
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/correct_permissions.pass.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/correct_permissions.pass.sh
new file mode 100644
index 000000000000..19a1ddf5034f
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/correct_permissions.pass.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+mkdir -p /run/log/journal /var/log/journal
+find /run/log/journal /var/log/journal -type f -exec chmod 0640 {} \;
+
+machine_id="$(cat /etc/machine-id)"
+mkdir -p "/var/log/journal/${machine_id}"
+touch "/var/log/journal/${machine_id}/system.journal"
+chmod 0640 "/var/log/journal/${machine_id}/system.journal"
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/deep_file.fail.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/deep_file.fail.sh
new file mode 100644
index 000000000000..9f8d3e10b4bf
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/deep_file.fail.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+machine_id=$(cat /etc/machine-id)
+deep_dir="/var/log/journal/${machine_id}/nested/deeper"
+
+mkdir -p "$deep_dir"
+chown root:systemd-journal "$deep_dir" "/var/log/journal/${machine_id}/nested"
+chmod 2750 "$deep_dir" "/var/log/journal/${machine_id}/nested"
+
+install -m 0750 -o root -g systemd-journal /dev/null \
+ "${deep_dir}/system@deadbeef.journal"
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/executable_file.fail.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/executable_file.fail.sh
new file mode 100755
index 000000000000..1d9f81a4877e
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/executable_file.fail.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+MACHINE_ID="$(cat /etc/machine-id)"
+JOURNAL_DIR="/var/log/journal/${MACHINE_ID}"
+JOURNAL_FILE="${JOURNAL_DIR}/user-1000@0005f97cd4a8c9b5-f088232c3718485a.journal~"
+
+mkdir -p "${JOURNAL_DIR}"
+touch "${JOURNAL_FILE}"
+chown root:systemd-journal "${JOURNAL_FILE}"
+chmod 0750 "${JOURNAL_FILE}"
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/group_writable_file.fail.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/group_writable_file.fail.sh
new file mode 100644
index 000000000000..483be2cd9b69
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/group_writable_file.fail.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+machine_id="$(cat /etc/machine-id)"
+mkdir -p "/run/log/journal/${machine_id}" "/var/log/journal/${machine_id}"
+
+touch "/run/log/journal/${machine_id}/user-1000.journal"
+touch "/var/log/journal/${machine_id}/user-1000.journal"
+chmod 0660 "/run/log/journal/${machine_id}/user-1000.journal"
+chmod 0660 "/var/log/journal/${machine_id}/user-1000.journal"
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/namespace_file.fail.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/namespace_file.fail.sh
new file mode 100644
index 000000000000..61dcbe02ced1
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/namespace_file.fail.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+machine_id=$(cat /etc/machine-id)
+namespace_dir="/var/log/journal/${machine_id}.testnamespace"
+
+mkdir -p "$namespace_dir"
+chown root:systemd-journal "$namespace_dir"
+chmod 2750 "$namespace_dir"
+
+install -m 0750 -o root -g systemd-journal /dev/null \
+ "${namespace_dir}/system.journal"
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/no_file.pass.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/no_file.pass.sh
new file mode 100644
index 000000000000..0f35063648c3
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/no_file.pass.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+mkdir -p /run/log/journal /var/log/journal
+find /run/log/journal /var/log/journal -type f -delete
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/setuid_file.fail.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/setuid_file.fail.sh
new file mode 100644
index 000000000000..733e4d0a44a5
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/setuid_file.fail.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+machine_id="$(cat /etc/machine-id)"
+mkdir -p "/run/log/journal/${machine_id}" "/var/log/journal/${machine_id}"
+
+touch "/run/log/journal/${machine_id}/user-1000.journal"
+touch "/var/log/journal/${machine_id}/user-1000.journal"
+chmod 4640 "/run/log/journal/${machine_id}/user-1000.journal"
+chmod 4640 "/var/log/journal/${machine_id}/user-1000.journal"
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/stricter_permissions.pass.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/stricter_permissions.pass.sh
new file mode 100644
index 000000000000..635f40b7674e
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/stricter_permissions.pass.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+mkdir -p /run/log/journal /var/log/journal
+find /run/log/journal /var/log/journal -type f -exec chmod 0600 {} \;
+
+machine_id="$(cat /etc/machine-id)"
+mkdir -p "/var/log/journal/${machine_id}"
+touch "/var/log/journal/${machine_id}/system.journal"
+chmod 0600 "/var/log/journal/${machine_id}/system.journal"
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/unexpected_name_file.fail.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/unexpected_name_file.fail.sh
new file mode 100644
index 000000000000..1ee2b2a23148
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/unexpected_name_file.fail.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+machine_id=$(cat /etc/machine-id)
+
+mkdir -p "/var/log/journal/${machine_id}"
+install -m 0750 -o root -g systemd-journal /dev/null \
+ "/var/log/journal/${machine_id}/leftover.log"
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/world_readable_file.fail.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/world_readable_file.fail.sh
new file mode 100644
index 000000000000..1a852acb2b05
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/world_readable_file.fail.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+machine_id="$(cat /etc/machine-id)"
+mkdir -p "/run/log/journal/${machine_id}" "/var/log/journal/${machine_id}"
+
+touch "/run/log/journal/${machine_id}/user-1000.journal"
+touch "/var/log/journal/${machine_id}/user-1000.journal"
+chmod 0644 "/run/log/journal/${machine_id}/user-1000.journal"
+chmod 0644 "/var/log/journal/${machine_id}/user-1000.journal"
diff --git a/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/world_writable_file.fail.sh b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/world_writable_file.fail.sh
new file mode 100644
index 000000000000..6ac24335d0a3
--- /dev/null
+++ b/linux_os/guide/system/logging/journald/file_permissions_system_journal/tests/world_writable_file.fail.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# platform = multi_platform_ubuntu
+
+machine_id="$(cat /etc/machine-id)"
+mkdir -p "/run/log/journal/${machine_id}" "/var/log/journal/${machine_id}"
+
+touch "/run/log/journal/${machine_id}/user-1000.journal"
+touch "/var/log/journal/${machine_id}/user-1000.journal"
+chmod 0666 "/run/log/journal/${machine_id}/user-1000.journal"
+chmod 0666 "/var/log/journal/${machine_id}/user-1000.journal"
diff --git a/shared/macros/10-bash.jinja b/shared/macros/10-bash.jinja
index 4feaa7a0bdcb..5f5b69beeddb 100644
--- a/shared/macros/10-bash.jinja
+++ b/shared/macros/10-bash.jinja
@@ -2895,3 +2895,69 @@ fi
{{{ bash_replace_or_append(login_defs_drop_in_path, line_regex_replace, value, '%s %s', cce_identifiers=cce_identifiers) }}}
{{%- endmacro %}}
+
+{{#
+ Set the ownership and permissions of the systemd journal directories
+ in tmpfiles.d drop-in.
+
+ The directory entries have to keep the executable bits, otherwise the
+ journal directories cannot be traversed. The journal files must not be
+ executable, so they need their own entries: the tilde only masks bits away,
+ so a recursive Z carrying the directory mode leaves an already executable
+ journal file executable, and the file rule then reports a finding that the
+ remediation cannot fix.
+
+ The file entries match one directory level, which is where journald keeps
+ the journal files. They match %m* rather than %m because a journal
+ namespace stores its files in /var/log/journal/MACHINE_ID.NAMESPACE, and
+ those files would otherwise only be covered by the recursive directory
+ entry and stay executable. tmpfiles.d cannot express more than one level:
+ the glob is matched one path component at a time, so there is no recursive
+ form, and the recursion of Z applies to directories as well, which would
+ strip the executable bits the journal directories need. A journal file that sits at a
+ greater depth or under an unexpected name is therefore corrected by a find
+ pass instead, because the check scans the trees recursively and would
+ otherwise report a finding that the remediation cannot fix. The tmpfiles.d
+ entries keep the ordinary layout correct across reboots, the find pass
+ repairs whatever else is already on disk.
+
+:parameter permission: permission to set on the journal directories
+:type permission: str
+:parameter file_permission: permission to set on the journal files
+:type file_permission: str
+#}}
+
+{{%- macro bash_set_journal_tmpfiles(permission, file_permission='0640') %}}
+TMPFILES_CONF="/etc/tmpfiles.d/zzz-systemd-stig.conf"
+
+mkdir -p /etc/tmpfiles.d
+touch "$TMPFILES_CONF"
+
+# Drop any previously written journal entries so stale or conflicting settings
+# in this file cannot be applied after the hardened ones.
+sed -i --follow-symlinks -E '/^\s*[zZ][+]*\s+\/(run|var)\/log\/journal/d' "$TMPFILES_CONF"
+
+# A drop-in whose name sorts after this file would be applied last and would
+# undo the hardening. Comment out journal entries in the other administrator
+# drop-ins so the hardened entries below are the effective ones.
+for conf in /etc/tmpfiles.d/*.conf /run/tmpfiles.d/*.conf; do
+ if [ -f "$conf" ] && [ "$conf" != "$TMPFILES_CONF" ]; then
+ sed -i --follow-symlinks -E 's,^(\s*[zZ][+]*\s+/(run|var)/log/journal.*),# \1,' "$conf"
+ fi
+done
+
+cat >>"$TMPFILES_CONF" <<'EOF'
+z /run/log/journal ~{{{ permission }}} root systemd-journal - -
+Z /run/log/journal ~{{{ permission }}} root systemd-journal - -
+z /run/log/journal/%m ~{{{ permission }}} root systemd-journal - -
+z /var/log/journal ~{{{ permission }}} root systemd-journal - -
+Z /var/log/journal ~{{{ permission }}} root systemd-journal - -
+z /var/log/journal/%m ~{{{ permission }}} root systemd-journal - -
+Z /run/log/journal/%m*/*.journal* ~{{{ file_permission }}} root systemd-journal - -
+Z /var/log/journal/%m*/*.journal* ~{{{ file_permission }}} root systemd-journal - -
+EOF
+
+systemd-tmpfiles --create
+
+find /run/log/journal /var/log/journal -type f -exec chmod u-x,g-wx,o-rwx {} +
+{{%- endmacro %}}