#!/usr/bin/env bash
#
# harden-ssh.sh — Passe SSH en clé-uniquement (password off), en sécurité.
#
# Filet de sécurité :
#   - `sshd -t` valide la conf AVANT reload (une conf invalide n'est jamais appliquée)
#   - reload (pas restart) => ta session courante n'est PAS coupée
#   - test automatique de reconnexion PAR CLÉ après reload (BatchMode = pas de mot de passe)
#     -> si ta clé ne passe pas, on te prévient tout de suite (tu as encore la session + la console Scaleway)
#
# Usage :  ./harden-ssh.sh [user@host]

set -uo pipefail

SRV="${1:-${SRV:-sgwsnlcupaqyxdqux@163.172.71.169}}"
CONF="${CONF:-$(cd "$(dirname "$0")" && pwd)/deploy/ssh/99-hardening.conf}"

[ -f "$CONF" ] || { echo "!! Introuvable : $CONF" >&2; exit 1; }

echo "==> Cible : $SRV"
echo "==> Vérif préalable : ta connexion actuelle est-elle bien par CLÉ ?"
if ssh -o BatchMode=yes -o ConnectTimeout=10 "$SRV" 'echo KEY_OK' 2>/dev/null | grep -q KEY_OK; then
  echo "    OK — clé SSH fonctionnelle (aucun mot de passe requis). On peut couper le password."
else
  echo "!! STOP : la connexion par clé (sans mot de passe) ÉCHOUE." >&2
  echo "   Tu te connectes probablement par MOT DE PASSE. Configure d'abord ta clé :" >&2
  echo "     ssh-copy-id $SRV" >&2
  echo "   Puis relance. (Couper le password sans clé = lockout garanti.)" >&2
  exit 1
fi
echo

scp "$CONF" "$SRV:/tmp/99-hardening.conf"

REMOTE=$(cat <<'REMOTE'
set -u
ts=$(date +%Y%m%d-%H%M%S)
DST=/etc/ssh/sshd_config.d/99-hardening.conf
[ -f "$DST" ] && sudo cp -a "$DST" "$DST.bak.$ts"
sudo install -m 644 -o root -g root /tmp/99-hardening.conf "$DST"
rm -f /tmp/99-hardening.conf

echo "===== sshd -t (validation) ====="
if ! sudo sshd -t; then
  echo ">> sshd -t ÉCHOUE : rollback, rien d'appliqué." >&2
  sudo rm -f "$DST"
  [ -f "$DST.bak.$ts" ] && sudo mv "$DST.bak.$ts" "$DST"
  exit 30
fi

sudo systemctl reload ssh
echo "===== Paramètres effectifs ====="
sudo sshd -T | grep -iE "^passwordauthentication|^permitrootlogin|^pubkeyauthentication|^authenticationmethods"
REMOTE
)

echo "==> Application (sudo demandera ton mot de passe)..."
ssh -tt "$SRV" "$REMOTE"
rc=$?
[ $rc -ne 0 ] && { echo "!! Échec (code $rc). Conf SSH inchangée."; exit $rc; }

echo
echo "==> Vérification finale (clé acceptée ET mot de passe refusé)..."
# Petit délai : l'activation par socket peut couper le listener une fraction de seconde au reload.
sleep 2

KEY_OK=no; PW_BLOCKED=no
ssh -o BatchMode=yes -o ConnectTimeout=10 "$SRV" 'true' 2>/dev/null && KEY_OK=yes

# Tentative password-only : DOIT échouer (le serveur n'offre que publickey).
# BatchMode + NumberOfPasswordPrompts=0 -> aucun prompt interactif, échec immédiat.
if ssh -o ConnectTimeout=10 -o BatchMode=yes -o NumberOfPasswordPrompts=0 \
       -o PreferredAuthentications=password -o PubkeyAuthentication=no \
       "$SRV" 'true' 2>&1 | grep -qi "Permission denied"; then
  PW_BLOCKED=yes
fi

if [ "$KEY_OK" = yes ] && [ "$PW_BLOCKED" = yes ]; then
  echo "    ✅ Clé acceptée + mot de passe refusé par le serveur. SSH durci pour de vrai."
elif [ "$KEY_OK" = yes ]; then
  echo "    ⚠️  Clé OK mais le refus du password n'a pas pu être confirmé automatiquement." >&2
  echo "       Vérifie à la main : sudo sshd -T | grep -iE 'authenticationmethods|passwordauth'" >&2
else
  echo "    ⚠️  La reconnexion par clé échoue. NE FERME PAS tes sessions ouvertes." >&2
  echo "       Rollback (session active ou console Scaleway) :" >&2
  echo "         sudo rm /etc/ssh/sshd_config.d/99-hardening.conf && sudo systemctl reload ssh" >&2
  exit 40
fi
