diff --git a/ddos-mitigator.conf b/ddos-mitigator.conf new file mode 100644 index 0000000..a7ebc54 --- /dev/null +++ b/ddos-mitigator.conf @@ -0,0 +1,30 @@ +# Example configuration file for ddos-mitigator.sh. +# PLEASE TAKE CARE not to put any whitespace around the '=' signs, as this file is directly sourced by the script +# file and this needs to conform to the BASH syntax. Also, make sure to declare the COUNTRIES variable with the +# correct array syntax: COUNTRIES=("AA" "BB" "CC"), or to comment it out altogether. + +# The path to the GeoIP2 database file (must be either country or city database). This parameter is mandatory. If it is +# not specified here, it must be given on the command line (through the -d option). +DATABASE_FILE="/path/to/geoip/country-or-city-database.mmdb" + +# Enable the autopilot for automatically banning IP addresses of the desired countries (see also COUNTRIES option). +# Only ban IP addresses with at least AUTOPILOT current connections. If the value is not specified or 0, don't +# automatically ban IP addresses, but run in interactive mode. +AUTOPILOT="1" + +# Defines the subnet size in bytes to be analyzed. Valid values are: +# - 8 for class A networks (X.0.0.0/8) +# - 16 for class B networks (X.X.0.0/16) +# - 24 for class C networks (X.X.X.0/24) +# - 32 for class D networks (X.X.X.X/32) +# If not specified, run in interactive mode and prompt for the netmask size. +NETMASK="8" + +# The country-codes to block as an array. Defaults to "CN" (China). +#COUNTRIES=("CN" "HK" "TW") + +# Specify the JAIL to use for banning the IP addresses. Defaults to 'apache-auth'. +#JAIL="apache-auth" + +# The desired port to monitor. Defaults to 443 (https). +#PORT="443" diff --git a/ddos-mitigator.sh b/ddos-mitigator.sh index 8270584..01689ea 100755 --- a/ddos-mitigator.sh +++ b/ddos-mitigator.sh @@ -32,10 +32,7 @@ # # ################################################################################ -# Set the host's own IP address. So far, only an IPv4 address is supported. -MY_IP="94.199.214.20" - -# After this point, no editing is required. +# Store the start time; this enables us to output the total runtime at the end. start="$(date +%s)" # Dependencies of this script. Simple array with the following structure: @@ -139,6 +136,13 @@ Usage: $(basename $0) -d FILE [OPTION...] printed to stderr and the program terminates with exit code 1. + -f, --config-file=FILENAME Specify the full path to the configuration + file. If omitted, all options are read + from the command line. + Any parameter specified on the command + line takes precedence over configuration + option read from the file. + -j, --jail=JAIL Specify the JAIL to use for banning the IP addresses. Defaults to 'apache-auth'. @@ -194,8 +198,30 @@ function filter() { mv "${filtered}" "${file}" } +function parse_config_file() { + source "${configfile}" + if [[ -z "${autopilot+x}" ]]; then + autopilot="${AUTOPILOT}" + fi + if [[ -z "${bancountries}" ]]; then + bancountries=()${COUNTRIES[@]}) + fi + if [[ -z "${database+x}" ]]; then + database="${DATABASE_FILE}" + fi + if [[ -z "${jail+x}" ]]; then + jail="${JAIL}" + fi + if [[ -z "${netmask+x}" ]]; then + netmask="${NETMASK}" + fi + if [[ -z "${port+x}" ]]; then + port="${PORT}" + fi +} + 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,f:,j:,n:,p:,h' -l 'auto::,country:,database:,dependencies,config-file:,jail:,netmask:,port:,help' -- "$@") if [ $? -ne 0 ]; then echo 'Error parsing command line options. Terminating. Invoke with --help for help.' >&2 @@ -238,6 +264,14 @@ function parse_command_line_args() { check_dependencies exit $? ;; + '-f' | '--config-file') + configfile="${2}" + if [[ ! -f "${configfile}" || ! -r "${configfile}" ]]; then + echo "Can not read configuration file '${2}'. Invoke with --help for help." >&2 + exit 1 + fi + shift + ;; '-j' | '--jail') jail="${2}" shift @@ -283,6 +317,11 @@ function parse_command_line_args() { shift done + # If the config file option is set, parse the config file. + if [[ ! -z ${configfile+x} ]]; then + parse_config_file + fi + if [[ -z "${database}" ]]; then echo "No GeoIP database specified. Invoke with --help for more information." >&2 exit 1