#!/bin/bash # Prüfen, ob age installiert ist if ! command -v age >/dev/null 2>&1; then echo "Fehler: Das Tool 'age' ist nicht installiert." echo "Bitte installiere es (z.B. via 'sudo pacman -S age' oder 'apt install age')." exit 1 fi CONFIG_FILE="$HOME/.ssh/config" CONFIG_BAK="$HOME/.ssh/config.bak.$(date +%F_%T)" # URL zur VERSCHLÜSSELTEN Config in deiner Gitea-Instanz REMOTE_ENC_URL="https://git.1337733.xyz/martin/sshconfig/raw/branch/main/config.enc" echo "=== SSH Config Sync (Secured by age) ===" echo "1) Lokale Config verschlüsseln (für den Upload/Copy-Paste in Git)" echo "2) Verschlüsselte Config aus dem Git entschlüsselt im Terminal ausgeben" echo "3) Merge: Remote Config entschlüsseln & lokal FEHLENDE Hosts ergänzen" echo "4) Sync: Remote Config entschlüsseln & lokale Version EXAKT überschreiben" echo "5) Lokal: Neuen SSH-Host interaktiv anlegen" echo "=======================" read -p "Wähle eine Option (1-5): " OPTION < /dev/tty # Globale Variable für den ausgewählten Key SELECTED_KEY="" # Funktion zur interaktiven Key-Auswahl select_ssh_key() { local keys=() if [ -d "$HOME/.ssh" ]; then while IFS= read -r line; do keys+=("$line") done < <(grep -rl "PRIVATE KEY" "$HOME/.ssh" 2>/dev/null) fi if [ ${#keys[@]} -eq 0 ]; then echo "Keine SSH-Schlüssel automatisch gefunden." read -p "Pfad zum SSH-Key (manuell eingeben, leer = überspringen): " SELECTED_KEY < /dev/tty return fi echo "Gefundene SSH-Schlüssel:" echo " 0) Manuelle Eingabe (Pfad selbst tippen)" for i in "${!keys[@]}"; do printf "%2d) %s\n" "$((i+1))" "${keys[$i]}" done echo " x) Keine Änderung / Überspringen / Ohne Key" local choice read -p "Wähle einen Schlüssel (0-${#keys[@]} oder x): " choice < /dev/tty if [[ "$choice" == "x" || "$choice" == "X" || -z "$choice" ]]; then SELECTED_KEY="" elif [[ "$choice" == "0" ]]; then read -p "Pfad zum SSH-Key (manuell eingeben): " SELECTED_KEY < /dev/tty elif [[ "$choice" -ge 1 && "$choice" -le ${#keys[@]} ]]; then SELECTED_KEY="${keys[$((choice-1))]}" else echo "Ungültige Auswahl, keine Änderung vorgenommen." SELECTED_KEY="" fi } # Hilfsfunktion für Option 3 und 4 replace_identity_file() { local target_file="$1" echo "" echo "--- Lokale Anpassung (IdentityFile) ---" select_ssh_key if [ -n "$SELECTED_KEY" ]; then sed -i "s|^[ \t]*IdentityFile.*| IdentityFile $SELECTED_KEY|" "$target_file" echo "Erfolg: Alle IdentityFile-Einträge wurden für diesen PC auf '$SELECTED_KEY' geändert." else echo "Info: IdentityFile-Einträge wurden nicht verändert." fi } case $OPTION in 1) if [ ! -f "$CONFIG_FILE" ]; then echo "Fehler: $CONFIG_FILE nicht gefunden!" exit 1 fi echo "age wird dich nun nach einem Verschlüsselungskennwort fragen..." age -p -a -o config.enc "$CONFIG_FILE" < /dev/tty echo "Erfolg: Die Datei wurde als 'config.enc' (Textformat) erstellt." ;; 2) echo "--- Entschlüsselte Config ---" TMP_ENC=$(mktemp) curl -sL "$REMOTE_ENC_URL" -o "$TMP_ENC" age -d "$TMP_ENC" < /dev/tty rm -f "$TMP_ENC" echo "-----------------------------" ;; 3) TMP_ENC=$(mktemp) TMP_DEC=$(mktemp) echo "Lade Git-Config herunter..." curl -sL "$REMOTE_ENC_URL" -o "$TMP_ENC" echo "age benötigt nun das Kennwort..." if ! age -d "$TMP_ENC" > "$TMP_DEC" < /dev/tty; then echo "Fehler: Entschlüsselung fehlgeschlagen (falsches Passwort oder Download fehlerhaft)." rm -f "$TMP_ENC" "$TMP_DEC" exit 1 fi rm -f "$TMP_ENC" # Aufräumen der verschlüsselten Temp-Datei replace_identity_file "$TMP_DEC" mkdir -p "$HOME/.ssh" && touch "$CONFIG_FILE" echo "Suche nach fehlenden Einträgen..." awk -v local_conf="$CONFIG_FILE" ' BEGIN { print_block = 0 } /^Host / { cmd = "grep -q \"^Host " $2 "$\" \"" local_conf "\"" if (system(cmd) == 0) { print_block = 0 } else { print_block = 1 print "\n# Merged from Git" } } { if (print_block == 1) print $0 }' "$TMP_DEC" >> "$CONFIG_FILE" chmod 600 "$CONFIG_FILE" echo "Erfolg: Fehlende Einträge wurden an $CONFIG_FILE angehängt." rm -f "$TMP_DEC" ;; 4) TMP_ENC=$(mktemp) TMP_DEC=$(mktemp) echo "Lade Git-Config herunter..." curl -sL "$REMOTE_ENC_URL" -o "$TMP_ENC" echo "age benötigt nun das Kennwort..." if ! age -d "$TMP_ENC" > "$TMP_DEC" < /dev/tty; then echo "Fehler: Entschlüsselung fehlgeschlagen." rm -f "$TMP_ENC" "$TMP_DEC" exit 1 fi rm -f "$TMP_ENC" replace_identity_file "$TMP_DEC" if [ -f "$CONFIG_FILE" ]; then cp "$CONFIG_FILE" "$CONFIG_BAK" echo "Backup der lokalen Config unter $CONFIG_BAK erstellt." fi mkdir -p "$HOME/.ssh" mv "$TMP_DEC" "$CONFIG_FILE" chmod 600 "$CONFIG_FILE" echo "Erfolg: Lokale Config wurde exakt mit der Git-Version synchronisiert." ;; 5) echo "--- Neuen Host anlegen ---" read -p "Host Alias (z.B. 'webserver' oder 'pi'): " NEW_HOST < /dev/tty if [ -z "$NEW_HOST" ]; then echo "Fehler: Der Host Alias darf nicht leer sein." exit 1 fi read -p "HostName (IP-Adresse oder Domain): " NEW_HOSTNAME < /dev/tty read -p "Benutzername (User, z.B. 'root'): " NEW_USER < /dev/tty read -p "Port (Standard: 22 - Einfach Enter drücken): " NEW_PORT < /dev/tty NEW_PORT=${NEW_PORT:-22} echo "" echo "Wähle das IdentityFile für diesen Host:" select_ssh_key NEW_KEY="$SELECTED_KEY" read -p "Soll ServerAliveInterval gesetzt werden? (j/n): " ADD_ALIVE < /dev/tty mkdir -p "$HOME/.ssh" chmod 700 "$HOME/.ssh" touch "$CONFIG_FILE" chmod 600 "$CONFIG_FILE" { echo "" echo "Host $NEW_HOST" [ -n "$NEW_HOSTNAME" ] && echo " HostName $NEW_HOSTNAME" [ -n "$NEW_USER" ] && echo " User $NEW_USER" echo " Port $NEW_PORT" [ -n "$NEW_KEY" ] && echo " IdentityFile $NEW_KEY" if [[ "$ADD_ALIVE" =~ ^[jJ]$ ]]; then echo " ServerAliveInterval 60" fi } >> "$CONFIG_FILE" echo "Erfolg: Host '$NEW_HOST' hinzugefügt." ;; *) echo "Ungültige Auswahl." exit 1 ;; esac