Files
raspi-backup/02_setup_ssh.sh
2025-12-30 23:52:08 +01:00

149 lines
4.5 KiB
Bash

#!/usr/bin/env bash
set -Eeuo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
CFG="$SCRIPT_DIR/config.sh"
[[ -f "$CFG" ]] || { echo "ERROR: config.sh fehlt: $CFG (erst 01_setup.sh ausführen)"; exit 1; }
# shellcheck disable=SC1090
source "$CFG"
RUN_USER="${SUDO_USER:-$USER}"
APP="raspi-backup"
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/${APP}"
LOG_FILE="${STATE_DIR}/${APP}.log"
mkdir -p "$STATE_DIR"
log(){ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE" >/dev/null; }
die(){ log "ERROR: $*"; echo "ERROR: $*" >&2; exit 1; }
need_cmd(){ command -v "$1" >/dev/null 2>&1 || die "Fehlt: $1"; }
need_root(){ [[ "${EUID:-$(id -u)}" -eq 0 ]] || die "Bitte mit sudo starten: sudo $SCRIPT_DIR/02_setup_ssh.sh"; }
host_short(){ hostname -s 2>/dev/null || hostname 2>/dev/null || echo "raspi"; }
nas_alias(){ echo "${ALIAS_PREFIX}-$(host_short)"; }
need_root
need_cmd ssh
need_cmd ssh-keygen
need_cmd tee
need_cmd awk
need_cmd mktemp
: "${NAS_HOST:?}" "${NAS_USER:?}" "${NAS_PORT:?}" "${KEY_TYPE:?}" "${ALIAS_PREFIX:?}" "${NAS_AUTH_KEYS_FILE:?}"
hn="$(host_short)"
alias="$(nas_alias)"
ssh_user="$RUN_USER"
user_home="$(eval echo "~${ssh_user}")"
[[ -d "$user_home" ]] || die "Home für User '$ssh_user' nicht gefunden."
ssh_dir="${user_home}/.ssh"
key="${ssh_dir}/id_${KEY_TYPE}_${hn}"
pub="${key}.pub"
ssh_cfg="${ssh_dir}/config"
log "SSH Setup START"
log "Run user : ${ssh_user}"
log "NAS : ${NAS_USER}@${NAS_HOST}:${NAS_PORT}"
log "Alias : ${alias}"
log "Key : ${key}"
sudo -u "$ssh_user" mkdir -p "$ssh_dir"
sudo -u "$ssh_user" chmod 700 "$ssh_dir"
sudo -u "$ssh_user" touch "$ssh_cfg"
sudo -u "$ssh_user" chmod 600 "$ssh_cfg"
if [[ ! -f "$key" ]]; then
log "Erzeuge SSH Key"
sudo -u "$ssh_user" ssh-keygen -t "$KEY_TYPE" -a 64 -f "$key" -N "" -C "${ssh_user}@${hn}"
else
log "SSH Key existiert bereits"
fi
sudo -u "$ssh_user" chmod 600 "$key" || true
sudo -u "$ssh_user" chmod 644 "$pub" || true
BEGIN_MARK="# BEGIN ${APP} ${alias}"
END_MARK="# END ${APP} ${alias}"
block_content="$(cat <<EOF
${BEGIN_MARK}
Host ${alias}
HostName ${NAS_HOST}
User ${NAS_USER}
Port ${NAS_PORT}
IdentityFile ${key}
IdentitiesOnly yes
ServerAliveInterval 30
ServerAliveCountMax 3
${END_MARK}
EOF
)"
log "Pflege SSH Alias Block (ersetzt/aktualisiert falls vorhanden)..."
# tmp-Datei als Zieluser anlegen
tmp_cfg="$(sudo -u "$ssh_user" mktemp)"
trap 'rm -f "$tmp_cfg" >/dev/null 2>&1 || true' EXIT
# ✅ WICHTIG: awk + Umleitung laufen komplett als Zieluser
sudo -u "$ssh_user" bash -c '
set -Eeuo pipefail
b="$1"; e="$2"; src="$3"; dst="$4"
awk -v b="$b" -v e="$e" '"'"'
$0==b {skip=1; next}
$0==e {skip=0; next}
skip==0 {print}
'"'"' "$src" > "$dst"
' _ "$BEGIN_MARK" "$END_MARK" "$ssh_cfg" "$tmp_cfg"
printf "\n%s\n" "$block_content" | sudo -u "$ssh_user" tee -a "$tmp_cfg" >/dev/null
sudo -u "$ssh_user" cat "$tmp_cfg" > "$ssh_cfg"
log "Lerne NAS Hostkey für User '${ssh_user}' (known_hosts aktualisieren)…"
sudo -u "$ssh_user" ssh \
-p "$NAS_PORT" \
-o StrictHostKeyChecking=accept-new \
-o ConnectTimeout=10 \
"${NAS_USER}@${NAS_HOST}" "true" >/dev/null \
|| die "Hostkey-Initialisierung (User) fehlgeschlagen"
log "Lerne NAS Hostkey zusätzlich für root (sauber via accept-new)…"
sudo mkdir -p /root/.ssh
sudo chmod 700 /root/.ssh
sudo ssh \
-p "$NAS_PORT" \
-i "$key" \
-o IdentitiesOnly=yes \
-o BatchMode=yes \
-o StrictHostKeyChecking=accept-new \
-o ConnectTimeout=10 \
"${NAS_USER}@${NAS_HOST}" "true" >/dev/null \
|| die "Hostkey-Initialisierung (root) fehlgeschlagen"
log "Installiere Public Key auf NAS"
sudo -u "$ssh_user" ssh -p "$NAS_PORT" "${NAS_USER}@${NAS_HOST}" "set -e
f='${NAS_AUTH_KEYS_FILE}'
d=\$(dirname \"\$f\")
mkdir -p \"\$d\"
touch \"\$f\"
chmod 600 \"\$f\"
" || die "Vorbereitung authorized_keys auf NAS fehlgeschlagen"
pubkey="$(sudo -u "$ssh_user" cat "$pub")"
if sudo -u "$ssh_user" ssh -p "$NAS_PORT" "${NAS_USER}@${NAS_HOST}" \
"grep -qxF \"$pubkey\" '${NAS_AUTH_KEYS_FILE}'" >/dev/null 2>&1; then
log "Public Key ist auf NAS schon vorhanden"
else
log "Hänge Public Key an authorized_keys an"
sudo -u "$ssh_user" ssh -p "$NAS_PORT" "${NAS_USER}@${NAS_HOST}" \
"printf '%s\n' \"$pubkey\" >> '${NAS_AUTH_KEYS_FILE}'" \
|| die "Anhängen des Public Keys fehlgeschlagen"
fi
log "SSH Setup OK"
echo "SSH Setup OK"
echo "Test:"
echo " sudo -u ${ssh_user} ssh ${alias} 'echo hello'"
echo " sudo ssh -p ${NAS_PORT} -i ${key} -o BatchMode=yes -o StrictHostKeyChecking=yes ${NAS_USER}@${NAS_HOST} 'echo hello'"