- Create new shell-ssh.sh module for SSH key installation and password setup * Install SSH public keys to authorized_keys (root + clawdie) * Configure sshd: disable password auth if key provided, enable if not * Set system user passwords (auto-generate or use provided) * Save emergency root password to root/.firstboot-emergency-password - Restore shell-system.sh (was accidentally overwritten during rename) Enables secure SSH-key-first access with password fallback. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
260 lines
7.9 KiB
Bash
260 lines
7.9 KiB
Bash
#!/bin/sh
|
|
# Clawdie Shell — SSH & System User Password Module
|
|
# Purpose: Configure SSH keys and system user passwords
|
|
# Author: Clawdie Project
|
|
# POSIX-compliant (no bash-isms)
|
|
|
|
set -eu
|
|
|
|
# Configuration (can be overridden for testing)
|
|
LOG_FILE="${LOG_FILE:-/var/log/clawdie-firstboot.log}"
|
|
PROGRESS_FILE="${PROGRESS_FILE:-/var/log/clawdie-firstboot.progress}"
|
|
EMERGENCY_PASSWORD_FILE="${EMERGENCY_PASSWORD_FILE:-/root/.firstboot-emergency-password}"
|
|
|
|
# Derived from wizard/build inputs (caller sets these)
|
|
# SSH_PUBLIC_KEY - Optional SSH public key (ssh-ed25519 or ssh-rsa)
|
|
# ROOT_PASSWORD - Optional root password (if empty, auto-generate)
|
|
# CLAWDIE_USER_PASSWORD - Optional clawdie user password (if empty, auto-generate)
|
|
|
|
# ============================================================================
|
|
# MAIN ENTRY POINT
|
|
# ============================================================================
|
|
|
|
clawdie_shell_ssh_setup() {
|
|
# Main orchestrator
|
|
# 1. Configure SSH keys (if provided)
|
|
# 2. Set system passwords (if provided or auto-generate)
|
|
# 3. Configure SSH auth methods (key-only or key+password)
|
|
|
|
log_msg "[ssh] Starting SSH and password setup"
|
|
|
|
# Generate emergency root password if not provided
|
|
if [ -z "${ROOT_PASSWORD:-}" ]; then
|
|
ROOT_PASSWORD=$(gen_secret)
|
|
fi
|
|
|
|
# Generate clawdie user password if not provided
|
|
if [ -z "${CLAWDIE_USER_PASSWORD:-}" ]; then
|
|
CLAWDIE_USER_PASSWORD=$(gen_secret)
|
|
fi
|
|
|
|
# Setup SSH keys if provided
|
|
if [ -n "${SSH_PUBLIC_KEY:-}" ]; then
|
|
clawdie_shell_ssh_install_pubkey
|
|
clawdie_shell_ssh_disable_password_auth
|
|
log_msg "[ssh] SSH public key installed, password auth disabled"
|
|
else
|
|
clawdie_shell_ssh_enable_password_auth
|
|
log_msg "[ssh] No SSH key provided, password auth enabled (less secure)"
|
|
fi
|
|
|
|
# Set system user passwords
|
|
clawdie_shell_ssh_set_passwords "$ROOT_PASSWORD" "$CLAWDIE_USER_PASSWORD"
|
|
log_msg "[ssh] System user passwords set"
|
|
|
|
# Save emergency root password to file
|
|
clawdie_shell_ssh_save_emergency_password "$ROOT_PASSWORD"
|
|
log_msg "[ssh] Emergency root password saved"
|
|
|
|
echo "[SSH] COMPLETE" >> "$PROGRESS_FILE"
|
|
log_msg "[ssh] SSH setup complete"
|
|
}
|
|
|
|
# ============================================================================
|
|
# SSH PUBLIC KEY INSTALLATION
|
|
# ============================================================================
|
|
|
|
clawdie_shell_ssh_install_pubkey() {
|
|
# Install SSH_PUBLIC_KEY to authorized_keys for both root and clawdie user
|
|
|
|
local root_ssh_dir="/root/.ssh"
|
|
local clawdie_ssh_dir="/home/clawdie/.ssh"
|
|
|
|
# Setup root authorized_keys
|
|
if [ ! -d "$root_ssh_dir" ]; then
|
|
mkdir -p "$root_ssh_dir"
|
|
chmod 700 "$root_ssh_dir"
|
|
fi
|
|
|
|
echo "$SSH_PUBLIC_KEY" >> "$root_ssh_dir/authorized_keys" 2>/dev/null || {
|
|
log_msg "[ssh] ERROR: Failed to install SSH key for root"
|
|
return 1
|
|
}
|
|
|
|
chmod 600 "$root_ssh_dir/authorized_keys"
|
|
log_msg "[ssh] Installed SSH key for root user"
|
|
|
|
# Setup clawdie authorized_keys
|
|
if [ ! -d "$clawdie_ssh_dir" ]; then
|
|
mkdir -p "$clawdie_ssh_dir"
|
|
chmod 700 "$clawdie_ssh_dir"
|
|
fi
|
|
|
|
echo "$SSH_PUBLIC_KEY" >> "$clawdie_ssh_dir/authorized_keys" 2>/dev/null || {
|
|
log_msg "[ssh] ERROR: Failed to install SSH key for clawdie"
|
|
return 1
|
|
}
|
|
|
|
chmod 600 "$clawdie_ssh_dir/authorized_keys"
|
|
chown -R clawdie:clawdie "$clawdie_ssh_dir"
|
|
log_msg "[ssh] Installed SSH key for clawdie user"
|
|
|
|
return 0
|
|
}
|
|
|
|
# ============================================================================
|
|
# SSH AUTH METHOD CONFIGURATION
|
|
# ============================================================================
|
|
|
|
clawdie_shell_ssh_disable_password_auth() {
|
|
# Disable password authentication in sshd_config
|
|
# Keep PubkeyAuthentication enabled
|
|
|
|
local sshd_config="/etc/ssh/sshd_config"
|
|
|
|
if [ ! -f "$sshd_config" ]; then
|
|
log_msg "[ssh] WARNING: sshd_config not found"
|
|
return 1
|
|
fi
|
|
|
|
# Ensure PubkeyAuthentication is enabled
|
|
if grep -q "^#*PubkeyAuthentication" "$sshd_config"; then
|
|
sed -i '' 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' "$sshd_config"
|
|
else
|
|
echo "PubkeyAuthentication yes" >> "$sshd_config"
|
|
fi
|
|
|
|
# Disable PasswordAuthentication
|
|
if grep -q "^#*PasswordAuthentication" "$sshd_config"; then
|
|
sed -i '' 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' "$sshd_config"
|
|
else
|
|
echo "PasswordAuthentication no" >> "$sshd_config"
|
|
fi
|
|
|
|
# Disable PermitRootLogin with password (allow pubkey only)
|
|
if grep -q "^#*PermitRootLogin" "$sshd_config"; then
|
|
sed -i '' 's/^#*PermitRootLogin.*/PermitRootLogin prohibit-password/' "$sshd_config"
|
|
else
|
|
echo "PermitRootLogin prohibit-password" >> "$sshd_config"
|
|
fi
|
|
|
|
log_msg "[ssh] Disabled password auth in sshd_config"
|
|
return 0
|
|
}
|
|
|
|
clawdie_shell_ssh_enable_password_auth() {
|
|
# Enable password authentication in sshd_config (fallback)
|
|
# Less secure but prevents lockout if user loses SSH key
|
|
|
|
local sshd_config="/etc/ssh/sshd_config"
|
|
|
|
if [ ! -f "$sshd_config" ]; then
|
|
log_msg "[ssh] WARNING: sshd_config not found"
|
|
return 1
|
|
fi
|
|
|
|
# Enable PasswordAuthentication
|
|
if grep -q "^#*PasswordAuthentication" "$sshd_config"; then
|
|
sed -i '' 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' "$sshd_config"
|
|
else
|
|
echo "PasswordAuthentication yes" >> "$sshd_config"
|
|
fi
|
|
|
|
# Allow root login with password
|
|
if grep -q "^#*PermitRootLogin" "$sshd_config"; then
|
|
sed -i '' 's/^#*PermitRootLogin.*/PermitRootLogin yes/' "$sshd_config"
|
|
else
|
|
echo "PermitRootLogin yes" >> "$sshd_config"
|
|
fi
|
|
|
|
log_msg "[ssh] WARNING: Password auth enabled (less secure)"
|
|
return 0
|
|
}
|
|
|
|
# ============================================================================
|
|
# PASSWORD MANAGEMENT
|
|
# ============================================================================
|
|
|
|
clawdie_shell_ssh_set_passwords() {
|
|
local root_pwd="$1"
|
|
local clawdie_pwd="$2"
|
|
|
|
# Set root password using echo | pw usermod
|
|
echo "$root_pwd" | pw usermod root -h 0 2>/dev/null || {
|
|
log_msg "[ssh] ERROR: Failed to set root password"
|
|
return 1
|
|
}
|
|
|
|
log_msg "[ssh] Root password set"
|
|
|
|
# Set clawdie user password
|
|
# Create user if it doesn't exist
|
|
if ! id clawdie >/dev/null 2>&1; then
|
|
pw useradd -n clawdie -u 1000 -g wheel -m -s /bin/sh 2>/dev/null || {
|
|
log_msg "[ssh] ERROR: Failed to create clawdie user"
|
|
return 1
|
|
}
|
|
log_msg "[ssh] Created clawdie user"
|
|
fi
|
|
|
|
echo "$clawdie_pwd" | pw usermod clawdie -h 0 2>/dev/null || {
|
|
log_msg "[ssh] ERROR: Failed to set clawdie password"
|
|
return 1
|
|
}
|
|
|
|
log_msg "[ssh] Clawdie user password set"
|
|
return 0
|
|
}
|
|
|
|
clawdie_shell_ssh_save_emergency_password() {
|
|
local root_pwd="$1"
|
|
|
|
# Save emergency password to file (root-only, readable only by root)
|
|
{
|
|
echo "EMERGENCY ROOT PASSWORD"
|
|
echo "=============================="
|
|
echo ""
|
|
echo "Generated at: $(date)"
|
|
echo "Password: $root_pwd"
|
|
echo ""
|
|
echo "Access:"
|
|
echo " ssh root@<domain>"
|
|
echo ""
|
|
echo "WARNING: Store this securely."
|
|
echo "This file should be moved to secure storage and deleted from this system."
|
|
} > "$EMERGENCY_PASSWORD_FILE" 2>/dev/null || {
|
|
log_msg "[ssh] WARNING: Could not save emergency password file"
|
|
return 1
|
|
}
|
|
|
|
chmod 600 "$EMERGENCY_PASSWORD_FILE"
|
|
log_msg "[ssh] Emergency password saved to $EMERGENCY_PASSWORD_FILE"
|
|
return 0
|
|
}
|
|
|
|
# ============================================================================
|
|
# UTILITY: Logging & Secret Generation
|
|
# ============================================================================
|
|
|
|
log_msg() {
|
|
local msg="$1"
|
|
echo "$msg" >> "$LOG_FILE" 2>/dev/null || true
|
|
}
|
|
|
|
gen_secret() {
|
|
openssl rand -base64 32 | tr -d '\n/+=' | head -c 32
|
|
}
|
|
|
|
# ============================================================================
|
|
# Export for use by firstboot.sh
|
|
# ============================================================================
|
|
|
|
case "${0##*/}" in
|
|
shell-ssh.sh)
|
|
# Direct execution (for testing)
|
|
clawdie_shell_ssh_setup
|
|
;;
|
|
*)
|
|
# Sourced from another script — functions available
|
|
;;
|
|
esac
|