64 lines
3.8 KiB
Bash
Executable file
64 lines
3.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Dealer-specific Blueforce user, restricted sudoers, mandatory administrator key.
|
|
set -euo pipefail
|
|
MODULE="03-user"
|
|
LOG_FILE="${LOG_FILE:-/var/log/blueforce-install.log}"
|
|
CHECK_MODE=0
|
|
[[ "${1:-}" == "--check" ]] && CHECK_MODE=1
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
# shellcheck source=../identity.sh
|
|
source "$SCRIPT_DIR/identity.sh"
|
|
DEALER_ID="${DEALER_ID:-}"
|
|
[[ -n "$DEALER_ID" ]] && bf_valid_dealer_id "$DEALER_ID" || { echo "FAIL: valid DEALER_ID is required" >&2; exit 1; }
|
|
BF_USER="$(bf_username "$DEALER_ID")"
|
|
BF_HOME="/home/$BF_USER"
|
|
SUDOERS_FILE="/etc/sudoers.d/$BF_USER"
|
|
AUTHORIZED_KEYS="$BF_HOME/.ssh/authorized_keys"
|
|
BF_ADMIN_PUBLIC_KEY="${BF_ADMIN_PUBLIC_KEY:-}"
|
|
BF_ADMIN_PUBLIC_KEY_FILE="${BF_ADMIN_PUBLIC_KEY_FILE:-}"
|
|
log() { echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) [03-user] $1" | tee -a "$LOG_FILE"; }
|
|
valid_key_file() { [[ -s "$AUTHORIZED_KEYS" ]] && ssh-keygen -l -f "$AUTHORIZED_KEYS" >/dev/null 2>&1; }
|
|
load_admin_key() {
|
|
[[ -z "$BF_ADMIN_PUBLIC_KEY" && -n "$BF_ADMIN_PUBLIC_KEY_FILE" && -r "$BF_ADMIN_PUBLIC_KEY_FILE" ]] || { log "FAIL: a seed-provided BF_ADMIN_PUBLIC_KEY_FILE is required; inline keys are refused"; return 1; }
|
|
[[ "$(stat -c '%U:%a' "$BF_ADMIN_PUBLIC_KEY_FILE")" =~ ^root:6[04]0$ ]] || { log "FAIL: administrator key file must be root-owned and not group/world writable"; return 1; }
|
|
grep -qE '^(ssh-(ed25519|rsa|ecdsa)|sk-ssh-ed25519)' "$BF_ADMIN_PUBLIC_KEY_FILE" && ! grep -q 'PRIVATE KEY' "$BF_ADMIN_PUBLIC_KEY_FILE" || { log "FAIL: administrator key file must contain a public SSH key only"; return 1; }
|
|
cat "$BF_ADMIN_PUBLIC_KEY_FILE"
|
|
}
|
|
if [[ "$CHECK_MODE" -eq 1 ]]; then
|
|
id "$BF_USER" >/dev/null 2>&1 || { log "FAIL(check): user $BF_USER missing"; exit 1; }
|
|
[[ -f "$SUDOERS_FILE" ]] && visudo -cf "$SUDOERS_FILE" >/dev/null 2>&1 || { log "FAIL(check): sudoers invalid"; exit 1; }
|
|
valid_key_file || { log "FAIL(check): authorized_keys is empty or invalid"; exit 1; }
|
|
log "OK(check): user, sudoers, and a valid administrator key are present"; exit 0
|
|
fi
|
|
key_data="$(load_admin_key)" || exit 1
|
|
[[ -n "${key_data//[[:space:]]/}" ]] || { log "FAIL: administrator key is empty"; exit 1; }
|
|
tmp_key="$(mktemp)"; trap 'rm -f "$tmp_key"' EXIT
|
|
printf '%s\n' "$key_data" > "$tmp_key"
|
|
ssh-keygen -l -f "$tmp_key" >/dev/null 2>&1 || { log "FAIL: supplied administrator public key is invalid"; exit 1; }
|
|
if id "$BF_USER" >/dev/null 2>&1; then
|
|
if id blueforce >/dev/null 2>&1 && [[ "$BF_USER" != blueforce ]]; then
|
|
log "FAIL: both legacy blueforce and target $BF_USER accounts exist; refusing automatic merge"
|
|
exit 1
|
|
fi
|
|
elif id blueforce >/dev/null 2>&1; then
|
|
usermod -l "$BF_USER" blueforce
|
|
if getent group blueforce >/dev/null 2>&1 && ! getent group "$BF_USER" >/dev/null 2>&1; then
|
|
groupmod -n "$BF_USER" blueforce
|
|
fi
|
|
usermod -d "$BF_HOME" -m "$BF_USER"
|
|
else
|
|
useradd -m -s /bin/bash "$BF_USER"
|
|
fi
|
|
passwd -l "$BF_USER" >/dev/null 2>&1 || true
|
|
install -d -m 700 -o "$BF_USER" -g "$BF_USER" "$BF_HOME/.ssh"
|
|
install -m 600 -o "$BF_USER" -g "$BF_USER" "$tmp_key" "$AUTHORIZED_KEYS"
|
|
valid_key_file || { log "FAIL: atomic authorized_keys install did not validate"; exit 1; }
|
|
cat > "/tmp/$BF_USER.sudoers" <<EOF
|
|
# Managed by blueforce-installer (03-user). Local edits will be overwritten.
|
|
$BF_USER ALL=(root) NOPASSWD: /usr/local/bin/bf-status, /usr/local/bin/bf-gui-on, /usr/local/bin/bf-gui-off, /bin/systemctl status *, /bin/systemctl is-active *, /bin/systemctl is-enabled *, /usr/bin/docker ps, /usr/bin/docker logs *
|
|
EOF
|
|
visudo -cf "/tmp/$BF_USER.sudoers"
|
|
install -m 440 "/tmp/$BF_USER.sudoers" "$SUDOERS_FILE"
|
|
rm -f /etc/sudoers.d/blueforce
|
|
bf_write_identity "$DEALER_ID" || { log "FAIL: dealer identity could not be locked"; exit 1; }
|
|
log "OK: user $BF_USER has a validated administrator key and restricted sudoers"
|