Files

66 lines
3.1 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Persönliches Admin-Konto fertigstellen: Passwort, TOTP (Authenticator-App) und Recovery-Keys.
# Läuft auf dem Admin-Laptop (Git-Bash). Das Konto selbst legt playbooks/cluster.yml an.
#
# platform/proxmox/scripts/pve-admin-user.sh r.rapp [pve44]
#
# Ergebnis (nie ins Repo):
# <ENV> PVE_ADMIN_<NAME>_PASS wird ergänzt, falls noch nicht vorhanden
# (Standard: C:/Users/r.rapp/it/proxmox/.env)
# <ENVDIR>/tfa-<name>.txt otpauth-URI zum Eintippen/Scannen und die Recovery-Keys (0600)
# Idempotent: Passwort nur beim ersten Lauf, TOTP/Recovery nur, wenn noch keine 2FA existiert.
set -euo pipefail
user=${1:?Benutzername ohne @pve}
node=${2:-pve44}
env_file=${PVE_ENV:-C:/Users/r.rapp/it/proxmox/.env}
out_dir=$(dirname "$env_file")
userid="${user}@pve"
var="PVE_ADMIN_$(echo "$user" | tr 'a-z.-' 'A-Z__')_PASS"
tfa_file="$out_dir/tfa-${user}.txt"
run() { ssh -T -o BatchMode=yes -o ConnectTimeout=10 "$node" "$@"; }
run "pveum user list --output-format json" | grep -q "\"userid\":\"$userid\"" \
|| { echo "FEHLER: $userid gibt es nicht – erst playbooks/cluster.yml laufen lassen" >&2; exit 1; }
# 1. Passwort (einmalig erzeugen, in .env ablegen, nie ausgeben)
if ! grep -qE "^${var}=" "$env_file"; then
pw=$(openssl rand -base64 24 | tr -d '/+=' | cut -c1-24)
printf '%s=%s\n' "$var" "$pw" >> "$env_file"
printf '%s' "$pw" | run "p=\$(cat); pvesh set /access/password --userid $userid --password \"\$p\""
echo "Passwort gesetzt und als $var in $env_file abgelegt"
else
echo "Passwort: $var ist schon in $env_file, unverändert"
fi
# 2. TOTP und Recovery-Keys, nur wenn für das Konto noch keine 2FA existiert
if run "pvesh get /access/tfa/$userid --output-format json" | grep -q '"type"'; then
echo "2FA: für $userid existiert schon ein Eintrag, nichts geändert (siehe $tfa_file)"
exit 0
fi
secret=$(openssl rand 20 | base32 | tr -d '=')
uri="otpauth://totp/knaster:${userid}?secret=${secret}&issuer=knaster&digits=6&period=30&algorithm=SHA1"
# aktuellen Code auf dem Knoten berechnen (Zeit des Knotens, kein Zusatzpaket)
code=$(run "python3 -c \"
import base64,hmac,struct,time,hashlib
s='$secret'
k=base64.b32decode(s+'='*(-len(s)%8))
h=hmac.new(k,struct.pack('>Q',int(time.time())//30),hashlib.sha1).digest()
o=h[-1]&15
print('%06d'%((struct.unpack('>I',h[o:o+4])[0]&0x7fffffff)%1000000))\"")
run "pvesh create /access/tfa/$userid --type totp --description 'Authenticator-App' --totp '$uri' --value $code" >/dev/null
keys=$(run "pvesh create /access/tfa/$userid --type recovery --description 'Recovery-Keys (offline)' --output-format json" \
| python -c 'import json,sys; print("\n".join(json.load(sys.stdin)["recovery"]))')
umask 077
{
echo "Proxmox 2FA für $userid (angelegt $(date +%F))"
echo
echo "TOTP in die Authenticator-App eintragen (QR aus der URI erzeugen oder Secret manuell eingeben):"
echo "$uri"
echo "Secret: $secret"
echo
echo "Recovery-Keys (je einmal gültig, offline aufbewahren):"
echo "$keys"
} > "$tfa_file"
echo "TOTP und Recovery-Keys angelegt: $tfa_file (0600). Anmeldung: Weboberfläche, Realm 'Proxmox VE authentication server'."