#!/usr/bin/env bash
#
# audit.sh — Collecte la conf & l'état d'un serveur Ubuntu (fail2ban / Nginx / UFW / Docker)
# et rapatrie le tout en local pour revue.
#
# Usage :
#   ./audit.sh                          # utilise les valeurs par défaut ci-dessous
#   ./audit.sh monserver@1.2.3.4        # override l'hôte
#   SRV=user@host ./audit.sh            # override via env
#
# Produit :
#   snapshot/outputs.txt   -> sortie de toutes les commandes d'état
#   snapshot/...           -> copies des fichiers de conf (jail.local, nginx, etc.)

set -uo pipefail

# ------------------------------------------------------------------ config
SRV="${1:-${SRV:-sgwsnlcupaqyxdqux@163.172.71.169}}"
DST="${DST:-$(cd "$(dirname "$0")" && pwd)}"   # dossier du script par défaut
SNAP="$DST/snapshot"
OUT="$SNAP/outputs.txt"

mkdir -p "$SNAP"

echo "==> Serveur : $SRV"
echo "==> Snapshot : $SNAP"
echo

# ------------------------------------------------------------------ 1. état système (outputs.txt)
echo "==> Collecte de l'état système -> $(basename "$OUT")"
echo "    (sudo va demander ton mot de passe une fois, puis il est mis en cache)"

# Script distant stocké dans une variable (heredoc quoté = aucune expansion locale),
# passé en ARGUMENT à 'ssh -tt'. Le -tt force un vrai TTY -> sudo peut s'authentifier.
# (Un heredoc sur stdin empêcherait l'allocation du TTY -> "a terminal is required".)
REMOTE_SCRIPT=$(cat <<'REMOTE'
  set +e
  hr() { printf '\n########## %s ##########\n' "$1"; }

  hr "OS";                     lsb_release -a 2>/dev/null; uname -r
  hr "SSH CONFIG";             sudo grep -E "^#?Port|^#?PermitRootLogin|^#?PasswordAuthentication" /etc/ssh/sshd_config
  hr "AUTH.LOG vs JOURNALD";   ls -l /var/log/auth.log 2>/dev/null || echo "pas de auth.log -> SSH dans journald (backend=systemd)"

  hr "UFW";                    sudo ufw status verbose; sudo ufw status numbered

  hr "FAIL2BAN VERSION";       fail2ban-client version
  hr "FAIL2BAN TEST CONF";     sudo fail2ban-client -t
  hr "FAIL2BAN JAILS";         sudo fail2ban-client status
  for j in sshd nginx-botsearch nginx-http-auth nginx-limit-req recidive; do
    echo "----- jail: $j -----"
    sudo fail2ban-client status "$j" 2>/dev/null || echo "(absent)"
  done
  hr "FAIL2BAN CONF EFFECTIVE"; sudo fail2ban-client -d 2>/dev/null | grep -E "add|set" | head -n 120

  hr "NGINX TEST";             sudo nginx -t
  hr "NGINX LOGS";             ls -lh /var/log/nginx/access.log /var/log/nginx/error.log 2>/dev/null
  hr "NGINX real_ip/limit_req"; sudo grep -R "log_format\|access_log\|limit_req\|real_ip" /etc/nginx/ 2>/dev/null

  hr "DOCKER PS";              sudo docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}" 2>/dev/null || echo "(docker absent ou non accessible)"
  hr "LISTEN HÔTE (ss)";       sudo ss -tlnp

  hr "TOP IP access.log";      sudo awk '{print $1}' /var/log/nginx/access.log 2>/dev/null | sort | uniq -c | sort -rn | head
  hr "TOP 404 paths";          sudo grep " 404 " /var/log/nginx/access.log 2>/dev/null | awk '{print $7}' | sort | uniq -c | sort -rn | head
  hr "Échecs SSH récents";     sudo journalctl -u ssh --no-pager 2>/dev/null | grep -i "failed\|invalid" | tail
REMOTE
)

# -tt force le TTY ; 2>&1 capture aussi le prompt sudo ; tr -d '\r' nettoie les retours chariot du pty.
ssh -tt "$SRV" "$REMOTE_SCRIPT" 2>&1 | tr -d '\r' | tee "$OUT"

echo
echo "==> État système collecté."
echo

# ------------------------------------------------------------------ 2. rapatriement des confs (tar via sudo -> robuste aux permissions root)
echo "==> Rapatriement des fichiers de conf..."

REMOTE_PATHS="/etc/fail2ban/jail.local \
/etc/fail2ban/jail.conf \
/etc/fail2ban/jail.d \
/etc/fail2ban/filter.d \
/etc/fail2ban/action.d \
/etc/nginx/nginx.conf \
/etc/nginx/sites-available \
/etc/nginx/sites-enabled \
/etc/nginx/conf.d"

# -h : suit les symlinks (sinon les vhosts de sites-enabled ne sont pas capturés)
ssh -tt "$SRV" "sudo tar czhf /tmp/audit-conf.tgz $REMOTE_PATHS 2>/dev/null; sudo chown \$(id -un) /tmp/audit-conf.tgz"
scp "$SRV:/tmp/audit-conf.tgz" "$SNAP/"
ssh "$SRV" "rm -f /tmp/audit-conf.tgz"

tar xzf "$SNAP/audit-conf.tgz" -C "$SNAP" && rm -f "$SNAP/audit-conf.tgz"

echo
echo "==> Terminé."
echo "    - État   : $OUT"
echo "    - Confs  : $SNAP/etc/..."
