#!/bin/bash 
# brainfw.sh
# Brain Firewall
#
# Author: Christophe Casalegno / Brain 0verride
# Contact: brain@christophe-casalegno.com
# Version 0.1
#
# Copyright (c) 2021 Christophe Casalegno
#
# This program is free software: you can redistribute it and/or modify
#
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <https://www.gnu.org/licenses/>
#
# The license is available on this server here:
# https://www.christophe-casalegno.com/licences/gpl-3.0.txt

WORKPLACE="/root/tmp"
BLACKLIST="$WORKPLACE/blacklist.txt"
ACTION="$1"
BLOCKFORMAT="$2"
TARGET="$3"

function check_workplace()
{
	WORKPLACE="$1"

	if [[ ! -e "$WORKPLACE" ]]
	then
		echo "$WORKPLACE doesn't exist, creating..."
		mkdir "$WORKPLACE"
	else
		if [[ ! -d "$WORKPLACE" ]]
		then
			echo "Alert: $WORKPLACE is a file, exiting..."
			exit 1
	else
		echo #"$WORPLACE is a directory, processing..."
	fi
	fi
}


function get_country()
{
        WORKPLACE="$1"
        COUNTRY="$2"
        BASE_URL="http://www.ipdeny.com/ipblocks/data/aggregated"

        wget -q $BASE_URL/$COUNTRY-aggregated.zone -O $WORKPLACE/$COUNTRY.zone
}


function blockip()
{
	IP="$1"

	iptables -I INPUT -s "$IP" -j DROP -v
}

function unblockip()
{
	IP="$1"

	iptables -D INPUT -s "$IP" -j DROP -v
}

function core()
{
	ACTION="$1"
	BLOCKFORMAT="$2"
	TARGET="$3"
	BLACKLIST="$4"
	WORKPLACE="$5"


	if [[ "$BLOCKFORMAT" = "country" ]]
	then
		get_country "$WORKPLACE" "$TARGET"
		HOWMANYLINES=$(cat "$WORKPLACE/$TARGET.zone" |wc -l)
		
		if [[ "$ACTION" = "block" ]]
		then
		
			SECONDS="0"
			echo "Processing blacklist $HOWMANYLINES for $TARGET country... please wait..."
			for LINE in $(cat $WORKPLACE/$TARGET.zone)
        		do 
				blockip $LINE > /dev/null 
			done
			echo "Done! Country $TARGET ($HOWMANYLINES) processed in $SECONDS seconds"
		
		elif [[ "$ACTION" = "unblock" ]]
		then
			SECONDS="0"
			echo "Processing unblocklist $HOWMANYLINES for $TARGET country... please wait..."
			for LINE in $(cat $WORKPLACE/$TARGET.zone)
			do 
				unblockip $LINE > /dev/null
			done
			echo "Done! Country $TARGET ($HOWMANYLINES) unblocked in $SECONDS seconds"

		else
			echo "$ACTION invalid, exiting..."
			exit 1
		fi
	
	elif [[ "$BLOCKFORMAT" = "ip" ]]
	then
		if [[ "$TARGET" =~ (([01]{,1}[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.([01]{,1}[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.([01]{,1}[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.([01]{,1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]))$ ]]
        	then
			echo "IP address $TARGET is valid"

                	if [[ $1 != 0.0.0.0 ]]
                	then
				
				if [[ "$ACTION" = "block" ]]
				then
					echo "Processing blocking $TARGET... please wait..."
                        		blockip "$TARGET"			
					echo "Done! $TARGET blocked"
				
				elif [[ "$ACTION" = "unblock" ]]
				then
					echo "Processing unblocking $TARGET... please wait..."
					unblockip "$TARGET"
					echo "Done! $TARGET unblocked"
				else
					echo "$ACTION invalid, process cancelled..."
					exit 1
				fi
                	else
                        	echo "You can't do this"
                	fi

        	elif [[ "$TARGET" =~ (((25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?))(\/([8-9]|[1-2][0-9]|3[0-2]))([^0-9.]|$) ]]
        	then
			echo "CIDR range $TARGET is valid"

                	if [[ $1 != 0.0.0.0 ]]
                	then
                        	if [[ "$ACTION" = "block" ]]
				then
					echo "Processing blocking $TARGET... please wait..."
					blockip "$TARGET"          
					echo "Done! $TARGET blocked"
				elif [[ "$ACTION" = "unblock" ]]
				then
					echo "Processing unblocking $TARGET... please wait..."
					unblockip "$TARGET"
					echo "Done! $TARGET unblocked"
				else
					echo "$ACTION invalid, process cancelled..."
					exit 1
				fi
                	else
                        	echo "You can't do this"
                	fi

        	else
        		echo "ERROR: $TARGET is an invalid IP address or CIDR format"
			exit 1
        	fi


	else
		echo "Block format: $BLOCKFORMAT invalid, exiting..."
		exit 1
	fi


}



function action()
{
	
	ACTION="$1"
	BLOCKFORMAT="$2"
	TARGET="$3"
	BLACKLIST="$4"
	WORKPLACE="$5"
	
	check_workplace "$WORKPLACE"

	if [[ "$ACTION" = "help" ]]
	then
		echo "./brainfw.sh {action} {blockformat} {target}"
		echo "{action} can be: help, block or unblock"
	        echo "{blockformat} can be: ip or country"
		echo "{target} can be : an ip (ex : 192.168.x.x), a CIDR (192.168.x.x/24) or a countrycode (ex: fr)"
	elif [[ "$ACTION" = "block" ]]
	then
		core $ACTION $BLOCKFORMAT $TARGET $BLACKLIST $WORKPLACE

	elif [[ "$ACTION" = "unblock" ]]
	then
		core $ACTION $BLOCKFORMAT $TARGET $BLACKLIST $WORKPLACE

	else 
		echo "Invalid action, please retry"
		exit 1
	fi
}



action $ACTION $BLOCKFORMAT $TARGET $BLACKLIST $WORKPLACE


