From fa5c044f39f3cdc3c2c3e77a2fa9397604ce17d6 Mon Sep 17 00:00:00 2001 From: bisco Date: Mon, 28 May 2018 23:59:02 +0200 Subject: [PATCH] added block_range.sh and template_iptables.sh scripts --- block_range.sh | 154 +++++++++++++++++++++++++++++++++++++++++++ template_iptables.sh | 41 ++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 block_range.sh create mode 100644 template_iptables.sh diff --git a/block_range.sh b/block_range.sh new file mode 100644 index 0000000..c2724ed --- /dev/null +++ b/block_range.sh @@ -0,0 +1,154 @@ +#!/bin/bash +# This script downloads a list of foreign countries' IP address ranges and it marks these IP ranges via ipset command. +# Author: bisco +# ipset solution has been suggested by Matt Wilcox script: https://mattwilcox.net/web-development/unexpected-ddos-blocking-china-with-ipset-and-iptables + +set -e + +### Variables +URL="http://www.ipdeny.com/ipblocks/data/countries" +ZONES="cn hk ru tw" +SCRIPTDIR="/root/firewall" +ZONEDIR="${SCRIPTDIR}/blocked_zones/" +RULESFILE="/tmp/iptables_rules-$(date +'%s')" +IPSET=$(which ipset) +IPTR=$(which iptables-restore) +IPTS=$(which iptables-save) +RM=$(which rm) +WGET=$(which wget) +MKDIR=$(which mkdir) +### End Variables + + +### Code. +### Please don't edit below unless if you know what you're doing. + + +### check_error function +### Check if things went all done when exit +check_error() +{ + if [ ! $? = 0 ]; then + echo "====> ERROR!" + exit + fi +} + + +### trap built-in command +### Run "check_error" function on exit process status +trap check_error EXIT + + +### usage function +### Show help and exits +usage() +{ + echo "Usage: $0 [option]" + echo "" + echo "-c | --check : check all binaries and system are ok" + echo "-d | --download : download only the IP range lists" + echo "-b | --block : set the IP range lists into the ${ZONES} chain" + echo "-h | --help : show this help and exits" + echo "" +} + + +### check_binary function +### This function checks if all binaries are properly installed on target system +check_binary() +{ + if [ "${IPSET}" == "" ] || [ "${IPTR}" == "" ] || [ "${RM}" == "" ] || [ "${WGET}" == "" ] || [ "${MKDIR}" == "" ]; then + echo "Some binaries not found. Please install: ipset, iptables-restore, rm, wget" + exit 1; + else + echo "All binaries are properly installed. Let's go on!" + fi +} + + +### prepare_system function +### This function handles all system operation needed. +prepare_system() +{ + # Create the $ZONEDIR directory. The "-p" flag to create the parents directories if needed and it doesn't show error if path exists. + ${MKDIR} -p "${ZONEDIR}" + + ### Remove old country zone files. + ### The ${VARIABLE:?} syntax is useful to avoid wrong file deletion, if the variable content is empty. + ### Examples: + ### rm -rf "${EMPTY_VAR}"/* executes rm -rf /* + ### rm -rf "${EMPTY_VAR:?}"/* raises an error + ${RM} -rf "${ZONEDIR:?}"/* + + ### Save current iptables rules on temporary file + ${IPTS} > "${RULESFILE}" +} + +### download_zones function +### This function downloads all the selected zones +download_zones() +{ + # Here there's a for cycle on an array of elements + for zone in $(echo "${ZONES[*]}"); + do + echo "Downloading $zone.zone file"; + ${WGET} -P "${ZONEDIR}" "${URL}/$zone.zone"; + done +} + + +### create_chains function +### Create one set per IP range, specifying the hash type to "net" +create_chains() +{ + for chain in $(echo "${ZONES[*]}"); + do + echo "Creating $chain chain"; + ${IPSET} create ${chain} hash:net; + done +} + + +### populate_chains +### This function insert the IP range lists into relative chain +populate_chains() +{ + for chain in $(echo "${ZONES[*]}"); + do + for ip in $(cat $ZONEDIR/$chain.zone); + do + ${IPSET} add $chain $ip; + done; + done +} + + +### reload_rules function +### Reload iptables rules saved during the prepare_system function +### Without reloading iptables rules, new IP ranges won't loaded +reload_rules() +{ + echo "Reloading iptables rules" + ${IPTR} < "${RULESFILE}" +} + + +### Main function +case $1 in + -c | --check) + check_binary;; + -d | --download) + check_binary; + prepare_system; + download_zones;; + -b | --block) + check_binary; + prepare_system; + download_zones; + create_chains; + populate_chains; + reload_rules;; + -h | --help | *) + usage;; +esac diff --git a/template_iptables.sh b/template_iptables.sh new file mode 100644 index 0000000..9ac4662 --- /dev/null +++ b/template_iptables.sh @@ -0,0 +1,41 @@ +#!/bin/bash +set -e + +# Variables +IPT=$(which iptables) +IPCMD=$(which ip) +MAINIP=$("${IPCMD}" -4 -o a | grep inet | grep -v "lo " | awk '{print $4}' | cut -d "/" -f 1) +DPORTSIN="20:22,80,443" +MOSHIN="60000:61000" + +# Trap errors +check_error() +{ + if [ "$?" = 0 ]; then + echo "===> OK"; + else + echo "===> ERROR!"; + exit + fi +} + +trap check_error EXIT + +# Flush rules and set default rules +$IPT -F +$IPT -P INPUT DROP +$IPT -P FORWARD DROP +$IPT -P OUTPUT ACCEPT + +# Set host sepcific rules +### Accept all data from "lo" interface +$IPT -A INPUT -i lo -j ACCEPT + +### Accept all connections after the three-way handshake +$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + +### Services rules +##### Allow connections to the server main ip for SSH, MOSH and psyBNC +##### Use multiports extension to set more ports in a oneline rule +$IPT -A INPUT -p tcp -d $MAINIP -m multiport --dports $DPORTSIN -j ACCEPT +$IPT -A INPUT -p udp -d $MAINIP -m multiport --dports $MOSHIN -j ACCEPT