#!/bin/bash ################################################################################ # Threat Intelligence Library ################################################################################ # Purpose: External threat intelligence integration using existing tools # Features: IP reputation lookups, geolocation, whitelist management # No new services - uses only existing APIs and tools ################################################################################ # Cache directory for threat intelligence THREAT_CACHE_DIR="/var/lib/server-toolkit/threat-cache" mkdir -p "$THREAT_CACHE_DIR" 2>/dev/null # Cache TTL (24 hours) CACHE_TTL=86400 ################################################################################ # AbuseIPDB Integration (Free API - 1000 requests/day) ################################################################################ # Check if IP is in AbuseIPDB # Returns: confidence_score|total_reports|country|isp check_abuseipdb() { local ip="$1" local cache_file="$THREAT_CACHE_DIR/abuseipdb_${ip//\./_}" # Check cache first if [ -f "$cache_file" ]; then local cache_age=$(($(date +%s) - $(stat -c %Y "$cache_file" 2>/dev/null || echo 0))) if [ "$cache_age" -lt "$CACHE_TTL" ]; then cat "$cache_file" return 0 fi fi # Check if API key exists local api_key_file="/root/.abuseipdb_api_key" if [ ! -f "$api_key_file" ]; then echo "0|0|Unknown|Unknown" return 1 fi local api_key=$(cat "$api_key_file") # Query AbuseIPDB API local response=$(curl -s -G https://api.abuseipdb.com/api/v2/check \ --data-urlencode "ipAddress=$ip" \ -d maxAgeInDays=90 \ -H "Key: $api_key" \ -H "Accept: application/json" 2>/dev/null) if [ -n "$response" ]; then local confidence=$(echo "$response" | grep -oP '"abuseConfidenceScore":\K[0-9]+' 2>/dev/null | head -1) local reports=$(echo "$response" | grep -oP '"totalReports":\K[0-9]+' 2>/dev/null | head -1) local country=$(echo "$response" | grep -oP '"countryCode":"\K[^"]+' 2>/dev/null | head -1) local isp=$(echo "$response" | grep -oP '"isp":"\K[^"]+' 2>/dev/null | head -1) local result="${confidence:-0}|${reports:-0}|${country:-Unknown}|${isp:-Unknown}" echo "$result" | tee "$cache_file" return 0 fi echo "0|0|Unknown|Unknown" return 1 } ################################################################################ # Geolocation Detection (Using existing geoiplookup or geoip-bin) ################################################################################ # Get country code for IP get_country_code() { local ip="$1" local cache_file="$THREAT_CACHE_DIR/geo_${ip//\./_}" # Check cache if [ -f "$cache_file" ]; then local cache_age=$(($(date +%s) - $(stat -c %Y "$cache_file" 2>/dev/null || echo 0))) if [ "$cache_age" -lt "$CACHE_TTL" ]; then cat "$cache_file" return 0 fi fi # Try geoiplookup (if installed) if command -v geoiplookup &>/dev/null; then local country=$(geoiplookup "$ip" 2>/dev/null | head -1 | grep -oP 'GeoIP Country Edition: \K[A-Z]{2}') if [ -n "$country" ]; then echo "$country" | tee "$cache_file" return 0 fi fi # Try geoip-bin (alternative) if command -v geoiplookup6 &>/dev/null; then local country=$(geoiplookup6 "$ip" 2>/dev/null | head -1 | grep -oP 'GeoIP Country Edition: \K[A-Z]{2}') if [ -n "$country" ]; then echo "$country" | tee "$cache_file" return 0 fi fi # Fallback to whois (slower, not cached as aggressively) if command -v whois &>/dev/null; then local country=$(whois "$ip" 2>/dev/null | grep -i "^country:" | head -1 | awk '{print $2}' | tr '[:lower:]' '[:upper:]') if [ -n "$country" ] && [ ${#country} -eq 2 ]; then echo "$country" | tee "$cache_file" return 0 fi fi echo "XX" return 1 } # Check if country is high-risk is_high_risk_country() { local country="$1" # High-risk countries (commonly seen in attacks) local high_risk="CN RU UA BY KP IR VN TH ID BR" if echo "$high_risk" | grep -qw "$country"; then return 0 fi return 1 } ################################################################################ # Smart Whitelisting ################################################################################ # Check if IP should be whitelisted (legitimate services) is_whitelisted_service() { local ip="$1" local whitelist_file="/var/lib/server-toolkit/whitelist_ips.txt" # Check static whitelist if [ -f "$whitelist_file" ]; then if grep -q "^$ip$" "$whitelist_file"; then return 0 fi fi # Check if IP belongs to known legitimate networks # Google IPs (8.8.0.0/16, 66.249.64.0/19, etc.) if [[ "$ip" =~ ^8\.8\. ]] || [[ "$ip" =~ ^66\.249\. ]] || [[ "$ip" =~ ^66\.102\. ]]; then return 0 fi # Cloudflare IPs (173.245.48.0/20, 103.21.244.0/22, etc.) if [[ "$ip" =~ ^173\.245\.(4[8-9]|5[0-9]|6[0-3])\. ]] || [[ "$ip" =~ ^103\.21\.24[4-7]\. ]]; then return 0 fi # Microsoft/Bing IPs (40.0.0.0/8, 65.52.0.0/14, etc.) if [[ "$ip" =~ ^40\. ]] || [[ "$ip" =~ ^65\.5[2-5]\. ]]; then return 0 fi # Common CDN/monitoring services # Akamai: 23.0.0.0/8 if [[ "$ip" =~ ^23\. ]]; then return 0 fi return 1 } # Add IP to whitelist add_to_whitelist() { local ip="$1" local reason="$2" local whitelist_file="/var/lib/server-toolkit/whitelist_ips.txt" if ! grep -q "^$ip$" "$whitelist_file" 2>/dev/null; then echo "$ip # $reason" >> "$whitelist_file" fi } ################################################################################ # Behavioral Analysis ################################################################################ # Analyze request timing pattern # Returns: human|bot|suspicious analyze_timing_pattern() { local ip="$1" local timing_file="$THREAT_CACHE_DIR/timing_${ip//\./_}" # Record timestamp echo "$(date +%s)" >> "$timing_file" # Keep only last 100 requests tail -100 "$timing_file" > "${timing_file}.tmp" 2>/dev/null mv "${timing_file}.tmp" "$timing_file" 2>/dev/null # Analyze if we have enough data local request_count=$(wc -l < "$timing_file" 2>/dev/null || echo 0) if [ "$request_count" -lt 10 ]; then echo "unknown" return fi # Calculate average time between requests local timestamps=$(cat "$timing_file") local total_gap=0 local gap_count=0 local prev_ts="" while IFS= read -r ts; do if [ -n "$prev_ts" ]; then local gap=$((ts - prev_ts)) total_gap=$((total_gap + gap)) gap_count=$((gap_count + 1)) fi prev_ts="$ts" done <<< "$timestamps" if [ "$gap_count" -gt 0 ]; then local avg_gap=$((total_gap / gap_count)) # Bot patterns: < 2 seconds between requests consistently if [ "$avg_gap" -lt 2 ]; then echo "bot" return fi # Human patterns: 5-30 seconds between requests with variation if [ "$avg_gap" -ge 5 ] && [ "$avg_gap" -le 30 ]; then echo "human" return fi # Suspicious: Too fast but not consistent bot pattern echo "suspicious" return fi echo "unknown" } ################################################################################ # Attack Pattern Learning ################################################################################ # Record attack pattern for learning record_attack_pattern() { local ip="$1" local attack_type="$2" local uri="$3" local user_agent="$4" local pattern_file="/var/lib/server-toolkit/attack-patterns/patterns.log" mkdir -p "$(dirname "$pattern_file")" 2>/dev/null # Format: timestamp|ip|attack_type|uri|user_agent echo "$(date +%s)|$ip|$attack_type|$uri|$user_agent" >> "$pattern_file" # Keep only last 10000 patterns (prevent unbounded growth) tail -10000 "$pattern_file" > "${pattern_file}.tmp" 2>/dev/null mv "${pattern_file}.tmp" "$pattern_file" 2>/dev/null } # Check if attack matches known pattern matches_known_pattern() { local attack_type="$1" local uri="$2" local pattern_file="/var/lib/server-toolkit/attack-patterns/patterns.log" if [ ! -f "$pattern_file" ]; then return 1 fi # Check if this attack type + similar URI has been seen before local similar_count=$(grep "|$attack_type|" "$pattern_file" | grep -c "$uri" || echo 0) if [ "$similar_count" -ge 3 ]; then return 0 # Known pattern fi return 1 # New pattern } ################################################################################ # Performance Impact Monitoring ################################################################################ # Get current server load get_server_load() { # Returns: load_1min|load_5min|load_15min|cpu_count local load=$(uptime | awk -F'load average:' '{print $2}' | sed 's/,//g' | xargs) local cpu_count=$(nproc) echo "${load}|${cpu_count}" } # Check if server is under stress is_server_stressed() { local load_data=$(get_server_load) IFS='|' read -r load1 load5 load15 cpu_count <<< "$load_data" # Remove any extra spaces load1=$(echo "$load1" | awk '{print $1}') # Convert to integer (multiply by 100 to handle decimals) local load_int=$(echo "$load1 * 100" | bc 2>/dev/null | cut -d. -f1) local threshold=$((cpu_count * 80)) # 80% of CPU count if [ "$load_int" -gt "$threshold" ]; then return 0 # Server is stressed fi return 1 } ################################################################################ # Incident Report Generation ################################################################################ # Generate incident report for an IP generate_incident_report() { local ip="$1" local report_file="/var/lib/server-toolkit/incident-reports/report_${ip//\./_}_$(date +%Y%m%d_%H%M%S).txt" mkdir -p "$(dirname "$report_file")" 2>/dev/null { echo "═══════════════════════════════════════════════════════════════" echo "SECURITY INCIDENT REPORT" echo "═══════════════════════════════════════════════════════════════" echo "" echo "Generated: $(date '+%Y-%m-%d %H:%M:%S %Z')" echo "IP Address: $ip" echo "" echo "─────────────────────────────────────────────────────────────" echo "THREAT INTELLIGENCE" echo "─────────────────────────────────────────────────────────────" # AbuseIPDB data local abuse_data=$(check_abuseipdb "$ip") IFS='|' read -r confidence reports country isp <<< "$abuse_data" echo "AbuseIPDB Confidence: ${confidence}%" echo "Total Reports: $reports" echo "Country: $country" echo "ISP: $isp" echo "" # Geolocation local geo=$(get_country_code "$ip") echo "Geolocation: $geo" if is_high_risk_country "$geo"; then echo "Risk Level: HIGH (Known attack source country)" else echo "Risk Level: MEDIUM" fi echo "" echo "─────────────────────────────────────────────────────────────" echo "ATTACK HISTORY" echo "─────────────────────────────────────────────────────────────" # Get attacks from pattern log local pattern_file="/var/lib/server-toolkit/attack-patterns/patterns.log" if [ -f "$pattern_file" ]; then echo "Recent attacks from this IP:" grep "|$ip|" "$pattern_file" | tail -20 | while IFS='|' read -r ts ip_addr attack_type uri ua; do echo " [$(date -d @$ts '+%Y-%m-%d %H:%M:%S')] $attack_type - $uri" done echo "" fi echo "─────────────────────────────────────────────────────────────" echo "RECOMMENDED ACTIONS" echo "─────────────────────────────────────────────────────────────" if [ "$confidence" -ge 75 ]; then echo "• IMMEDIATE BLOCK - High confidence malicious IP" echo " Command: csf -d $ip \"AbuseIPDB: ${confidence}% confidence\"" elif [ "$reports" -ge 10 ]; then echo "• TEMPORARY BLOCK - Multiple abuse reports" echo " Command: csf -td $ip 86400 \"Multiple abuse reports\"" else echo "• MONITOR - Watch for continued activity" fi echo "" echo "═══════════════════════════════════════════════════════════════" echo "END OF REPORT" echo "═══════════════════════════════════════════════════════════════" } > "$report_file" echo "$report_file" } ################################################################################ # Multi-Server Coordination (for environments with multiple servers) ################################################################################ # Share threat data with other servers (if configured) share_threat_data() { local ip="$1" local attack_type="$2" local score="$3" local coordination_file="/var/lib/server-toolkit/shared-threats.log" # Log for potential sharing echo "$(date +%s)|$(hostname)|$ip|$attack_type|$score" >> "$coordination_file" # Keep only last 1000 entries tail -1000 "$coordination_file" > "${coordination_file}.tmp" 2>/dev/null mv "${coordination_file}.tmp" "$coordination_file" 2>/dev/null } # Check if IP is flagged by other servers check_shared_threats() { local ip="$1" local coordination_file="/var/lib/server-toolkit/shared-threats.log" if [ -f "$coordination_file" ]; then local count=$(grep "|$ip|" "$coordination_file" | wc -l) echo "$count" else echo "0" fi } ################################################################################ # Threat Intelligence Summary ################################################################################ # Get comprehensive threat intelligence for an IP get_threat_intelligence() { local ip="$1" local abuse_data=$(check_abuseipdb "$ip" 2>/dev/null || echo "0|0|Unknown|Unknown") local geo=$(get_country_code "$ip" 2>/dev/null || echo "XX") local timing=$(analyze_timing_pattern "$ip" 2>/dev/null || echo "unknown") local whitelisted="no" is_whitelisted_service "$ip" && whitelisted="yes" # Format: abuse_confidence|abuse_reports|country|isp|timing_pattern|whitelisted echo "${abuse_data}|${geo}|${timing}|${whitelisted}" } # Export functions for use in other scripts export -f check_abuseipdb export -f get_country_code export -f is_high_risk_country export -f is_whitelisted_service export -f add_to_whitelist export -f analyze_timing_pattern export -f record_attack_pattern export -f matches_known_pattern export -f get_server_load export -f is_server_stressed export -f generate_incident_report export -f share_threat_data export -f check_shared_threats export -f get_threat_intelligence