Skip to content

Commit

Permalink
feat: use generator vs static drop-in for rescue/emergency services
Browse files Browse the repository at this point in the history
This uses a systemd-generator to replace the static drop-ins which
provide SYSTEMD_SULOGIN_FORCE=1 for rescue.service and
emergency.service.

This improves security by not grantng a root shell upon fsck-failure,
for example. This respects password protected bootloaders and should
be compatible with hardening efforts such as:
coreos/fedora-coreos-tracker#805
  • Loading branch information
bsherman authored and cgwalters committed Feb 15, 2024
1 parent 68b7cbd commit dfc0604
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/bash

# This systemd.generator(7) detects if rescue or emergency targets were
# requested from the kernel cmdline; if so, it overrides the respective
# target to set force sulogin, allowing use of rescue/emergency targets
# on systems with locked root password (as is Fedora default).
#
# This does NOT bypass locked root password on a fsck failure, but WILL
# bypass when rescue/emergency targets are chosen from kernel cmdline.
# Since this requires console/grub access, it is assumed to be at least
# as secure as a user reset of the root password using grub to modify
# the kernel cmdline with init=/bin/bash .
#
# NOTE: the SYSTEMD_SULOGIN_FORCE method used here does not bypass any
# assigned password; root password is only bypassed when locked/unset.

export PATH="/usr/bin:/usr/sbin:${PATH}"
if [ -n "$1" ]; then
# If invoked with arguments (not testing) log to kmsg
# https://github.com/systemd/systemd/issues/15638
exec 1>/dev/kmsg; exec 2>&1
fi

# If invoked with no arguments (for testing) write to /tmp
UNIT_DIR="${1:-/tmp}"

set -euo pipefail

have_some_karg() {
local args=("$@")
IFS=" " read -r -a cmdline <<< "$(</proc/cmdline)"
local i
for i in "${cmdline[@]}"; do
for a in "${args[@]}"; do
if [[ "$i" == "$a" ]]; then
return 0
fi
done
done
return 1
}

write_dropin() {
local service="$1"

local out_dir="${UNIT_DIR}/${service}.service.d"
mkdir -p "${out_dir}"

# /tmp isn't r/w yet, and the shell needs to cache the here-document
TMPDIR=/run
cat > "${out_dir}/sulogin-force.conf" <<EOF
# Automatically created by coreos-sulogin-force-generator
[Service]
Environment=SYSTEMD_SULOGIN_FORCE=1
EOF
echo "$(basename ${0}): set SYSTEMD_SULOGIN_FORCE=1 for ${service}.service"
}

# Match kernel command line targets for systemd(1) rescue/emergency
# Ignores 'rd.' prefixed targets since they enter the dracut ramdisk
# environment which does not interact with installed system root user.
if have_some_karg 'systemd.unit=rescue.target' rescue single s S 1; then
write_dropin rescue
elif have_some_karg 'systemd.unit=emergency.target' emergency '-b' ; then
write_dropin emergency
fi

This file was deleted.

This file was deleted.

0 comments on commit dfc0604

Please sign in to comment.