#!/bin/bash
# =============================================================
# persist_ssh.sh – Persistent Reverse SSH Tunnels für Wartung
# =============================================================
# Installiert zwei unabhängige systemd-Services (je ein Tunnel
# zu JUMP und ALTJ), die direkt nach dem Netzwerk-Start aktiv
# sind – vollständig unabhängig von Crontab, sshcon.sh, ini.sh.
#
# Verwendung:
#   sudo bash persist_ssh.sh [--days N] [--remove]
#
# Download & Ausführen (auf dem Player):
#   wget -q --no-check-certificate -O /tmp/persist_ssh.sh \
#     https://172.105.95.252/persist_ssh.sh \
#     && sudo bash /tmp/persist_ssh.sh
#
# Optionen:
#   --days N    Ablauf in N Tagen (Default: 7)
#   --remove    Services entfernen
#
# Nach Ablauf: Services werden automatisch deaktiviert.
# Manuell entfernen: sudo bash persist_ssh.sh --remove
# =============================================================

set -euo pipefail

# --- Konfiguration ---
JUMP_HOST="139.162.165.199"
ALTJ_HOST="85.90.244.122"
SSH_USER="snowtv"
MCID_FILE="/home/snowtv/bin/mcid.cfg"
EXPIRY_FILE="/etc/sshtunnel-expiry"
WATCHDOG_BIN="/usr/local/bin/sshtunnel-watchdog.sh"
DEFAULT_DAYS=7

# SSH-Key: bevorzuge Ed25519, fallback auf RSA; bei fehlendem Key von Server laden
DEPLOY_URL="https://172.105.95.252/cfg_files"
SSH_KEY="/home/snowtv/.ssh/id_ed25519"
if [[ -f "/home/snowtv/.ssh/id_ed25519" ]]; then
    SSH_KEY="/home/snowtv/.ssh/id_ed25519"
elif [[ -f "/home/snowtv/.ssh/id_rsa" ]]; then
    SSH_KEY="/home/snowtv/.ssh/id_rsa"
else
    echo "Kein SSH-Key gefunden – lade id_ed25519 vom Deployment-Server..."
    mkdir -p /home/snowtv/.ssh
    chmod 700 /home/snowtv/.ssh
    wget -q --no-check-certificate -O /home/snowtv/.ssh/id_ed25519 "${DEPLOY_URL}/id_ed25519"
    chmod 600 /home/snowtv/.ssh/id_ed25519
    chown snowtv:snowtv /home/snowtv/.ssh/id_ed25519
    SSH_KEY="/home/snowtv/.ssh/id_ed25519"
    echo "id_ed25519 deployt"
fi

# --- Argumente ---
DAYS=$DEFAULT_DAYS
REMOVE=false
while [[ $# -gt 0 ]]; do
    case $1 in
        --days)   DAYS="$2"; shift 2 ;;
        --remove) REMOVE=true; shift ;;
        *) echo "Unbekannter Parameter: $1"; exit 1 ;;
    esac
done

# --- Root prüfen ---
if [[ $EUID -ne 0 ]]; then
    echo "ERROR: Root erforderlich. Aufruf: sudo bash $0"
    exit 1
fi

# --- REMOVE-Modus ---
if $REMOVE; then
    echo "Entferne sshtunnel-Services..."
    systemctl stop  sshtunnel-jump.service sshtunnel-altj.service \
                    sshtunnel-watchdog.timer sshtunnel-watchdog.service 2>/dev/null || true
    systemctl disable sshtunnel-jump.service sshtunnel-altj.service \
                      sshtunnel-watchdog.timer sshtunnel-watchdog.service 2>/dev/null || true
    rm -f /etc/systemd/system/sshtunnel-jump.service
    rm -f /etc/systemd/system/sshtunnel-altj.service
    rm -f /etc/systemd/system/sshtunnel-watchdog.service
    rm -f /etc/systemd/system/sshtunnel-watchdog.timer
    rm -f "$WATCHDOG_BIN"
    rm -f "$EXPIRY_FILE"
    systemctl daemon-reload
    echo "Fertig. Alle sshtunnel-Services entfernt."
    exit 0
fi

# --- Player-ID lesen ---
if [[ ! -f "$MCID_FILE" ]]; then
    echo "ERROR: $MCID_FILE nicht gefunden"
    exit 1
fi
PLAYER_ID=$(grep '^ID=' "$MCID_FILE" | cut -d= -f2 | tr -d '[:space:]')
if [[ -z "$PLAYER_ID" ]]; then
    echo "ERROR: Player-ID konnte nicht aus $MCID_FILE gelesen werden"
    exit 1
fi
TUNNEL_PORT="10${PLAYER_ID}"

# --- Jumpserver-Plausibilisierung ---
test_port() {
    local host=$1 port=$2
    timeout 5 bash -c "echo > /dev/tcp/$host/$port" 2>/dev/null
}

echo ""
echo "Plausibilisierung Jumpserver..."
JUMP_PORT=""
ALTJ_PORT=""

for port in 22 443; do
    if test_port "$JUMP_HOST" "$port"; then
        JUMP_PORT=$port
        echo "  JUMP  $JUMP_HOST:$port  erreichbar"
        break
    fi
done
[[ -z "$JUMP_PORT" ]] && echo "  JUMP  $JUMP_HOST: nicht erreichbar (uebersprungen)"

