Fix the bar visibility toggle and make the acceptance suite cover 4.0.2 security hardening
(cherry picked from commit 432b5e3e24)
106 lines
4.1 KiB
Bash
Executable File
106 lines
4.1 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Verifies the security posture of an installed system: the unprivileged
|
|
# session-to-root paths closed for 4.0.2 (blanket input-group grant, shipped
|
|
# asdcontrol sudoers authorization) and the SSH hardening flow.
|
|
#
|
|
# The sshd section reconfigures the machine (enables sshd, opens the firewall,
|
|
# disables password logins), so it demands explicit opt-in: it only runs when
|
|
# OMARCHY_ACCEPTANCE_SUDO_PASSWORD is set, which omarchy-iso-test does for its
|
|
# throwaway VMs. A cached sudo timestamp alone never triggers it, so running
|
|
# the suite on a machine you care about cannot reconfigure sshd by accident.
|
|
|
|
set -euo pipefail
|
|
|
|
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
|
|
|
# Membership of `input` gives raw access to /dev/input/event*: any process
|
|
# running as the user could log keystrokes. Only the opt-in controller and
|
|
# ydotool features may grant it.
|
|
verify_input_group() {
|
|
if id -nG | grep -qw input; then
|
|
if pacman -Q xpadneo-dkms &>/dev/null || pacman -Q ydotool &>/dev/null; then
|
|
pass "input group membership is backed by an opt-in feature"
|
|
else
|
|
fail "user is not in the input group" "no controller or ydotool support installed to justify it"
|
|
fi
|
|
else
|
|
pass "user is not in the input group"
|
|
fi
|
|
}
|
|
|
|
sudo_available() {
|
|
if sudo -n true 2>/dev/null; then
|
|
return 0
|
|
fi
|
|
|
|
if [[ -n ${OMARCHY_ACCEPTANCE_SUDO_PASSWORD:-} ]]; then
|
|
printf '%s\n' "$OMARCHY_ACCEPTANCE_SUDO_PASSWORD" | sudo -S -v 2>/dev/null
|
|
return $?
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
verify_asdcontrol_sudoers() {
|
|
# Omarchy used to ship a passwordless sudoers grant for asdcontrol; that
|
|
# authorization now belongs to the package alone.
|
|
if sudo -n test -e /etc/sudoers.d/omarchy-asdcontrol; then
|
|
fail "no omarchy asdcontrol sudoers grant is shipped" "/etc/sudoers.d/omarchy-asdcontrol exists"
|
|
fi
|
|
pass "no omarchy asdcontrol sudoers grant is shipped"
|
|
}
|
|
|
|
verify_sshd_hardening() {
|
|
local key_file=/tmp/omarchy-acceptance-sshd-key
|
|
local effective_config
|
|
|
|
rm -f "$key_file" "$key_file.pub"
|
|
ssh-keygen -t ed25519 -N "" -q -C "omarchy-acceptance" -f "$key_file"
|
|
|
|
if ! omarchy-setup-security-sshd --key="$(cat "$key_file.pub")" >"$ARTIFACTS/setup-security-sshd.log" 2>&1; then
|
|
fail "omarchy-setup-security-sshd completes unattended" "$(tail -5 "$ARTIFACTS/setup-security-sshd.log")"
|
|
fi
|
|
pass "omarchy-setup-security-sshd completes unattended"
|
|
|
|
systemctl is-active sshd.service >/dev/null || fail "sshd is running after setup"
|
|
pass "sshd is running after setup"
|
|
|
|
grep -qxF "$(cat "$key_file.pub")" "$HOME/.ssh/authorized_keys" || fail "the key is authorized"
|
|
pass "the key is authorized"
|
|
|
|
# The command verifies its own hardening before keeping it, but assert the
|
|
# effective config independently: sshd honors the first value it reads, and
|
|
# regressions here reopen password logins. Keywords match case-insensitively
|
|
# because OpenSSH 9.x dumps them lowercase and 10.x in CamelCase.
|
|
effective_config=$(sudo -n sshd -T) || fail "sshd reports its effective config"
|
|
grep -qixF "passwordauthentication no" <<<"$effective_config" || fail "password authentication is off"
|
|
pass "password authentication is off"
|
|
grep -qixF "kbdinteractiveauthentication no" <<<"$effective_config" || fail "keyboard-interactive authentication is off"
|
|
pass "keyboard-interactive authentication is off"
|
|
|
|
if omarchy-cmd-present ufw; then
|
|
sudo -n ufw status | grep -qE '^22/tcp\s+LIMIT' || fail "the SSH port is rate limited in the firewall"
|
|
pass "the SSH port is rate limited in the firewall"
|
|
fi
|
|
|
|
# Leave the machine as found where cheap: the throwaway key stays useless
|
|
# once removed, while the hardening itself is the state under test.
|
|
sed -i "\#$(cat "$key_file.pub" | cut -d' ' -f2)#d" "$HOME/.ssh/authorized_keys"
|
|
rm -f "$key_file" "$key_file.pub"
|
|
}
|
|
|
|
verify_input_group
|
|
|
|
if sudo_available; then
|
|
verify_asdcontrol_sudoers
|
|
else
|
|
pass "asdcontrol sudoers check skipped: sudo needs a password"
|
|
fi
|
|
|
|
if [[ -n ${OMARCHY_ACCEPTANCE_SUDO_PASSWORD:-} ]] && sudo_available; then
|
|
verify_sshd_hardening
|
|
else
|
|
pass "sshd hardening exercise skipped: set OMARCHY_ACCEPTANCE_SUDO_PASSWORD to run it"
|
|
fi
|