Defer USB enrollment until owner provisioning completes
This commit is contained in:
1 parent
54bacefbf4
commit
67d173c9f9
5 files changed
+85
-29
No files matched your search
@@ -747,12 +747,6 @@ create_user() {
|
||||
echo "%wheel ALL=(ALL:ALL) ALL" >/etc/sudoers.d/00-omarchy-wheel
|
||||
chmod 440 /etc/sudoers.d/00-omarchy-wheel
|
||||
|
||||
if omarchy-pkg-present usbguard; then
|
||||
source "$OMARCHY_PATH/install/helpers/usb-authorization.sh"
|
||||
usb_authorization_add_user "$username"
|
||||
systemctl try-restart usbguard.service
|
||||
fi
|
||||
|
||||
source "$OMARCHY_PATH/install/helpers/browser-policy.sh"
|
||||
for dir in "${BROWSER_POLICY_MANAGED_DIRS[@]}"; do
|
||||
[[ -d $dir || -L $dir ]] || continue
|
||||
@@ -1040,6 +1034,12 @@ run_provisioning() {
|
||||
limine-update
|
||||
fi
|
||||
|
||||
if omarchy-pkg-present usbguard; then
|
||||
log_step "enrolling the owner's USB devices"
|
||||
source "$OMARCHY_PATH/install/helpers/usb-authorization.sh"
|
||||
usb_authorization_provision_owner "$username"
|
||||
fi
|
||||
|
||||
log_step "cleaning up provisioning state"
|
||||
cleanup_oem_state
|
||||
log_step "first-boot setup complete"
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
echo "Configure USB device authorization"
|
||||
|
||||
# A deferred install has only the builder's peripherals attached. The owner
|
||||
# needs working input before there is an account or a session for approvals.
|
||||
if [[ -z ${OMARCHY_INSTALL_USER:-} ]]; then
|
||||
systemctl disable usbguard.service
|
||||
return 0
|
||||
fi
|
||||
|
||||
rules_file="${OMARCHY_USB_AUTHORIZATION_RULES_FILE:-/etc/usbguard/rules.conf}"
|
||||
daemon_config="${OMARCHY_USB_AUTHORIZATION_DAEMON_CONFIG:-/etc/usbguard/usbguard-daemon.conf}"
|
||||
|
||||
@@ -7,21 +14,10 @@ source "$OMARCHY_INSTALL/helpers/usb-authorization.sh"
|
||||
usb_authorization_require_secure_settings "$daemon_config"
|
||||
|
||||
if [[ ! -s $rules_file ]]; then
|
||||
policy=$(mktemp "${TMPDIR:-/tmp}/omarchy-usb-policy.XXXXXXXXXX")
|
||||
chmod 600 "$policy"
|
||||
|
||||
if usb_authorization_generate_policy "$policy"; then
|
||||
install -Dm600 -o root -g root "$policy" "$rules_file"
|
||||
rm -f "$policy"
|
||||
else
|
||||
rm -f "$policy"
|
||||
return 1
|
||||
fi
|
||||
usb_authorization_install_policy "$rules_file"
|
||||
fi
|
||||
|
||||
if [[ -n ${OMARCHY_INSTALL_USER:-} ]]; then
|
||||
usb_authorization_add_user "$OMARCHY_INSTALL_USER"
|
||||
fi
|
||||
usb_authorization_add_user "$OMARCHY_INSTALL_USER"
|
||||
|
||||
# Installs are followed by a reboot, so enable the daemon without starting it
|
||||
# in the live ISO's chroot.
|
||||
|
||||
@@ -49,11 +49,11 @@ usb_authorization_require_secure_setting() {
|
||||
usb_authorization_require_secure_settings() {
|
||||
local config="$1"
|
||||
|
||||
usb_authorization_require_secure_setting "$config" ImplicitPolicyTarget block
|
||||
usb_authorization_require_secure_setting "$config" PresentDevicePolicy apply-policy
|
||||
usb_authorization_require_secure_setting "$config" InsertedDevicePolicy apply-policy
|
||||
usb_authorization_require_secure_setting "$config" AuthorizedDefault none
|
||||
usb_authorization_require_secure_setting "$config" RestoreControllerDeviceState false
|
||||
usb_authorization_require_secure_setting "$config" ImplicitPolicyTarget block || return 1
|
||||
usb_authorization_require_secure_setting "$config" PresentDevicePolicy apply-policy || return 1
|
||||
usb_authorization_require_secure_setting "$config" InsertedDevicePolicy apply-policy || return 1
|
||||
usb_authorization_require_secure_setting "$config" AuthorizedDefault none || return 1
|
||||
usb_authorization_require_secure_setting "$config" RestoreControllerDeviceState false || return 1
|
||||
}
|
||||
|
||||
usb_authorization_generate_policy() {
|
||||
@@ -85,6 +85,33 @@ usb_authorization_add_user() {
|
||||
--exceptions=listen
|
||||
}
|
||||
|
||||
usb_authorization_install_policy() {
|
||||
local rules="$1" policy status=0
|
||||
|
||||
policy=$(mktemp "${TMPDIR:-/tmp}/omarchy-usb-policy.XXXXXXXXXX") || return 1
|
||||
if usb_authorization_generate_policy "$policy"; then
|
||||
install -Dm600 -o root -g root "$policy" "$rules" || status=$?
|
||||
else
|
||||
status=1
|
||||
fi
|
||||
rm -f "$policy"
|
||||
return "$status"
|
||||
}
|
||||
|
||||
usb_authorization_provision_owner() {
|
||||
local user="$1"
|
||||
local rules="${2:-/etc/usbguard/rules.conf}"
|
||||
local config="${3:-/etc/usbguard/usbguard-daemon.conf}"
|
||||
|
||||
usb_authorization_require_secure_settings "$config" || return 1
|
||||
# Enroll the owner's hardware, replacing any policy inherited from the
|
||||
# builder. Do this only after the interactive provisioning steps finish.
|
||||
usb_authorization_install_policy "$rules" || return 1
|
||||
usb_authorization_add_user "$user" || return 1
|
||||
systemctl enable usbguard.service || return 1
|
||||
systemctl restart usbguard.service
|
||||
}
|
||||
|
||||
usb_authorization_trust_present_devices() {
|
||||
local line id
|
||||
local count=0
|
||||
|
||||
@@ -13,6 +13,8 @@ Omarchy takes security extremely seriously. This is meant to be an operating sys
|
||||
|
||||
USB device authorization is enabled by default. Omarchy uses USBGuard to trust the devices connected during installation and block USB devices it has not seen before. When a device is blocked, click the persistent notification and choose whether to allow it once, always allow it, or keep it blocked.
|
||||
|
||||
On a preinstalled machine that asks you to create your account at first boot, USB protection starts at the end of that setup. It trusts the devices connected then, so your keyboard works throughout account setup even if it differs from the installer's keyboard.
|
||||
|
||||
You can turn the protection off from _Remove > Security > USB Device Authorization_. _Setup > Security > USB Device Authorization_ turns it back on with the existing trusted-device policy.
|
||||
|
||||
Only approve hardware you recognize. A malicious USB device can forge the manufacturer, model, serial number, and device class shown during review. Permanent approval is a convenience for accessories you control, not proof of the device's identity.
|
||||
|
||||
@@ -62,7 +62,7 @@ generate-policy)
|
||||
echo 'usbguard <generate-policy>' >>"$CALLS"
|
||||
[[ ${GENERATE_FAIL:-0} == 0 ]] || exit 1
|
||||
if [[ ${GENERATE_EMPTY:-0} == 0 ]]; then
|
||||
echo 'allow id 1d6b:0002 name "Linux Foundation root hub" hash "root"'
|
||||
printf '%s\n' "${GENERATED_RULE:-allow id 1d6b:0002 name \"Linux Foundation root hub\" hash \"root\"}"
|
||||
fi
|
||||
;;
|
||||
list-devices)
|
||||
@@ -357,10 +357,8 @@ grep -Fq 'config/usb-authorization.sh' "$ROOT/install/config/all.sh" ||
|
||||
fail "fresh installs configure the USB authorization policy"
|
||||
grep -Fq 'omarchy-usb-authorization.service' "$ROOT/install/user/first-run/enable-user-units.sh" ||
|
||||
fail "fresh installs enable the USB approval watcher"
|
||||
grep -Fq 'usb_authorization_add_user "$username"' "$ROOT/bin/omarchy-provision-owner" ||
|
||||
fail "deferred provisioning grants the new owner approval access"
|
||||
grep -Fq 'systemctl try-restart usbguard.service' "$ROOT/bin/omarchy-provision-owner" ||
|
||||
fail "deferred provisioning reloads the new owner ACL"
|
||||
grep -Fq 'usb_authorization_provision_owner "$username"' "$ROOT/bin/omarchy-provision-owner" ||
|
||||
fail "deferred provisioning enrolls the owner before finishing"
|
||||
grep -Fqx 'omarchy-setup-security-usb-authorization --yes' "$ROOT/migrations/1789433473.sh" ||
|
||||
fail "existing installs enable USB authorization during migration"
|
||||
|
||||
@@ -391,6 +389,39 @@ fi
|
||||
! grep -Fq 'systemctl <enable usbguard.service>' "$calls" || fail "failed enumeration must not enable USBGuard"
|
||||
pass "fresh installation distinguishes no USB hardware from enumeration failure"
|
||||
|
||||
: >"$rules"
|
||||
: >"$calls"
|
||||
OMARCHY_INSTALL_USER="" bash -euo pipefail -c 'source "$OMARCHY_INSTALL/config/usb-authorization.sh"' >"$scratch/install-deferred-output"
|
||||
[[ ! -s $rules ]] || fail "deferred installation must not enroll the builder's hardware"
|
||||
! grep -q '^usbguard' "$calls" || fail "deferred installation must not enumerate or grant owner ACLs"
|
||||
grep -Fqx 'systemctl <disable usbguard.service>' "$calls" || fail "deferred installation leaves enforcement disabled"
|
||||
! grep -Fq 'systemctl <enable usbguard.service>' "$calls" || fail "deferred installation must not enable enforcement"
|
||||
|
||||
source "$ROOT/install/helpers/usb-authorization.sh"
|
||||
echo 'allow id 1234:0001 name "Builder keyboard" hash "builder"' >"$rules"
|
||||
owner_rule='allow id 1234:0002 name "Owner keyboard" hash "owner"'
|
||||
: >"$calls"
|
||||
GENERATED_RULE="$owner_rule" usb_authorization_provision_owner owner "$rules" "$daemon_config"
|
||||
[[ $(<"$rules") == "$owner_rule" ]] || fail "owner enrollment must replace inherited builder trust"
|
||||
grep -Fqx 'usbguard <add-user> <owner> <--devices=list,listen,modify> <--policy=list> <--exceptions=listen>' "$calls" ||
|
||||
fail "owner provisioning grants approval access"
|
||||
[[ $(tail -2 "$calls") == $'systemctl <enable usbguard.service>\nsystemctl <restart usbguard.service>' ]] ||
|
||||
fail "enforcement starts only after owner policy and ACL setup"
|
||||
|
||||
: >"$calls"
|
||||
if GENERATE_FAIL=1 usb_authorization_provision_owner owner "$rules" "$daemon_config" >"$scratch/owner-failed" 2>&1; then
|
||||
fail "owner enrollment must reject enumeration failure"
|
||||
fi
|
||||
[[ $(<"$rules") == "$owner_rule" ]] || fail "failed enrollment preserves the old policy"
|
||||
! grep -q '^systemctl' "$calls" || fail "failed owner enrollment must not enable enforcement"
|
||||
: >"$calls"
|
||||
sed 's/ImplicitPolicyTarget=block/ImplicitPolicyTarget=allow/' "$daemon_config" >"$scratch/insecure-daemon.conf"
|
||||
if usb_authorization_provision_owner owner "$rules" "$scratch/insecure-daemon.conf" >"$scratch/owner-insecure" 2>&1; then
|
||||
fail "owner enrollment rejects insecure settings even when called in a conditional"
|
||||
fi
|
||||
[[ ! -s $calls ]] || fail "invalid settings must prevent all enrollment changes"
|
||||
pass "deferred installs enroll owner hardware before enabling enforcement"
|
||||
|
||||
malicious_rule='block id 07a6:8513 name "$(touch '"$scratch"'/injected)" hash "attacker" with-interface 02:06:00'
|
||||
export BLOCKED_DEVICE_RULE="$malicious_rule"
|
||||
notification_count=$(grep -c '^notification' "$calls" || true)
|
||||
|
||||
Reference in new issue
Block a user