for port in 22 443; do
    if test_port "$ALTJ_HOST" "$port"; then
        ALTJ_PORT=$port
        echo "  ALTJ  $ALTJ_HOST:$port  erreichbar"
        break
    fi
done
[[ -z "$ALTJ_PORT" ]] && echo "  ALTJ  $ALTJ_HOST: nicht erreichbar (uebersprungen)"

if [[ -z "$JUMP_PORT" && -z "$ALTJ_PORT" ]]; then
    echo "ERROR: Kein Jumpserver erreichbar. Abbruch."
    exit 1
fi

# --- autossh installieren falls nötig ---
if ! command -v autossh >/dev/null 2>&1; then
    echo "Installiere autossh..."
    apt-get install -y -q autossh
fi

# --- Ablaufzeit setzen ---
EXPIRY_TS=$(date -d "+${DAYS} days" +%s)
EXPIRY_DATE=$(date -d "+${DAYS} days" "+%Y-%m-%d %H:%M")
echo "$EXPIRY_TS" > "$EXPIRY_FILE"

# --- Systemd-Service installieren ---
install_service() {
    local name=$1
    local host=$2
    local port=$3
    local unit="/etc/systemd/system/sshtunnel-${name}.service"

    cat > "$unit" <<EOF
[Unit]
Description=Persistent Reverse SSH Tunnel ${name^^} (Player ${PLAYER_ID}, Ablauf ${EXPIRY_DATE})
After=network-online.target
Wants=network-online.target

[Service]
User=${SSH_USER}
Restart=always
RestartSec=30
ExecStart=/usr/bin/autossh -M 0 -N \
  -o StrictHostKeyChecking=no \
  -o ServerAliveInterval=30 \
  -o ServerAliveCountMax=3 \
  -o ExitOnForwardFailure=yes \
  -i ${SSH_KEY} \
  -p ${port} \
  -R ${TUNNEL_PORT}:127.0.0.1:22 \
  ${SSH_USER}@${host}

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable --now "sshtunnel-${name}.service"
    echo "  sshtunnel-${name}.service aktiv  →  ssh -p ${TUNNEL_PORT} ${SSH_USER}@${host}"
}

echo ""
echo "Installiere Services..."
[[ -n "$JUMP_PORT" ]] && install_service "jump" "$JUMP_HOST" "$JUMP_PORT"
[[ -n "$ALTJ_PORT" ]] && install_service "altj" "$ALTJ_HOST" "$ALTJ_PORT"

# --- Watchdog: Auto-Disable bei Ablauf ---
cat > "$WATCHDOG_BIN" <<'WATCHDOG'
#!/bin/bash
# sshtunnel-watchdog.sh – deaktiviert Tunnel nach Ablaufzeit
EXPIRY_FILE="/etc/sshtunnel-expiry"
LOG="/var/log/stv.log"

[[ -f "$EXPIRY_FILE" ]] || exit 0
EXPIRY_TS=$(cat "$EXPIRY_FILE")
NOW_TS=$(date +%s)

if [[ $NOW_TS -ge $EXPIRY_TS ]]; then
    MSG="$(date) persist_ssh: Ablaufzeit erreicht – deaktiviere sshtunnel-Services"
    logger -t sshtunnel-watchdog "$MSG"
    [[ -f "$LOG" ]] && echo "$MSG" >> "$LOG"

    systemctl stop    sshtunnel-jump.service sshtunnel-altj.service 2>/dev/null || true
    systemctl disable sshtunnel-jump.service sshtunnel-altj.service 2>/dev/null || true
    systemctl stop    sshtunnel-watchdog.timer 2>/dev/null || true
    systemctl disable sshtunnel-watchdog.timer 2>/dev/null || true

    logger -t sshtunnel-watchdog "Services deaktiviert. Entfernen: sudo bash persist_ssh.sh --remove"
fi
WATCHDOG
chmod +x "$WATCHDOG_BIN"

cat > /etc/systemd/system/sshtunnel-watchdog.service <<EOF
[Unit]
Description=SSH Tunnel Watchdog – Ablauf-Pruefung

[Service]
Type=oneshot
ExecStart=${WATCHDOG_BIN}
EOF

cat > /etc/systemd/system/sshtunnel-watchdog.timer <<EOF
[Unit]
Description=SSH Tunnel Watchdog Timer

[Timer]
OnBootSec=5min
OnUnitActiveSec=6h

[Install]
WantedBy=timers.target
EOF

systemctl daemon-reload
systemctl enable --now sshtunnel-watchdog.timer

# --- Zusammenfassung ---
echo ""
echo "============================================================"
echo "  Persistent SSH Tunnels installiert"
echo "  Player-ID  : ${PLAYER_ID}"
echo "  Tunnel-Port: ${TUNNEL_PORT}"
echo "  Ablauf     : ${EXPIRY_DATE} (in ${DAYS} Tagen, auto-disable)"
echo ""
echo "  Zugang:"
[[ -n "$JUMP_PORT" ]] && echo "    ssh -p ${TUNNEL_PORT} ${SSH_USER}@${JUMP_HOST}"
[[ -n "$ALTJ_PORT" ]] && echo "    ssh -p ${TUNNEL_PORT} ${SSH_USER}@${ALTJ_HOST}"
echo ""
echo "  Status pruefen : systemctl status sshtunnel-jump sshtunnel-altj"
echo "  Manuell Remove : sudo bash persist_ssh.sh --remove"
echo "============================================================"
