diff --git a/ddos-mitigator/superscript.sh b/ddos-mitigator/superscript.sh index 31ea6cf..a11a12d 100755 --- a/ddos-mitigator/superscript.sh +++ b/ddos-mitigator/superscript.sh @@ -47,6 +47,76 @@ blue="\033[38;2;0;85;255m" bold="\033[1m" reset="\033[0m" +function printHelp() { + echo "Help ... to be written." +} + +function parseCommandline() { + TEMP=$(getopt -o 'a::,n:,h' -l 'auto::,netmask:,help' -- "$@") + + if [ $? -ne 0 ] ; then + echo 'Error parsing command line options. Terminating. Invoke with --help for help.' >&2 + exit 1 + fi + + eval set -- "${TEMP}" + unset TEMP + + while true ; do + case "$1" in + '-a'|'--auto') + case $2 in + '') + autopilot=1 + ;; + *[!0-9]*) + echo "Invalid argument for parameter 'auto': '$2'. Invoke with --help for help." >&2 + exit 1 + ;; + *) + autopilot=$2 + ;; + esac + shift + ;; + '-n'|'--netmask') + case "$2" in + '1'|'8') + netmask=8 + ;; + '2'|'16') + netmask=16 + ;; + '3'|'24') + netmask=24 + ;; + '4'|'32') + netmask=32 + ;; + *) + echo "Invalid argument for parameter 'netmask': '$2'. Invoke with --help for help." >&2 + exit 1 + ;; + esac + shift + ;; + '-h'|'--help') + printHelp + exit + ;; + '--') + shift + break + ;; + *) + echo "Unknown error on command line argument '$1'. Terminating." >&2 + exit 1 + ;; + esac + shift + done +} + # Clean up when the script exits. trap 'sudo -k; popd; rm -r ${tmpdir}' EXIT @@ -56,6 +126,12 @@ tmpdir=$(mktemp -d) pushd "${tmpdir}" touch "${banlist}" +# Parse the command line options +autopilot=0 +netmask=0 + +parseCommandline "$@" + # Determine the current connections to the desired port; store the raw data in # $fileraw. netstat -nt | grep "${MY_IP}:${MY_PORT}" | tr -s '[:blank:]' | cut -d' ' -f5 \ @@ -73,47 +149,50 @@ nlines24=$(cat "${file24}" | wc -l) nlines16=$(cat "${file16}" | wc -l) nlines8=$(cat "${file8}" | wc -l) -# Now let the user choose which file to process. -echo "We've got:" -echo "[1] 32bit: ${nlines32} entries" -echo "[2] 24bit: ${nlines24} entries" -echo "[3] 16bit: ${nlines16} entries" -echo "[4] 8bit: ${nlines8} entries" -read -p 'Which one do you want to work with (q=Quit) [1-4]? ' choice +if [ ${netmask} -eq 0 ] ; then + # Now let the user choose which file to process. + echo "We've got:" + echo "[1] 8bit: ${nlines8} entries" + echo "[2] 16bit: ${nlines16} entries" + echo "[3] 24bit: ${nlines24} entries" + echo "[4] 32bit: ${nlines32} entries" + read -p 'Which one do you want to work with (q=Quit) [1-4]? ' choice -# Based on the user's choice, initialize the variables $file, $ext and -# $nlines, which will be used after this point. Also, $choice will be -# used to color the output based on subnet-type. -case "${choice}" in - "1" ) - file="${file32}" - ext="${ext32}" - nlines="${nlines32}" - ;; - "2" ) - file="${file24}" - ext="${ext24}" - nlines="${nlines24}" - ;; - "3" ) - file="${file16}" - ext="${ext16}" - nlines="${nlines16}" - ;; - "4" ) - file="${file8}" - ext="${ext8}" - nlines="${nlines8}" - ;; - "Q" | "q" ) - echo "You chose to abort. That's fine! Have a nice day!" - exit - ;; - * ) - echo "Invalid input: ${choice}. I'm out of here." - exit 1 - ;; -esac + # Based on the user's choice, initialize the variables $file, $ext and + # $nlines, which will be used after this point. Also, $choice will be + # used to color the output based on subnet-type. + case "${choice}" in + "1" ) + netmask=8 + ;; + "2" ) + netmask=16 + ;; + "3" ) + netmask=24 + ;; + "4" ) + netmask=32 + ;; + "Q" | "q" ) + echo "You chose to abort. That's fine! Have a nice day!" + exit + ;; + * ) + echo "Invalid input: ${choice}. I'm out of here." + exit 1 + ;; + esac +fi + +# Now initialize the variables $file, $ext and $nlines based on the chosen $netmask +TEMP="file${netmask}" +file="${!TEMP}" +TEMP="ext${netmask}" +ext="${!TEMP}" +TEMP="nlines${netmask}" +nlines="${!TEMP}" +unset TEMP echo "Processing ${file}." @@ -197,18 +276,35 @@ function processFile () { count="$(echo "${line}" | cut -d' ' -f2)" addr="$(echo "${line}" | cut -d' ' -f3-)${ext}" setHilite "${count}" - whois "${addr}" | tee "${whoisoutput}" + if [[ autopilot -eq 0 ]] ; then + whois "${addr}" | tee "${whoisoutput}" + else + whois "${addr}" > "${whoisoutput}" + fi grep -iq "^country: *cn$" "${whoisoutput}" country_cn=$? grep -iq "^source: *apnic$" "${whoisoutput}" source_apnic=$? - if [[ ${country_cn} -eq 0 && ${source_apnic} -eq 0 ]] ; then - echo -e "${red}Country = CN and source = APNIC!${reset}" - fi echo -en "Address ${bold}$((nline++)) of ${nlines}${reset}: \ -Found '${blue}${addr}${reset}' ${hilite}${count}${reset} times. Ban [y/N/s=No, \ -and skip remaining]? " - read banaction +Found '${blue}${addr}${reset}' ${hilite}${count}${reset} times." + + if [[ ${autopilot} -eq 0 ]] ; then + echo -en "Ban [y/N/s=No, and skip remaining]? " + read banaction + else + echo -en "\n${red}Autopilot active.${reset} " + if [[ ${country_cn} -eq 0 && ${source_apnic} -eq 0 ]] ; then + if [[ $count -ge $autopilot ]] ; then + banaction=y + else + echo -en "${yellow}Ignoring because count ${count} is below specified limit of ${autopilot}.${reset} " + banaction=n + fi + else + banaction=n + fi + fi + case "${banaction}" in "s" | "S" ) echo -e "Not banning '${blue}${addr}${reset}', \