#!/bin/bash # Wazuh Active Response -> CrowdSec ban read INPUT SRC_IP=$(echo "$INPUT" | python3 -c " import sys, json, re try: d = json.load(sys.stdin) alert = d.get('parameters', {}).get('alert', {}) data = alert.get('data', {}) # 1. Try standard srcip field ip = data.get('srcip') or data.get('src_ip') or '' # 2. Fallback: extract first public IP from full_log if not ip: full_log = alert.get('full_log', '') ips = re.findall(r'\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b', full_log) private = re.compile(r'^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.)') for candidate in ips: if not private.match(candidate): ip = candidate break print(ip) except: print('') " 2>/dev/null) ACTION=$(echo "$INPUT" | python3 -c " import sys, json try: d = json.load(sys.stdin) print(d.get('command', 'add')) except: print('add') " 2>/dev/null) LOG=/var/ossec/logs/active-responses.log if [ -z "$SRC_IP" ] || [ "$SRC_IP" = "null" ]; then echo "$(date) crowdsec-ban: no IP found" >> "$LOG" exit 0 fi # Ne pas bannir les IPs privees / VPN if echo "$SRC_IP" | grep -qE '^10\.|^192\.168\.|^172\.(1[6-9]|2[0-9]|3[01])\.|^127\.'; then echo "$(date) crowdsec-ban: skip private IP $SRC_IP" >> "$LOG" exit 0 fi if [ "$ACTION" = "delete" ]; then /usr/local/bin/docker exec crowdsec cscli decisions delete --ip "$SRC_IP" 2>/dev/null echo "$(date) crowdsec-ban: UNBAN $SRC_IP" >> "$LOG" else /usr/local/bin/docker exec crowdsec cscli decisions add --ip "$SRC_IP" \ --duration 24h --reason Wazuh-ActiveResponse --type ban 2>&1 >> "$LOG" echo "$(date) crowdsec-ban: BAN $SRC_IP" >> "$LOG" fi