#!/bin/bash # # Watch for floods and blacklist # Lets get some Variables defined readonly max_ho=12 # Max # of Half Open Connectionsi from any /24 readonly host_ip="" # IP addy of host machine readonly log_file="/home/user/Drain.txt" # Directory to log to. readonly alert_to="user@example.com" # Who to mail Alerts to readonly alert_level=50 # How man Half Open before we send an e-mail readonly server_name="$(hostname)" # Name of your server. For E-mail alerts, defaults to hostmane readonly whitelist_file="/home/user/whitelist" # location of a list of IPs not to block 1 per live # This Function scans for half open TCP connections (Sign of a SYN flood) # and outputs a list of: # <# of half open> function floodCheck () { netstat -tn | awk '$6 == "SYN_RECV" {print $5}' | rev | cut -d\: -f 2- | rev | cut -d\. -f 1-3 | sort | uniq -c -d } # This function takes an IP address as input # Checks if it is already in iptables # If not add it function blackList () { if [[ $1 = "" ]]; then echo "no value" return 1 fi # Is the IP whitelisted grep -q "$1" "$whitelist_file" if [[ $? -eq 0 ]]; then echo "$1 is Whitelisted. Not Blocking." return 1 fi echo "Checking: $1" iptables -L INPUT -n | grep -q $1 if [ $? == 0 ]; then echo "$1 already in blacklist" return 1 fi echo "Blacklisting: $1" iptables -I INPUT -s "$1" -d $host_ip -p all -j DROP # Don't wanna hear from ya iptables -I OUTPUT -d "$1" -s $host_ip -p all -j DROP # Don't wanna talk to ya echo -e "\n$(date) , Blocking $1\n" >> "$log_file" echo } # Some diagnostic output as I usually run this via "watch -n5 ..." number_of_ho=$(netstat -tn | grep SYN_RECV | wc -l) # Helps us to spot distributed attacks that floodCheck may miss # E-mail Alerts if [[ "$number_of_ho" -gt "$alert_level" ]] && [[ ! -e /tmp/ALERTED_FLAG ]]; then echo -e "$number_of_ho half open connections on $server_name.\nPotential SYN Flood situation.\nPlease checkwhat is going on.\nPlease clear ALERTED_FLAG when the situation is Resolved.\n\n \ $server_name" | mail -s "SYN Flood Warning" -t "$alert_to" touch /tmp/ALERTED_FLAG fi # Display and Logging. (Probably should seperate the two) if [[ "$number_of_ho" -gt "1" ]]; then echo "Number of half open connections: $number_of_ho" echo "-------------------------------------" floodCheck ; echo # Show the list so we can see distributed. echo -e "$(date), $number_of_ho half open. From: $(netstat -tn | awk '$6 == "SYN_RECV" {print $5}' | rev | cut -d\: -f 2- | rev | sort -u | wc -l) IP Addies." >> "$log_file" if [[ "$number_of_ho" -gt "$max_ho" ]]; then echo -e "$(netstat -tn | grep SYN_RECV)\n" >> "$log_file" fi fi # Check and block Flooders for ip_addy in $( floodCheck | awk -v allowed_ho=$max_ho '$1 > allowed_ho {print $2}' ) ; do if [[ "$(whoami)" == "root" ]]; then blackList "$ip_addy.0/24" fi done