#!/usr/bin/env bash
# suricata.sh - install/remove Suricata IDS on Debian 13 (trixie) with ET/open rules
# Usage: sudo ./suricata.sh add|remove|status   (IFACE=eth1 ./suricata.sh add to override iface)

set -euo pipefail

IFACE="${IFACE:-eth0}"
[[ $IFACE =~ ^[A-Za-z0-9._@:-]+$ ]] || { echo "invalid IFACE" >&2; exit 1; }
YAML=/etc/suricata/suricata.yaml
RULES_DIR=/var/lib/suricata/rules
LOG_DIR=/var/log/suricata
RULES_UPDATE_SERVICE=/etc/systemd/system/suricata-rules-update.service
RULES_UPDATE_TIMER=/etc/systemd/system/suricata-rules-update.timer
PIP_INSTALLED=0

# Re-exec with sudo if not root
if [[ ${EUID} -ne 0 ]]; then
    exec sudo -E "$0" "$@"
fi

usage() {
    echo "Usage: $0 {add|remove|status}"
    exit 2
}

install_rules_tool() {
    # suricata-update is not in Debian main; try apt then pip
    if command -v suricata-update >/dev/null 2>&1; then
        echo "[*] suricata-update already present"
        return 0
    fi
    echo "[*] Trying apt-get install suricata-update"
    if apt-get install -y suricata-update 2>/dev/null; then
        return 0
    fi
    echo "[*] Falling back to pip3 install --break-system-packages suricata-update"
    apt-get install -y python3 python3-pip
    pip3 install --break-system-packages suricata-update
    PIP_INSTALLED=1
}

add() {
    echo "[*] Installing Suricata"
    export DEBIAN_FRONTEND=noninteractive
    apt-get update -y || true
    apt-get install -y suricata

    echo "[*] Setting af-packet interface to ${IFACE} in ${YAML}"
    # Match any interface name (ens*, enp*, br*, ...), not just eth[0-9]+
    if grep -qE '^[[:space:]]*- interface:' "${YAML}"; then
        sed -i -E "s/^([[:space:]]*- interface: ).*/\1${IFACE}/" "${YAML}"
    else
        echo "[!] no '- interface:' entry found in ${YAML}; interface not set" >&2
    fi

    echo "[*] Installing suricata-update"
    install_rules_tool

    echo "[*] Fetching ET/open rules into ${RULES_DIR}"
    install -d -m 0755 "${RULES_DIR}"
    suricata-update
    # Point the config at the downloaded rules if not already set
    grep -q '^default-rule-path' "${YAML}" || \
        sed -i "s|^rule-files:|default-rule-path: ${RULES_DIR}\nrule-files:|" "${YAML}"

    echo "[*] Validating config"
    suricata -T -c "${YAML}" -v || echo "[!] suricata -T reported issues; check ${YAML}"

    echo "[*] Enabling suricata.service"
    systemctl enable --now suricata.service

    echo "[*] Installing weekly rule-refresh timer (suricata-rules-update.timer)"
    cat > "${RULES_UPDATE_SERVICE}" <<'EOF'
[Unit]
Description=Refresh Suricata rules with suricata-update

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'suricata-update && systemctl reload suricata'
EOF

    cat > "${RULES_UPDATE_TIMER}" <<'EOF'
[Unit]
Description=Run suricata-rules-update weekly

[Timer]
OnCalendar=weekly
Persistent=true

[Install]
WantedBy=timers.target
EOF
    systemctl daemon-reload
    systemctl enable --now suricata-rules-update.timer

    echo "[+] Suricata installed; eve.json at ${LOG_DIR}/eve.json"
}

remove() {
    echo "[*] Stopping and disabling suricata.service"
    systemctl stop suricata.service 2>/dev/null || true
    systemctl disable suricata.service 2>/dev/null || true

    echo "[*] Removing the weekly rule-refresh timer if present"
    systemctl disable --now suricata-rules-update.timer 2>/dev/null || true
    rm -f "${RULES_UPDATE_SERVICE}" "${RULES_UPDATE_TIMER}"

    echo "[*] Removing ntopng-suricata.service unit if present"
    systemctl disable --now ntopng-suricata.service 2>/dev/null || true
    rm -f /etc/systemd/system/ntopng-suricata.service
    systemctl daemon-reload

    echo "[*] Purging suricata"
    export DEBIAN_FRONTEND=noninteractive
    apt-get purge -y suricata 2>/dev/null || true

    if [[ ${PIP_INSTALLED} -eq 1 ]] || pip3 show suricata-update >/dev/null 2>&1; then
        echo "[*] Uninstalling pip-installed suricata-update"
        pip3 uninstall -y --break-system-packages suricata-update 2>/dev/null || true
    fi

    echo "[*] Removing rules and logs"
    rm -rf "${RULES_DIR}" "${LOG_DIR}" /var/lib/suricata 2>/dev/null || true
    rm -rf /etc/suricata

    echo "[*] apt-get autoremove --purge"
    apt-get autoremove --purge -y

    echo "[+] Suricata removed"
}

status() {
    echo "[*] suricata service:"
    systemctl is-active suricata.service 2>/dev/null && systemctl is-enabled suricata.service 2>/dev/null || echo "inactive/not installed"
    echo "[*] Rules:"
    if [[ -d ${RULES_DIR} ]] && ls "${RULES_DIR}"/*.rules >/dev/null 2>&1; then
        echo "$(ls "${RULES_DIR}"/*.rules | wc -l) ruleset file(s) in ${RULES_DIR}"
    else
        echo "no rules found in ${RULES_DIR}"
    fi
    echo "[*] eve.json:"
    if [[ -f ${LOG_DIR}/eve.json ]]; then
        echo "present (${LOG_DIR}/eve.json)"
    else
        echo "missing"
    fi
}

case "${1:-}" in
    add)    add ;;
    remove) remove ;;
    status) status ;;
    *)      usage ;;
esac
