161 lines
4.8 KiB
Bash
Executable File
161 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# setup-ssh-access.sh
|
|
# Benutzung:
|
|
# ./setup-ssh-access.sh user@host[:port] [--key ~/.ssh/id_rsa] [--remote-gen]
|
|
#
|
|
# Beispiele:
|
|
# ./setup-ssh-access.sh alice@example.com
|
|
# ./setup-ssh-access.sh alice@example.com:2222 --key ~/.ssh/my_rsa --remote-gen
|
|
|
|
set -euo pipefail
|
|
|
|
# Defaults
|
|
KEY_PRIV="${HOME}/.ssh/id_rsa"
|
|
KEY_PUB="${KEY_PRIV}.pub"
|
|
REMOTE=""
|
|
PORT=""
|
|
REMOTE_GEN=false
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $0 user@host[:port] [--key /path/to/key] [--remote-gen]
|
|
|
|
--key / -k : private key path (default: ~/.ssh/id_rsa). The script will look for the .pub next to it.
|
|
--remote-gen : if set, the script will also generate (~/.ssh/id_rsa) on the remote account if missing.
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
# simple arg parse
|
|
if [ $# -lt 1 ]; then usage; fi
|
|
|
|
# first arg is remote
|
|
REMOTE_ARG="$1"
|
|
shift || true
|
|
|
|
# parse user@host[:port]
|
|
if [[ "$REMOTE_ARG" =~ ^([^@]+@[^:]+):?([0-9]+)?$ ]]; then
|
|
REMOTE="${BASH_REMATCH[1]}"
|
|
if [ -n "${BASH_REMATCH[2]}" ]; then
|
|
PORT="${BASH_REMATCH[2]}"
|
|
fi
|
|
else
|
|
echo "Ungültiger Ziel-Host: $REMOTE_ARG"
|
|
usage
|
|
fi
|
|
|
|
# handle rest params
|
|
while (( "$#" )); do
|
|
case "$1" in
|
|
--key|-k)
|
|
shift
|
|
KEY_PRIV="${1:-}"
|
|
KEY_PUB="${KEY_PRIV}.pub"
|
|
;;
|
|
--remote-gen)
|
|
REMOTE_GEN=true
|
|
;;
|
|
--help|-h)
|
|
usage
|
|
;;
|
|
*)
|
|
echo "Unbekannter Parameter: $1"
|
|
usage
|
|
;;
|
|
esac
|
|
shift || true
|
|
done
|
|
|
|
SSH_OPTS=()
|
|
if [ -n "$PORT" ]; then
|
|
SSH_OPTS+=("-p" "$PORT")
|
|
fi
|
|
# reduce interactive host key prompt on modern OpenSSH; accept-new allows first-time add.
|
|
SSH_OPTS+=("-o" "StrictHostKeyChecking=accept-new" "-o" "UserKnownHostsFile=${HOME}/.ssh/known_hosts")
|
|
|
|
echo "Ziel: $REMOTE ${PORT:+Port=$PORT}"
|
|
echo "Schlüssel (priv): $KEY_PRIV"
|
|
echo "Schlüssel (pub) : $KEY_PUB"
|
|
$REMOTE_GEN && echo "Remote key generation: aktiviert"
|
|
|
|
# 1) lokal: existenz prüfen, ggf. erzeugen
|
|
if [ ! -f "$KEY_PUB" ]; then
|
|
echo "Lokaler Public-Key fehlt. Erzeuge RSA 4096 ohne Passphrase: $KEY_PRIV"
|
|
mkdir -p "$(dirname "$KEY_PRIV")"
|
|
# Achtung: erzeugt key ohne passphrase (-N "")
|
|
ssh-keygen -t rsa -b 4096 -f "$KEY_PRIV" -C "$(whoami)@$(hostname)-$(date +%Y%m%d)" -N "" || {
|
|
echo "ssh-keygen fehlgeschlagen."; exit 2;
|
|
}
|
|
else
|
|
echo "Lokaler Public-Key vorhanden: $KEY_PUB"
|
|
fi
|
|
|
|
# 2) optional: entfernten Account Schlüssel erzeugen (nur falls --remote-gen)
|
|
if [ "$REMOTE_GEN" = true ]; then
|
|
echo "Prüfe / erzeuge SSH-Key auf entfernten Benutzerkonto (falls nicht vorhanden)..."
|
|
# Erzeuge mit -f ~/.ssh/id_rsa ohne Passphrase falls nicht existiert.
|
|
ssh "${SSH_OPTS[@]}" "$REMOTE" bash -s <<'REMOTE_CMD'
|
|
set -e
|
|
mkdir -p ~/.ssh
|
|
chmod 700 ~/.ssh
|
|
if [ ! -f ~/.ssh/id_rsa ]; then
|
|
echo "ssh-key auf remote nicht gefunden -> erzeuge ~/.ssh/id_rsa (ohne passphrase)"
|
|
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" -C "$(whoami)@$(hostname)-remote" || exit 1
|
|
else
|
|
echo "Remote bereits mit Schlüsselpaar ausgestattet: ~/.ssh/id_rsa existiert"
|
|
fi
|
|
REMOTE_CMD
|
|
fi
|
|
|
|
# 3) Schlüssel auf remote kopieren: bevorzugt ssh-copy-id falls installiert
|
|
if command -v ssh-copy-id >/dev/null 2>&1; then
|
|
echo "Benutze ssh-copy-id (falls verfügbar) um Public Key zu kopieren..."
|
|
# ssh-copy-id erwartet die public key (handle port)
|
|
if [ -n "$PORT" ]; then
|
|
# ssh-copy-id hat -p, aber auf manchen Plattformen nicht; fallback per SSH+cat
|
|
if ssh-copy-id -p "$PORT" -i "$KEY_PUB" "${REMOTE}" >/dev/null 2>&1; then
|
|
echo "ssh-copy-id erfolgreich."
|
|
else
|
|
echo "ssh-copy-id mit -p schlug fehl oder ist nicht kompatibel -> fallback"
|
|
# fallthrough to manual method below
|
|
COPY_FALLBACK=true
|
|
fi
|
|
else
|
|
if ssh-copy-id -i "$KEY_PUB" "${REMOTE}"; then
|
|
echo "ssh-copy-id erfolgreich."
|
|
COPY_FALLBACK=false
|
|
else
|
|
echo "ssh-copy-id schlug fehl -> fallback"
|
|
COPY_FALLBACK=true
|
|
fi
|
|
fi
|
|
else
|
|
COPY_FALLBACK=true
|
|
fi
|
|
|
|
# 4) fallback: sichere Methode: auf remote ~/.ssh anlegen und Datei anhängen
|
|
if [ "${COPY_FALLBACK:-true}" = true ]; then
|
|
echo "Benutze Fallback: Public Key per SSH anhängen..."
|
|
# send public key content to remote and append to ~/.ssh/authorized_keys
|
|
# We use a safe here-doc redirection so permissions can be set server-side
|
|
ssh "${SSH_OPTS[@]}" "$REMOTE" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" || {
|
|
echo "Fehler beim Erstellen von ~/.ssh auf Remote"; exit 3;
|
|
}
|
|
|
|
# Append (avoid duplicates)
|
|
PUB_CONTENT="$(cat "$KEY_PUB")"
|
|
# check duplicate and append only if not present
|
|
ssh "${SSH_OPTS[@]}" "$REMOTE" bash -s <<REMOTE_CHECK
|
|
set -e
|
|
AUTHORIZED="\$HOME/.ssh/authorized_keys"
|
|
grep -qxF "$PUB_CONTENT" "\$AUTHORIZED" 2>/dev/null || echo "$PUB_CONTENT" >> "\$AUTHORIZED"
|
|
chmod 600 "\$AUTHORIZED"
|
|
REMOTE_CHECK
|
|
fi
|
|
|
|
echo "Fertig. Versuche, dich mit dem neuen Key einzuloggen:"
|
|
echo " ssh ${PORT:+-p $PORT }$REMOTE"
|
|
echo "Hinweis: Falls du eine Passphrase möchtest, kannst du die lokale Key mit ssh-keygen -p ändern."
|
|
|
|
exit 0
|