Files
dejima-devbox-hardener/test/units.bats
T
branderson 38a8df5d5a Add the audit timer, and the guard against naming a path twice
The timer exists because the rules it checks are edited on the hypervisor, in a console, possibly by someone not thinking about this VM at the time. A rule dragged below the DROPs or a Firewall checkbox cleared while debugging something else produces no symptom here at all: the box keeps working, it is simply no longer contained. Hourly means nobody has to remember.

The service runs reach and not all. That is a security decision rather than a tidiness one: the radius report inventories credentials by path, and a timer would write that into the journal on a schedule, where it outlives the run and is readable by anything that later gets root.

units.bats is not a straight copy. It read BIN_DIR out of install.sh, and this repository has none by design, so it now reads the one entry point. Copied unchanged it would have passed by reading a file that does not exist. Its first test also passed vacuously with no units present, because grep failing to open a file gives the same non-zero status the test was looking for; it now asserts there is something to check before checking it.
2026-08-09 23:18:46 -07:00

57 lines
2.5 KiB
Bash

#!/usr/bin/env bats
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2026 Brad Anderson
#
# The systemd units, checked against where bootstrap actually puts things.
#
# These exist because the failure they guard has no symptom worth the name. A
# unit naming a program that is not there fails with 203/EXEC on every start,
# and for a timer that means the firewall silently stops being re-checked: no
# error anyone sees, nothing different on the box, and a host that looks
# configured while verifying nothing at all.
#
# In the sister repository a timer shipped that way and had never once worked
# on any host. The unit said /usr/local/bin and the installer used
# /usr/local/sbin, and nothing compared the two.
setup() {
REPO="$(cd "$BATS_TEST_DIRNAME/.." && pwd)"
T="$BATS_TEST_TMPDIR"
}
@test "no unit hard-codes a path to a program bootstrap places" {
# Assert there is something to check first. Without this the test passes
# when systemd/ is empty or absent, because grep's own failure to open a
# file also produces a non-zero status - a green test asserting nothing.
units=("$REPO"/systemd/*.service)
[ -f "${units[0]}" ] || { echo "no units to check"; false; }
# The path belongs to bootstrap. Written down a second time it can only
# agree by luck, and in the sister repository it did not.
run grep -nE '^Exec(Start|Stop)=/(usr|opt|bin|sbin)' "${units[@]}"
[ "$status" -ne 0 ]
}
@test "every unit's ExecStart resolves to the directory bootstrap uses" {
# This repository has no install.sh by design, so the value is read from
# the one entry point instead. Copying this test unchanged would have made
# it pass by reading a file that does not exist.
bin=$(sed -n 's|^BIN_DIR=${BIN_DIR:-\(.*\)}|\1|p' "$REPO/bin/dejima-devbox-bootstrap")
[ -n "$bin" ]
for u in "$REPO"/systemd/*.service; do
exe=$(sed -n 's|^ExecStart=\([^ ]*\).*|\1|p' "$u" | head -1)
[ -n "$exe" ]
# After substitution it must name a program this repository ships.
resolved="${exe/@@BIN_DIR@@/$bin}"
[ "$resolved" != "$exe" ] || { echo "$u: ExecStart is not templated: $exe"; false; }
prog="${resolved##*/}"
[ -f "$REPO/bin/$prog" ] || { echo "$u: names $prog, which bin/ does not ship"; false; }
done
}
@test "bootstrap substitutes the marker rather than copying it through" {
grep -q '@@BIN_DIR@@' "$REPO/bin/dejima-devbox-bootstrap"
# And refuses to finish if what it wrote is not executable.
grep -q 'which is not executable' "$REPO/bin/dejima-devbox-bootstrap"
}