#!/usr/bin/env bash
# Refresh OpenSnitch C2 threat-feed blocklists. Runs as USER (no root). Fail-safe: keep last-good on any error.
set -uo pipefail
DIR=/var/lib/opensnitch-c2-feeds
UA="opensnitch-c2-feed/1.0 (+dev-workstation)"
TMP=$(mktemp -d) || exit 1
trap 'rm -rf "$TMP"' EXIT
fail=0

fetch(){ curl -fsS -m 45 -A "$UA" "$1" -o "$2"; }

# validate line count within sane bounds, then atomic install; else keep last-good
install_list(){ # $1=tmpfile $2=destname $3=minlines $4=maxlines
  local t="$1" name="$2" min="$3" max="$4" n
  n=$(grep -cvE '^\s*$' "$t" 2>/dev/null); n=${n:-0}
  if [ "$n" -lt "$min" ] || [ "$n" -gt "$max" ]; then
    echo "SKIP  $name ($n entries out of [$min,$max]) — keeping last-good"; fail=1; return
  fi
  mv -f "$t" "$DIR/$name" && chmod 644 "$DIR/$name" && echo "OK    $name ($n entries)"
}

# 1) FireHOL level1 (CIDR + IP, '#' comments)
if fetch "https://iplists.firehol.org/files/firehol_level1.netset" "$TMP/fh"; then
  grep -vE '^\s*(#|$)' "$TMP/fh" > "$TMP/firehol1.netset"
  install_list "$TMP/firehol1.netset" firehol1.netset 100 100000
else echo "FETCH-FAIL firehol"; fail=1; fi

# 2) Spamhaus DROP (JSONL, .cidr field)
if fetch "https://www.spamhaus.org/drop/drop_v4.json" "$TMP/sh"; then
  node -e 'const fs=require("fs");let o=[];for(const l of fs.readFileSync(process.argv[1],"utf8").split("\n")){if(!l.trim())continue;try{const j=JSON.parse(l);if(j.cidr)o.push(j.cidr);}catch{}}process.stdout.write(o.join("\n"))' "$TMP/sh" > "$TMP/spamhaus.netset"
  install_list "$TMP/spamhaus.netset" spamhaus-drop.netset 100 50000
else echo "FETCH-FAIL spamhaus"; fail=1; fi

# 3) Feodo Tracker active C2 (IPs)
if fetch "https://feodotracker.abuse.ch/downloads/ipblocklist.txt" "$TMP/fe"; then
  grep -vE '^\s*(#|$)' "$TMP/fe" | grep -E '^[0-9]' > "$TMP/feodo.netset"
  install_list "$TMP/feodo.netset" feodo.netset 1 10000
else echo "FETCH-FAIL feodo"; fail=1; fi

# 4) SSLBL botnet C2 (IPs; may be legitimately empty)
if fetch "https://sslbl.abuse.ch/blacklist/sslipblacklist.txt" "$TMP/ss"; then
  grep -vE '^\s*(#|$)' "$TMP/ss" | grep -E '^[0-9]' > "$TMP/sslbl.netset" || true
  install_list "$TMP/sslbl.netset" sslbl.netset 0 10000
else echo "FETCH-FAIL sslbl"; fail=1; fi

echo "done (fail=$fail)"; ls -la "$DIR" 2>/dev/null
exit 0
