Files
ca-service/schluesseldienst_admin.sh
2025-06-15 19:13:08 +02:00

160 lines
7.4 KiB
Bash

#!/bin/bash
# --- Konfiguration (BITTE ANPASSEN!) ---
# Der Name deines rclone-Remotes für Nextcloud
# Beispiel: Wenn du in rclone config "nextcloud3" als Namen vergeben hast.
RCLONE_REMOTE="nextcloud3"
# Pfade in Nextcloud, relativ zum Root deines rclone-Remotes (z.B. nextcloud3:/)
# Hier legen Benutzer ihre Public Keys ab.
NEXTCLOUD_INCOMING_DIR="CA/Eingang"
# Hier werden die signierten Zertifikate abgelegt.
NEXTCLOUD_SIGNED_DIR="CA/Ausgang"
# Hierher werden verarbeitete Public Keys verschoben.
NEXTCLOUD_ARCHIVE_DIR="CA/Archiv"
# Lokales Verzeichnis auf dem CA-System, in dem Dateien temporär verarbeitet werden.
# Stelle sicher, dass dieses Verzeichnis existiert und für den Skript-Benutzer schreibbar ist.
LOCAL_PROCESSING_DIR="/$HOME/tmp"
# Absoluter Pfad zu deinem privaten CA-Schlüssel auf diesem System.
# WICHTIG: Dieser Schlüssel MUSS EXTREM SICHER SEIN (z.B. Berechtigungen 600, nur für den Skript-User lesbar).
CA_KEY_PATH="/$HOME/ca_key"
# Standard-Gültigkeitsdauer für die ausgestellten Zertifikate.
# Beispiele: '+1d' für 1 Tag, '+1w' für 1 Woche, '+52w' für 1 Jahr.
CERTIFICATE_VALIDITY='+10w'
USERNAME="root"
# --- Ende Konfiguration ---
# --- Funktionen ---
# Prüft, ob alle benötigten Befehle (ssh-keygen, rclone, jq) verfügbar sind.
check_dependencies() {
local missing=0
for cmd in ssh-keygen rclone jq; do
if ! command -v "$cmd" &> /dev/null; then
echo "Fehler: Befehl '$cmd' nicht gefunden. Bitte installieren Sie ihn." >&2
missing=1
fi
done
if [ "$missing" -eq 1 ]; then
exit 1
fi
}
# --- Hauptlogik ---
# Schritt 1: Prüfe Abhängigkeiten
check_dependencies
echo "--- Starte SSH CA Automatisierungs-Skript ---"
# Schritt 2: Lokales Verarbeitungsverzeichnis vorbereiten
mkdir -p "$LOCAL_PROCESSING_DIR" || { echo "Fehler: Konnte '$LOCAL_PROCESSING_DIR' nicht erstellen." >&2; exit 1; }
chmod 700 "$LOCAL_PROCESSING_DIR" # Setzt restriktive Berechtigungen
# Schritt 3: CA-Schlüssel Berechtigungen prüfen
if [ ! -f "$CA_KEY_PATH" ] || [ ! -r "$CA_KEY_PATH" ]; then
echo "Fehler: Privater CA-Schlüssel nicht gefunden oder nicht lesbar unter '$CA_KEY_PATH'." >&2
echo "Bitte stellen Sie sicher, dass die Berechtigungen (z.B. 600) korrekt gesetzt sind." >&2
exit 1
fi
echo "Suche nach neuen Public Keys im Nextcloud-Ordner '$RCLONE_REMOTE:$NEXTCLOUD_INCOMING_DIR'..."
# Schritt 4: Public Keys aus Nextcloud auflisten
# rclone lsjson gibt eine JSON-Liste der Dateien zurück.
# --files-only filtert nur Dateien, --include "*.pub" nur .pub-Dateien.
# 2>/dev/null unterdrückt rclone-Fehlermeldungen, falls das Verzeichnis leer ist.
PUBLIC_KEYS_JSON=$(rclone lsjson "$RCLONE_REMOTE:$NEXTCLOUD_INCOMING_DIR" --files-only --include "*.pub" 2>/dev/null)
# Prüfe, ob die JSON-Ausgabe leer ist oder nur "[]" enthält
if [ -z "$PUBLIC_KEYS_JSON" ] || [ "$PUBLIC_KEYS_JSON" == "[]" ]; then
echo "Keine neuen Public Keys zum Verarbeiten gefunden."
else
echo "Gefundene Public Keys:"
# Zeigt die Namen der gefundenen Dateien an (setzt 'jq' voraus).
echo "$PUBLIC_KEYS_JSON" | jq -r '.[].Name'
# Lese die Dateinamen sicher in ein Bash-Array ein.
# Dies ist entscheidend, um doppelte Verarbeitung zu vermeiden,
# da das Array eine Momentaufnahme der Dateinamen vor der Verarbeitung darstellt.
readarray -t PUBLIC_KEYS_ARRAY < <(echo "$PUBLIC_KEYS_JSON" | jq -r '.[].Name')
if [ ${#PUBLIC_KEYS_ARRAY[@]} -eq 0 ]; then
echo "Hinweis: Obwohl JSON gefunden wurde, konnten keine Dateinamen extrahiert werden (eventuell falsches Format?)." >&2
else
# Schritt 5: Iteriere und verarbeite jeden Public Key
for pub_key_filename in "${PUBLIC_KEYS_ARRAY[@]}"; do
echo "--- Verarbeite Public Key: '$pub_key_filename' ---"
# Extrahiere den Benutzernamen aus dem Dateinamen (z.B. "alf" aus "alf_id_ed25519.pub")
# USERNAME=$(echo "$pub_key_filename" | cut -d'_' -f1)
# USERNAME wird oben gesetzt!
if [ -z "$USERNAME" ]; then
echo "Warnung: Konnte Benutzernamen nicht aus Dateinamen '$pub_key_filename' extrahieren. Überspringe." >&2
continue # Springe zur nächsten Datei
fi
# Definiere lokale Pfade für den Public Key und das zukünftige Zertifikat
local_pub_key_path="${LOCAL_PROCESSING_DIR}/${pub_key_filename}"
local_cert_path="${LOCAL_PROCESSING_DIR}/${pub_key_filename%.pub}-cert.pub"
# 5.1: Public Key von Nextcloud herunterladen
echo "Lade '$pub_key_filename' von Nextcloud herunter nach '$local_pub_key_path'..." >&2
if ! rclone copy "$RCLONE_REMOTE:$NEXTCLOUD_INCOMING_DIR/$pub_key_filename" "$LOCAL_PROCESSING_DIR" --progress; then
echo "Fehler beim Herunterladen von '$pub_key_filename'. Überspringe diesen Schlüssel." >&2
rm -f "$local_pub_key_path" "$local_cert_path" # Aufräumen, falls teilweise heruntergeladen
continue
fi
# 5.2: Public Key signieren
echo "Signiere Schlüssel für Benutzer '$USERNAME'..." >&2
# ssh-keygen fragt nach der Passphrase, wenn der CA-Schlüssel passwortgeschützt ist.
ssh-keygen -s "$CA_KEY_PATH" -V "$CERTIFICATE_VALIDITY" -n "$USERNAME" -I "CA für ${USERNAME}" "$local_pub_key_path" 2>&1
if [ $? -ne 0 ]; then
echo "Fehler beim Signieren von '$pub_key_filename'. Überspringe diesen Schlüssel." >&2
rm -f "$local_pub_key_path" "$local_cert_path" # Aufräumen
continue
fi
echo "Schlüssel erfolgreich signiert: '$local_cert_path'." >&2
# 5.3: Signiertes Zertifikat nach Nextcloud hochladen
echo "Lade signiertes Zertifikat '$local_cert_path' nach Nextcloud hoch zu '$RCLONE_REMOTE:$NEXTCLOUD_SIGNED_DIR'..." >&2
if ! rclone copy "$local_cert_path" "$RCLONE_REMOTE:$NEXTCLOUD_SIGNED_DIR" --progress; then
echo "Fehler beim Hochladen des signierten Zertifikats '$local_cert_path'. Überspringe diesen Schlüssel." >&2
rm -f "$local_pub_key_path" "$local_cert_path" # Aufräumen
continue
fi
# 5.4: Ursprünglichen Public Key nach der Verarbeitung archivieren
echo "Verschiebe Public Key '$pub_key_filename' nach '$RCLONE_REMOTE:$NEXTCLOUD_ARCHIVE_DIR'..." >&2
if ! rclone move "$RCLONE_REMOTE:$NEXTCLOUD_INCOMING_DIR/$pub_key_filename" "$RCLONE_REMOTE:$NEXTCLOUD_ARCHIVE_DIR" --progress; then
echo "Warnung: Konnte Public Key '$pub_key_filename' nicht nach '$RCLONE_REMOTE:$NEXTCLOUD_ARCHIVE_DIR' verschieben." >&2
else
echo "Public Key '$pub_key_filename' nach '$RCLONE_REMOTE:$NEXTCLOUD_ARCHIVE_DIR' verschoben." >&2
fi
# 5.5: Lokale temporäre Dateien aufräumen
rm -f "$local_pub_key_path" "$local_cert_path"
echo "Lokale temporäre Dateien für '$pub_key_filename' entfernt." >&2
done # Ende der for-Schleife
fi # Ende if [ ${#PUBLIC_KEYS_ARRAY[@]} -eq 0 ]
echo "--- Alle Public Keys verarbeitet. ---"
fi # Ende if [ -z "$PUBLIC_KEYS_JSON" ]
# Schritt 6: Lokales Verarbeitungsverzeichnis aufräumen
# rmdir entfernt nur leere Verzeichnisse. 2>/dev/null || true unterdrückt Fehler.
rmdir "$LOCAL_PROCESSING_DIR" 2>/dev/null || true
echo "--- SSH CA Automatisierungs-Skript beendet. ---"
exit 0