diff --git a/ddos-mitigator.sh b/ddos-mitigator.sh index 8270584..b9ef911 100755 --- a/ddos-mitigator.sh +++ b/ddos-mitigator.sh @@ -61,10 +61,12 @@ suffix8="/8" suffix16="/16" suffix24="/24" suffix32="/32" +suffixipv6="" ext8=".0.0.0" ext16=".0.0" ext24=".0" ext32="" +extipv6="" # Define some constants to format the output in a colorful way. red="$(printf '\033[38;2;255;0;43m')" @@ -150,6 +152,12 @@ Usage: $(basename $0) -d FILE [OPTION...] - 2 or 16 for class B networks (X.X.0.0/16) - 3 or 24 for class C networks (X.X.X.0/24) - 4 or 32 for class D networks (X.X.X.X/32) + - 5 or 128 for IPv6 addresses (no IPv4 + addresses are considered) + + -6, --enable-ipv6 Enable banning of IPv6 addresses in + addition to the IPv4 addresses/networks + defined by -n (if SIZE is 1, 2, 3 or 4) -p, --port=PORT The desired port to monitor. Defaults to 443 (https). @@ -195,7 +203,7 @@ function filter() { } function parse_command_line_args() { - TEMP=$(getopt -o 'a::,c:,d:,e,j:,n:,p:,h' -l 'auto::,country:,database:,dependencies,jail:,netmask:,port:,help' -- "$@") + TEMP=$(getopt -o 'a::,c:,d:,e,j:,n:,p:,6,h' -l 'auto::,country:,database:,dependencies,jail:,netmask:,port:,enable-ipv6,help' -- "$@") if [ $? -ne 0 ]; then echo 'Error parsing command line options. Terminating. Invoke with --help for help.' >&2 @@ -256,6 +264,9 @@ function parse_command_line_args() { '4' | '32') netmask=32 ;; + '5'|'128') + netmask="ipv6" + ;; *) echo "Invalid argument for parameter 'netmask': '${2}'. Invoke with --help for help." >&2 exit 1 @@ -267,6 +278,9 @@ function parse_command_line_args() { port="${2}" shift ;; + '-6'|'--enable-ipv6') + enableipv6=1 + ;; '-h' | '--help') print_help exit @@ -366,6 +380,7 @@ function process_file() { local banaction='' local nline=1 local country= + # Read the contents from filedescriptor 3 (important: Don's use the # standard filedescriptor because we need to handle user input from # within the loop). @@ -438,6 +453,7 @@ file8="${tmpdir}/sorted-http-8.txt" file16="${tmpdir}/sorted-http-16.txt" file24="${tmpdir}/sorted-http-24.txt" file32="${tmpdir}/sorted-http-32.txt" +fileipv6="${tmpdir}/sorted-http-ipv6.txt" # This file will contain the addresses to be banned. banlist="${tmpdir}/banlist.txt" @@ -445,6 +461,7 @@ touch "${banlist}" # Parse the command line options autopilot=0 +enableipv6=0 netmask=0 jail="apache-auth" bancountries=("CN") @@ -470,6 +487,8 @@ connections=$(ss -HOn state established "( sport = :${port} )" | tr -s '[:blank: echo "${connections}" | grep '^\[::ffff:' - | cut -d: -f4 | cut -d] -f1 | grep -v '^$' >"${fileraw}" # Pure IPv4: 192.168.0.1:443 echo "${connections}" | grep -v '^\[' - | cut -d: -f1 | grep -v '^$' >>"${fileraw}" +# IPv6: [aaaa:...]:443 +echo "${connections}" | grep '^\[[^:]' - | cut -d']' -f1 | sed -e 's/^\[//' | grep -v '^$' | sort > "${fileipv6}" # Group and sort the data into the subnet-specific files. sort "${fileraw}" >"${file32}" @@ -482,18 +501,21 @@ filter "${file32}" "${ext32}" "${suffix32}" filter "${file24}" "${ext24}" "${suffix24}" filter "${file16}" "${ext16}" "${suffix16}" filter "${file8}" "${ext8}" "${suffix8}" +filter "${fileipv6}" "" "" # Determine the number of connections per address uniq -c "${file32}" | sort -rn | sponge "${file32}" uniq -c "${file24}" | sort -rn | sponge "${file24}" uniq -c "${file16}" | sort -rn | sponge "${file16}" uniq -c "${file8}" | sort -rn | sponge "${file8}" +uniq -c "${fileipv6}" | sort -rn | sponge "${fileipv6}" # Determine the number of entries per file. nlines32=$(cat "${file32}" | wc -l) nlines24=$(cat "${file24}" | wc -l) nlines16=$(cat "${file16}" | wc -l) nlines8=$(cat "${file8}" | wc -l) +nlinesipv6=$(cat "${fileipv6}" | wc -l) if [ ${netmask} -eq 0 ]; then # Now let the user choose which file to process. @@ -502,6 +524,7 @@ if [ ${netmask} -eq 0 ]; then echo "[2] 16bit: ${nlines16} entries" echo "[3] 24bit: ${nlines24} entries" echo "[4] 32bit: ${nlines32} entries" + echo "[5] IPv6: ${nlinesipv6} 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 @@ -520,6 +543,9 @@ if [ ${netmask} -eq 0 ]; then "4") netmask=32 ;; + "5" ) + netmask="ipv6" + ;; "Q" | "q") echo "You chose to abort. That's fine! Have a nice day!" exit @@ -544,6 +570,15 @@ unset TEMP echo "Processing ${file}." +# Handle IPv6 option +if [[ "${enableipv6}" -eq 1 ]]; then + if [[ "${netmask}" != "ipv6" ]]; then + cat "${file}" "${fileipv6}" | sort -n | sponge "${file}" + nlines=$(( ${nlines} + ${nlinesipv6} )) + fi +fi + + # Invoke the processing function on the chosen file. process_file "${file}"