#!/usr/bin/env bash
# =============================================================================
# Fidelitas — Wazuh Agent Installer — Ubuntu Server (22.04 / 24.04)
# Instalación local desde paquete .deb ubicado en el mismo directorio.
#
# USO:   sudo bash wazuh-agent-ubuntu-server.sh
# REQS:  root | TCP 192.168.121.31:1514,1515 accesible | .deb en la misma carpeta
# =============================================================================

set -euo pipefail

# Obtener la ruta de la carpeta desde donde se ejecuta este script
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEB_PACKAGE="${SCRIPT_DIR}/wazuh-agent_4.14.7-1_amd64.deb"

# ════════════════════════════════════════════════════════════════════════════════
#  CONFIGURACIÓN — EDITAR ANTES DE EJECUTAR
# ════════════════════════════════════════════════════════════════════════════════

WAZUH_MANAGER="www.fidelitas.ai"
AGENT_NAME="$(hostname -f)"
AGENT_GROUP="cloud-linux-servers"

# Directorios a monitorear con FIM
MONITOR_DIRS=(
    "/etc"
    "/usr/bin"
    "/usr/sbin"
    "/var/log"
    "/var/www/html"
    "/home/develop"
)

# Servicios systemd a monitorear
MONITOR_SERVICES=(
    "ssh"
    "ufw"
    "cron"
)

# ════════════════════════════════════════════════════════════════════════════════
#  SCRIPT — NO MODIFICAR
# ════════════════════════════════════════════════════════════════════════════════

log()  { printf '[%s] %s\n' "$(date '+%H:%M:%S')" "$*"; }
ok()   { printf '[%s] \033[32m✓\033[0m %s\n' "$(date '+%H:%M:%S')" "$*"; }
err()  { printf '[%s] \033[31m✗\033[0m %s\n' "$(date '+%H:%M:%S')" "$*" >&2; }
die()  { err "$*"; exit 1; }

[[ $EUID -ne 0 ]] && die "Ejecutar como root: sudo bash $0"

log "Fidelitas — Wazuh Agent Install (Modo Local) — Ubuntu Server"
log "Manager: ${WAZUH_MANAGER} | Agente: ${AGENT_NAME} | Grupo: ${AGENT_GROUP}"

# ── Verificar conectividad al manager ─────────────────────────────────────────
log "Verificando conectividad con manager (${WAZUH_MANAGER}:1515)..."
if ! bash -c "echo >/dev/tcp/${WAZUH_MANAGER}/1515" 2>/dev/null; then
    die "No se puede alcanzar ${WAZUH_MANAGER}:1515 — verificar firewall/VPN"
fi
ok "Conectividad OK"

# ── Instalar paquete localmente ───────────────────────────────────────────────
if dpkg -s wazuh-agent &>/dev/null; then
    INSTALLED_VER=$(dpkg-query -W -f='${Version}' wazuh-agent)
    ok "wazuh-agent ya instalado (${INSTALLED_VER}) — actualizando config"
else
    log "Verificando archivo del paquete local..."
    if [ ! -f "$DEB_PACKAGE" ]; then
        die "No se encontró el paquete .deb en: ${DEB_PACKAGE}. Descárgalo o verifica el nombre."
    fi
    
    log "Instalando wazuh-agent desde el paquete local..."
    dpkg -i "$DEB_PACKAGE"
    ok "Paquete instalado localmente"
fi

# ── Generar ossec.conf ────────────────────────────────────────────────────────
log "Generando /var/ossec/etc/ossec.conf..."

DIRS_PY=$(printf '"%s",' "${MONITOR_DIRS[@]}" | sed 's/,$//')
SVCS_PY=$(printf '"%s",' "${MONITOR_SERVICES[@]}" | sed 's/,$//')

python3 - <<PYEOF
wazuh_manager   = "${WAZUH_MANAGER}"
agent_name      = "${AGENT_NAME}"
agent_group     = "${AGENT_GROUP}"
monitor_dirs    = [${DIRS_PY}]
monitor_svcs    = [${SVCS_PY}]

syscheck_dirs = "\n".join(
    f'    <directories check_all="yes" realtime="yes" report_changes="yes">{d}</directories>'
    for d in monitor_dirs
)

