#!/usr/bin/env bash # # Create a Linux user and install an SSH public key. # # This script is designed for repeatable server onboarding. It creates the user # if missing, prepares ~/.ssh, writes the authorized key, and can optionally add # the user to a sudo-capable group. # # Usage: # sudo bash linux_user_bootstrap.sh --user deploy --ssh-key "ssh-ed25519 AAAA..." # sudo bash linux_user_bootstrap.sh --user deploy --ssh-key-file ./deploy.pub --sudo # # Options: # --user NAME Linux username to create or update. # --ssh-key KEY Public SSH key content. # --ssh-key-file FILE File containing the public SSH key. # --sudo Add the user to sudo or wheel group. # --help Show this help message. set -Eeuo pipefail target_user="" ssh_key="" ssh_key_file="" grant_sudo=false usage() { sed -n '2,21p' "$0" | sed 's/^# \{0,1\}//' } log() { printf '[%s] %s\n' "$(date -Is)" "$*" } while [[ "$#" -gt 0 ]]; do case "$1" in --user) target_user="${2:-}" shift 2 ;; --ssh-key) ssh_key="${2:-}" shift 2 ;; --ssh-key-file) ssh_key_file="${2:-}" shift 2 ;; --sudo) grant_sudo=true shift ;; --help|-h) usage exit 0 ;; *) printf 'ERROR: unknown option: %s\n' "$1" >&2 usage >&2 exit 1 ;; esac done [[ "$(id -u)" -eq 0 ]] || { printf 'ERROR: this script must run as root.\n' >&2; exit 1; } [[ "$target_user" =~ ^[a-z_][a-z0-9_-]*[$]?$ ]] || { printf 'ERROR: invalid Linux username: %s\n' "$target_user" >&2; exit 1; } if [[ -n "$ssh_key_file" ]]; then [[ -f "$ssh_key_file" ]] || { printf 'ERROR: SSH key file not found: %s\n' "$ssh_key_file" >&2; exit 1; } ssh_key="$(< "$ssh_key_file")" fi [[ "$ssh_key" == ssh-* || "$ssh_key" == ecdsa-* ]] || { printf 'ERROR: a valid public SSH key is required.\n' >&2; exit 1; } if id "$target_user" >/dev/null 2>&1; then log "User already exists: ${target_user}" else log "Creating user: ${target_user}" useradd --create-home --shell /bin/bash "$target_user" fi home_dir="$(getent passwd "$target_user" | cut -d: -f6)" ssh_dir="${home_dir}/.ssh" authorized_keys="${ssh_dir}/authorized_keys" install -d -m 700 -o "$target_user" -g "$target_user" "$ssh_dir" touch "$authorized_keys" chmod 600 "$authorized_keys" chown "$target_user:$target_user" "$authorized_keys" if ! grep -qxF "$ssh_key" "$authorized_keys"; then log "Installing SSH public key for ${target_user}" printf '%s\n' "$ssh_key" >> "$authorized_keys" fi if [[ "$grant_sudo" == true ]]; then if getent group sudo >/dev/null 2>&1; then usermod -aG sudo "$target_user" log "Added ${target_user} to sudo group." elif getent group wheel >/dev/null 2>&1; then usermod -aG wheel "$target_user" log "Added ${target_user} to wheel group." else printf 'ERROR: no sudo or wheel group found.\n' >&2 exit 1 fi fi log "User bootstrap completed successfully."