211 lines
6.9 KiB
Bash
211 lines
6.9 KiB
Bash
#!/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 |