#!/bin/bash # Red-team: Resilience/chaos — retry storms, partial failure, cache desync, config stale SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../config.sh" OUT="$OUT/resilience" mkdir -p "$OUT" echo '=== RESILIENCE & CHAOS RED-TEAM ===' | tee "$OUT/summary.txt" # Retry storm simulation (rapid reconnects without completing) echo '--- Connection Retry Storm (20 parallel half-open) ---' | tee -a "$OUT/summary.txt" for i in $(seq 1 20); do curl -sk -o /dev/null --max-time 2 --connect-timeout 1 "$TARGET/" &>/dev/null & done wait echo 'Retry storm complete — check if server is still responsive' | tee -a "$OUT/summary.txt" resp=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 10 "$TARGET/") echo "[$resp] Server response after storm" | tee -a "$OUT/summary.txt" # Slow Loris style — keep connections open with slow headers (test connection limit) echo '' | tee -a "$OUT/summary.txt" echo '--- Slow Client (large response streaming) ---' | tee -a "$OUT/summary.txt" resp=$(curl -sk -o /dev/null -w '%{http_code} %{time_total}' --max-time 15 --limit-rate 1 "$TARGET/") echo "[$resp] Slow download test" | tee -a "$OUT/summary.txt" # Cache desync — different Accept headers same URL echo '' | tee -a "$OUT/summary.txt" echo '--- Cache Desync via Accept Header ---' | tee -a "$OUT/summary.txt" r1=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 10 -H 'Accept: application/json' "$TARGET/") r2=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 10 -H 'Accept: text/html' "$TARGET/") r3=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 10 -H 'Accept: */*' "$TARGET/") echo "[$r1] Accept: application/json" | tee -a "$OUT/summary.txt" echo "[$r2] Accept: text/html" | tee -a "$OUT/summary.txt" echo "[$r3] Accept: */*" | tee -a "$OUT/summary.txt" # Rate-limit cascade — send exactly at limit, then burst to check cascade echo '' | tee -a "$OUT/summary.txt" echo '--- Rate Limit Cascade Test (80 rapid requests) ---' | tee -a "$OUT/summary.txt" declare -A rcounts for i in $(seq 1 80); do code=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 3 "$TARGET/") rcounts[$code]=$(( ${rcounts[$code]:-0} + 1 )) done for code in "${!rcounts[@]}"; do echo " HTTP $code: ${rcounts[$code]} times" | tee -a "$OUT/summary.txt" done # Circuit breaker test — rapid 404 errors to trip circuit echo '' | tee -a "$OUT/summary.txt" echo '--- Circuit Breaker Trip (repeated 404s) ---' | tee -a "$OUT/summary.txt" declare -A cbcounts for i in $(seq 1 30); do code=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 5 "$TARGET/nonexistent-$RANDOM") cbcounts[$code]=$(( ${cbcounts[$code]:-0} + 1 )) done for code in "${!cbcounts[@]}"; do echo " HTTP $code: ${cbcounts[$code]} times" | tee -a "$OUT/summary.txt" done resp=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 10 "$TARGET/") echo "[$resp] Server still responds after 404 storm" | tee -a "$OUT/summary.txt" cat "$OUT/summary.txt"