Created
April 9, 2019 12:17
-
-
Save ankitraturi/d5088c324d38f9a6e692d29bd4059a3f to your computer and use it in GitHub Desktop.
ddos Mitigation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ##### Paths of the script and other files | |
| PROGDIR="/usr/local/ddos" | |
| PROG="/usr/local/ddos/ddos.sh" | |
| IGNORE_IP_LIST="/usr/local/ddos/ignore.ip.list" | |
| IGNORE_NETWORK_LIST="/usr/local/ddos/ignore.network.list" | |
| #CRON="/etc/cron.d/ddos.cron" | |
| APF="/etc/apf/apf" | |
| IPT="/sbin/iptables" | |
| ##### frequency in minutes for running the script | |
| ##### Caution: Every time this setting is changed, run the script with --cron | |
| ##### option so that the new frequency takes effect | |
| FREQ=1 | |
| ##### How many connections define a bad IP? Indicate that below. | |
| NO_OF_CONNECTIONS=12 | |
| ## APF_BAN=0 (Uses iptables for banning ips instead of APF) | |
| APF_BAN=0 | |
| ##### KILL=0 (Bad IPs are'nt banned, good for interactive execution of script) | |
| ##### KILL=1 (Recommended setting) | |
| KILL=1 | |
| ##### An email is sent to the following address when an IP is banned. | |
| ##### Blank would suppress sending of mails | |
| EMAIL_TO="ankit.ambar@gmail.com" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| load_conf() | |
| { | |
| CONF="/usr/local/ddos/ddos.conf" | |
| if [ -f "$CONF" ] && [ ! "$CONF" == "" ]; then | |
| source $CONF | |
| else | |
| head | |
| echo "\$CONF not found." | |
| exit 1 | |
| fi | |
| } | |
| head() | |
| { | |
| echo "DDoS Mitigation" | |
| echo | |
| } | |
| showhelp() | |
| { | |
| head | |
| echo 'Usage: ddos.sh [OPTIONS] [N]' | |
| echo 'N : number of tcp/udp connections (default 150)' | |
| echo 'OPTIONS:' | |
| echo '-h | --help: Show this help screen' | |
| echo '-c | --cron: Create cron job to run this script regularly (default 1 mins)' | |
| echo '-k | --kill: Block the offending ip making more than N connections' | |
| } | |
| unbanip() | |
| { | |
| UNBAN_SCRIPT=`mktemp /tmp/unban.XXXXXXXX` | |
| TMP_FILE=`mktemp /tmp/unban.XXXXXXXX` | |
| UNBAN_IP_LIST=`mktemp /tmp/unban.XXXXXXXX` | |
| echo '#!/bin/sh' > $UNBAN_SCRIPT | |
| echo "sleep $BAN_PERIOD" >> $UNBAN_SCRIPT | |
| if [ $APF_BAN -eq 1 ]; then | |
| while read line; do | |
| echo "$APF -u $line" >> $UNBAN_SCRIPT | |
| echo $line >> $UNBAN_IP_LIST | |
| done < $BANNED_IP_LIST | |
| else | |
| while read line; do | |
| echo "$IPT -D INPUT -s $line -j DROP" >> $UNBAN_SCRIPT | |
| echo $line >> $UNBAN_IP_LIST | |
| done < $BANNED_IP_LIST | |
| fi | |
| echo "grep -v --file=$UNBAN_IP_LIST $IGNORE_IP_LIST > $TMP_FILE" >> $UNBAN_SCRIPT | |
| echo "mv $TMP_FILE $IGNORE_IP_LIST" >> $UNBAN_SCRIPT | |
| echo "rm -f $UNBAN_SCRIPT" >> $UNBAN_SCRIPT | |
| echo "rm -f $UNBAN_IP_LIST" >> $UNBAN_SCRIPT | |
| echo "rm -f $TMP_FILE" >> $UNBAN_SCRIPT | |
| . $UNBAN_SCRIPT & | |
| } | |
| add_to_cron() | |
| { | |
| rm -f $CRON | |
| sleep 1 | |
| service crond restart | |
| sleep 1 | |
| echo "SHELL=/bin/sh" > $CRON | |
| if [ $FREQ -le 2 ]; then | |
| echo "0-59/$FREQ * * * * root /usr/local/ddos/ddos.sh >/dev/null 2>&1" >> $CRON | |
| else | |
| let "START_MINUTE = $RANDOM % ($FREQ - 1)" | |
| let "START_MINUTE = $START_MINUTE + 1" | |
| let "END_MINUTE = 60 - $FREQ + $START_MINUTE" | |
| echo "$START_MINUTE-$END_MINUTE/$FREQ * * * * root /usr/local/ddos/ddos.sh >/dev/null 2>&1" >> $CRON | |
| fi | |
| service crond restart | |
| } | |
| load_conf | |
| while [ $1 ]; do | |
| case $1 in | |
| '-h' | '--help' | '?' ) | |
| showhelp | |
| exit | |
| ;; | |
| '--cron' | '-c' ) | |
| add_to_cron | |
| exit | |
| ;; | |
| '--kill' | '-k' ) | |
| KILL=1 | |
| ;; | |
| *[0-9]* ) | |
| NO_OF_CONNECTIONS=$1 | |
| ;; | |
| * ) | |
| showhelp | |
| exit | |
| ;; | |
| esac | |
| shift | |
| done | |
| TMP_PREFIX='/tmp/ddos' | |
| TMP_FILE="mktemp $TMP_PREFIX.XXXXXXXX" | |
| BANNED_IP_MAIL=`$TMP_FILE` | |
| BANNED_IP_LIST=`$TMP_FILE` | |
| echo "Banned the following concurrent IP addresses on `date`" > $BANNED_IP_MAIL | |
| echo >> $BANNED_IP_MAIL | |
| BAD_IP_LIST=`$TMP_FILE` | |
| #netstat -ntu |egrep ":80|:443" | awk '{print $5}' | cut -d: -f4 | sort | uniq -c | sort -nr > $BAD_IP_LIST | |
| netstat -ntu | grep ESTABLISHED | grep :80 | awk '{print $5}' | sed 's/::ffff://' | cut -d: -f1 | sort | uniq -c | sort -nr > $BAD_IP_LIST | |
| #netstat -ntu | grep :80 | awk '{print $5}' | cut -d: -f4 | sort | uniq -c | sort -nr > $BAD_IP_LIST | |
| ###cat $BAD_IP_LIST | |
| if [ $KILL -eq 1 ]; then | |
| IP_BAN_NOW=0 | |
| while read line; do | |
| CURR_LINE_CONN=$(echo $line | cut -d" " -f1) | |
| if [ $CURR_LINE_CONN -lt $NO_OF_CONNECTIONS ]; then | |
| ### break | |
| continue | |
| fi | |
| CURR_LINE_IP=$(echo $line | cut -d" " -f2) | |
| IGNORE_BAN=`grep -c $CURR_LINE_IP $IGNORE_IP_LIST` | |
| if [ $IGNORE_BAN -ge 1 ]; then | |
| continue | |
| fi | |
| CURR_LINE_OCTET=$(echo $CURR_LINE_IP | cut -d"." -f1) | |
| IGNORE_BAN2=`egrep -c ^"$CURR_LINE_OCTET"$ $IGNORE_NETWORK_LIST` | |
| if [ $IGNORE_BAN2 -ge 1 ]; then | |
| continue | |
| fi | |
| IP_BAN_NOW=1 | |
| echo "$CURR_LINE_IP with $CURR_LINE_CONN connections" >> $BANNED_IP_MAIL | |
| echo $CURR_LINE_IP >> $BANNED_IP_LIST | |
| echo $CURR_LINE_IP >> $IGNORE_IP_LIST | |
| if [ $APF_BAN -eq 1 ]; then | |
| $APF -d $CURR_LINE_IP | |
| else | |
| $IPT -I INPUT -s $CURR_LINE_IP -j DROP | |
| fi | |
| done < $BAD_IP_LIST | |
| if [ $IP_BAN_NOW -eq 1 ]; then | |
| dt=`date` | |
| if [ $EMAIL_TO != "" ]; then | |
| cat $BANNED_IP_MAIL | mail -s "Concurrent IP addresses banned on $dt" $EMAIL_TO | |
| fi | |
| unbanip | |
| fi | |
| fi | |
| rm -f $TMP_PREFIX.* | |
| echo "RUN"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment