flood-detector.sh 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #!/usr/local/bin/bash
  2. # Author:: Benjamin Sonntag (<benjamin _at_ sonntag _dot_ fr>)
  3. # Author:: Sebastien Badia (<seb _at_ sebian _dot_ fr>)
  4. # Author:: Philippe Le Brouster (<plb _at_ nebkha _dot_ net>)
  5. # detect flood by first counting the number of packets per second on an interface,
  6. # if the PPS is too high, search for a victim and add it to blackhole
  7. if [[ "x${DEBUG}" == "x1" ]]; then
  8. set -e
  9. set -x
  10. fi
  11. hostname=$(hostname -s)
  12. case $hostname in
  13. "zoulou")
  14. IFACE="ix0.109"
  15. ;;
  16. "yankee")
  17. IFACE="em0.179"
  18. ;;
  19. "x-ray")
  20. IFACE="ix0.115"
  21. ;;
  22. "grimoire")
  23. IFACE="eth0"
  24. ;;
  25. "whiskey")
  26. IFACE="ix0.3012"
  27. ;;
  28. "vodka")
  29. IFACE="ix0.110"
  30. ;;
  31. *)
  32. echo "Unknown router"
  33. exit 1
  34. esac
  35. # Above this rate, trigger the flood removal process
  36. MAXPPS=50000
  37. # Max PPS for the victim itself :
  38. MAXPPSVICTIM=5000
  39. # The mail recipient to notify :
  40. MAILRECIPIENT="root@gitoyen.net"
  41. show_usage(){
  42. cat <<EOHELP
  43. Usage: $0 [OPTION]
  44. Flood detector and blackhole
  45. -e Nmap expression.
  46. -i Interface to catch (default $IFACE)
  47. -n PPs that trigger tcpdump (default $MAXPPS)
  48. -t PPs that trigger the blackhole (default $MAXPPSVICTIM)
  49. -m Recipient (default $MAILRECIPIENT)
  50. -h Show this help.
  51. ./flood-detector.sh -e 'dst net 80.67.160.0/24 or dst net 80.67.174.0/24'
  52. EOHELP
  53. }
  54. while getopts "i:e:n:t:m:h" opt; do
  55. case $opt in
  56. e)
  57. # Filter the tcpdump on that expression then
  58. FILTER="$OPTARG"
  59. ;;
  60. n)
  61. MAXPPS="$OPTARG"
  62. ;;
  63. t)
  64. MAXPPSVICTIM="$OPTARG"
  65. ;;
  66. i)
  67. IFACE="$OPTARG"
  68. ;;
  69. m)
  70. MAILRECIPIENT="$OPTARG"
  71. ;;
  72. *)
  73. show_usage
  74. exit 1
  75. ;;
  76. esac
  77. done
  78. if [ -z "$FILTER" ]; then
  79. show_usage
  80. exit 1
  81. fi
  82. echo "Auto Blackholing"
  83. echo "IFACE $IFACE"
  84. echo "FILTER $FILTER"
  85. echo "MAXPPS $MAXPPS"
  86. echo "MAXPPSVICTIM $MAXPPSVICTIM"
  87. while true
  88. do
  89. INPPS=`netstat -w 1 -I "$IFACE" -q 3 | tail -1 | awk '{print $1}' `
  90. if [ "$INPPS" -gt "$MAXPPS" ]
  91. then
  92. echo "`date` $INPPS > $MAXPPS, searching for a victim"
  93. # Ok, we are flooded, turn the blackhole ON for the victim
  94. #tcpdump -i "$IFACE" -p -n -w /tmp/flood.pcap "$FILTER" &
  95. tcpdump -i "$IFACE" -p -n -w - "$FILTER" | gzip - > /tmp/flood.pcap.gz &
  96. ME="$!"
  97. sleep 2
  98. kill -TERM "$ME" >/dev/null 2>/dev/null
  99. sleep 1
  100. kill -KILL "$ME" >/dev/null 2>/dev/null
  101. # Now find the victim and add it to the blackhole :
  102. #BLACK="`tcpdump -r /tmp/flood.pcap -n 2>/dev/null |awk '{print $5}' |awk -F "." '{print $1 "." $2 "." $3 "." $4}' |sort | uniq -c | sort -gr | head -1`"
  103. BLACK="` zcat /tmp/flood.pcap.gz 2>/dev/null | tcpdump -r - -n 2>/dev/null |awk '{print $5}' |awk -F "." '{print $1 "." $2 "." $3 "." $4}' |sort | uniq -c | sort -gr | head -1`"
  104. BLACKCOUNT="`echo $BLACK | awk '{print $1}'`"
  105. BLACKME="`echo $BLACK | awk '{print $2}'|cut -d':' -f1`"
  106. if [ -n "$BLACKME" ] && [ -n "$BLACKCOUNT" ] && [ "$BLACKCOUNT" -gt "$MAXPPSVICTIM" ];
  107. then
  108. echo "`date` found $BLACKME that received $BLACKCOUNT pps, blackholing..."
  109. # we got him, add him to the blackhole :
  110. bash /tmp/blackhole.sh -a add -i ${BLACKME}/32
  111. # And we tell the admin ;)
  112. ( echo "Automatic blackhole triggered at `date`" ; echo "PPS was $INPPS, and $BLACKCOUNT was sent to $BLACKME" ) | mail -s "Automatic Blackhole triggered on `hostname` for $BLACKME" $MAILRECIPIENT
  113. else
  114. echo "`date` Nobody found for the filtered expression, will try again later"
  115. fi
  116. fi
  117. sleep 5
  118. done