#!/bin/bash # Create a local 'pveadmin' account as an emergency backdoor for when # IPA/SSSD is unavailable. The account authenticates by SSH key only # (password auth is disabled by harden-ssh.sh); the password set here # is for physical console access only. # # Idempotent - safe to re-run. If the account already exists, the SSH key # is refreshed but the password and account are left unchanged. Run as root. # # Usage: # ./create-local-backdoor.sh # ./create-local-backdoor.sh --key-file # # Set BACKDOOR_PASS env var to supply the console password non-interactively; # otherwise you will be prompted. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=lib/common.sh source "${SCRIPT_DIR}/lib/common.sh" require_root USERNAME="pveadmin" SSH_KEY="" if [ "${1:-}" = "--key-file" ]; then KEY_FILE="${2:-}" [ -z "$KEY_FILE" ] && { echo "ERROR: --key-file requires a path." >&2; exit 1; } [ -f "$KEY_FILE" ] || { echo "ERROR: key file not found: $KEY_FILE" >&2; exit 1; } SSH_KEY="$(cat "$KEY_FILE")" else SSH_KEY="${1:-}" fi if [ -z "$SSH_KEY" ]; then echo "Usage: $0 " >&2 echo " $0 --key-file " >&2 exit 1 fi if ! echo "$SSH_KEY" | grep -qE '^(ssh-rsa|ssh-ed25519|ecdsa-sha2-nistp[0-9]+) [A-Za-z0-9+/=]'; then echo "ERROR: argument doesn't look like a valid SSH public key." >&2 exit 1 fi if id "$USERNAME" >/dev/null 2>&1; then echo "User '${USERNAME}' already exists -- not modifying account or password." else useradd --create-home --shell /bin/bash "$USERNAME" echo "Created Linux user '${USERNAME}'." if [ -n "${BACKDOOR_PASS:-}" ]; then printf '%s:%s\n' "$USERNAME" "$BACKDOOR_PASS" | chpasswd echo "Console password set." else echo "Set a console password for '${USERNAME}' (used for physical console access only):" passwd "$USERNAME" fi fi HOME_DIR="$(getent passwd "$USERNAME" | cut -d: -f6)" SSH_DIR="${HOME_DIR}/.ssh" AUTH_FILE="${SSH_DIR}/authorized_keys" mkdir -p "$SSH_DIR" chmod 700 "$SSH_DIR" chown "${USERNAME}:${USERNAME}" "$SSH_DIR" if grep -qF "$SSH_KEY" "$AUTH_FILE" 2>/dev/null; then echo "SSH key already present in ${AUTH_FILE}." else printf '%s\n' "$SSH_KEY" >> "$AUTH_FILE" echo "Installed SSH key in ${AUTH_FILE}." fi chmod 600 "$AUTH_FILE" chown "${USERNAME}:${USERNAME}" "$AUTH_FILE" SUDOERS_FILE="/etc/sudoers.d/${USERNAME}-nopasswd" write_if_changed "$SUDOERS_FILE" "${USERNAME} ALL=(root) NOPASSWD: ALL" chmod 0440 "$SUDOERS_FILE" visudo -c >/dev/null echo "Sudoers rule for '${USERNAME}' is valid." echo echo "'${USERNAME}' is ready: SSH key login, NOPASSWD sudo, console password set."