Assert the closed session-to-root paths on an installed system — no blanket input-group membership, no shipped asdcontrol sudoers grant — and exercise omarchy-setup-security-sshd unattended end to end: sshd up, key authorized, password and keyboard-interactive authentication off in the effective config, SSH port rate limited in the firewall. The sshd section mutates the machine, so it requires the explicit OMARCHY_ACCEPTANCE_SUDO_PASSWORD opt-in that omarchy-iso-test passes for its throwaway VMs; elsewhere it skips.
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
|