#!/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