service_blocks = "\n\n".join(
    f"""  <localfile>
    <log_format>full_command</log_format>
    <alias>service-check-{svc}</alias>
    <command>systemctl is-active {svc} 2>/dev/null || echo INACTIVE</command>
    <frequency>300</frequency>
  </localfile>"""
    for svc in monitor_svcs
)

config = f"""<ossec_config>

  <client>
    <server>
      <address>{wazuh_manager}</address>
      <port>1514</port>
      <protocol>tcp</protocol>
    </server>
    <enrollment>
      <enabled>yes</enabled>
      <manager_address>{wazuh_manager}</manager_address>
      <port>1515</port>
      <agent_name>{agent_name}</agent_name>
      <groups>{agent_group}</groups>
      <delay_after_enrollment>20</delay_after_enrollment>
    </enrollment>
    <crypto_method>aes</crypto_method>
    <notify_time>10</notify_time>
    <time-reconnect>60</time-reconnect>
  </client>

  <client_buffer>
    <disabled>no</disabled>
    <queue_size>5000</queue_size>
    <events_per_second>500</events_per_second>
  </client_buffer>

  <logging>
    <log_format>plain</log_format>
  </logging>

  <syscheck>
    <disabled>no</disabled>
    <frequency>43200</frequency>
    <scan_on_start>yes</scan_on_start>
    <alert_new_files>yes</alert_new_files>
{syscheck_dirs}
    <directories check_all="yes">/bin,/sbin,/usr/bin,/usr/sbin</directories>
    <ignore>/etc/mtab</ignore>
    <ignore>/etc/adjtime</ignore>
    <ignore>/etc/resolv.conf</ignore>
  </syscheck>

  <rootcheck>
    <disabled>no</disabled>
    <check_files>yes</check_files>
    <check_trojans>yes</check_trojans>
    <check_dev>yes</check_dev>
    <check_sys>yes</check_sys>
    <check_pids>yes</check_pids>
    <check_ports>yes</check_ports>
    <check_if>yes</check_if>
    <frequency>43200</frequency>
    <skip_nfs>yes</skip_nfs>
  </rootcheck>

  <wodle name="cis-cat">
    <disabled>yes</disabled>
  </wodle>

  <wodle name="osquery">
    <disabled>yes</disabled>
  </wodle>

  <wodle name="syscollector">
    <disabled>no</disabled>
    <interval>1h</interval>
    <scan_on_start>yes</scan_on_start>
    <hardware>yes</hardware>
    <os>yes</os>
    <network>yes</network>
    <packages>yes</packages>
    <ports all="no">yes</ports>
    <processes>yes</processes>
  </wodle>

  <sca>
    <enabled>yes</enabled>
    <scan_on_start>yes</scan_on_start>
    <interval>12h</interval>
    <skip_nfs>yes</skip_nfs>
  </sca>

  <active-response>
    <disabled>no</disabled>
  </active-response>

  <localfile>
    <log_format>journald</log_format>
    <location>journald</location>
  </localfile>

  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/syslog</location>
  </localfile>

  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/auth.log</location>
  </localfile>

  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/dpkg.log</location>
  </localfile>

  <localfile>
    <log_format>command</log_format>
    <alias>df -P</alias>
    <command>df -P</command>
    <frequency>360</frequency>
  </localfile>

  <localfile>
    <log_format>full_command</log_format>
    <alias>netstat</alias>
    <command>ss -tlnp</command>
    <frequency>360</frequency>
  </localfile>

{service_blocks}

</ossec_config>
"""

with open("/var/ossec/etc/ossec.conf", "w") as f:
    f.write(config)

print("ossec.conf generado correctamente")
PYEOF

ok "ossec.conf generado"

# ── Permisos ──────────────────────────────────────────────────────────────────
chown root:wazuh /var/ossec/etc/ossec.conf
chmod 640 /var/ossec/etc/ossec.conf

# ── Habilitar y arrancar ──────────────────────────────────────────────────────
log "Habilitando servicio wazuh-agent..."
systemctl daemon-reload
systemctl enable wazuh-agent
systemctl restart wazuh-agent
ok "Servicio wazuh-agent activo"

sleep 5
STATUS=$(systemctl is-active wazuh-agent 2>/dev/null || echo "unknown")
if [[ "$STATUS" == "active" ]]; then
    ok "Agente corriendo correctamente"
else
    err "Servicio en estado: ${STATUS}"
    exit 1
fi
